Как перевернуть все слова в строке, не меняя позицию символа? - PullRequest
0 голосов
/ 05 августа 2020

Мне нужно написать программу, которая перевернет все слова в строке, но все символы должны оставаться на предыдущей позиции, например: «a1bcd efg!h» => «d1cba hgf!e». Я написал простую программу, которая может перевернуть все слова / символы, но я понятия не имею, как это сделать, как в примере

public void reverseWordInMyString(String str) {
    String[] words = str.split(" ");
    String reversedString = "";

    for (int i = 0; i < words.length; i++) {

        String word = words[i];
        String reverseWord = "";

        for (int j = word.length()-1; j >= 0; j--) {

            reverseWord = reverseWord + word.charAt(j);
        }

        reversedString = reversedString + reverseWord + " ";
    }
    System.out.println(reversedString);
}

Ответы [ 3 ]

1 голос
/ 05 августа 2020

согласно www.geeksforgeeks.org

Проблема:

Дана строка, содержащая специальный символ вместе с алфавитами (от 'a' до 'z' и ' A 'на' Z '), переверните строку таким образом, чтобы не затрагивать специальные символы.

Решение:

  1. Создайте временный массив символов, скажем, temp [].
  2. Скопируйте символы алфавита c из заданного массива в temp [].
  3. Reverse temp [], используя стандартный алгоритм преобразования строки. Теперь пройдитесь по входной строке и температуре за один l oop. Везде, где есть символ алфавита c, входная строка, замените его текущим символом temp [].

Алгоритм:

1) Let input string be 'str[]' and length of string be 'n'
2) l = 0, r = n-1
3) While l is smaller than r, do following
    a) If str[l] is not an alphabetic character, do l++
    b) Else If str[r] is not an alphabetic character, do r--
    c) Else swap str[l] and str[r]

Java Код:

    public static void main(String[] args){
        String s = "Thi!s is a sa5mpl?e sentence.";
        String[] words = s.split("\\s+");
        System.out.println("Result:" + reverse(s));
        //Output: sih!T si a el5pma?s ecnetnes.
    }

    public static String reverse(String input)
    {
        String[] words = input.split("\\s+");
        String last_str = "";

        for(int j=0;j<words.length;j++){
            char[] str = words[j].toCharArray();
            int r = str.length - 1, l = 0;

            // Traverse string from both ends until
            // 'l' and 'r'
            while (l < r)
            {
                // Ignore special characters
                if (!Character.isAlphabetic(str[l]))
                    l++;
                else if(!Character.isAlphabetic(str[r]))
                    r--;

                    // Both str[l] and str[r] are not spacial
                else
                {
                    str[l] ^= str[r];//swap using triple XOR
                    str[r] ^= str[l];
                    str[l] ^= str[r];
                    l++;
                    r--;
                }
            }
            last_str = last_str + new String(str) + " ";
        }
        // Initialize left and right pointers

        return last_str;
    }

}
1 голос
/ 05 августа 2020

Это хорошее начало. Вопрос очень сложен. 1006 * Для выполнения этого домашнего задания вам понадобятся два аккумулятора: один идущий спереди назад, который постоянно увеличивается (так что это будет for (int i = 0; i < word.length(); i++)), и один, который начинается в конце и уменьшается, но не

Идея такова: go продвигаясь вперед, вы проверяете персонажа, которого находите в позиции i. Затем вы используете if, так как вопрос просит вас делать разные вещи в зависимости от условия:

  • если символ в i является специальным символом, просто добавьте его.
  • else, добавьте последний неспециальный символ в строку, которую мы еще не добавили.

случай if тривиален. Случай else - нет. Вот тут-то и пригодится ваш второй аккумулятор: он будет отслеживать, где вы находитесь в строке, с конца. Это al oop -in-l oop. Что вам нужно:

повторить следующий алгоритм:

  • Если символ в 'j' (который идет от конца до начала) является специальным символом, уменьшите j, и перезапустите этот алгоритм.
  • В противном случае это «последний неспециальный символ, который мы еще не добавили», поэтому добавьте его, уменьшите j и выйдите из этого алгоритма.

Вышеуказанное может be done, например, while или do / while l oop. Он будет внутри вас на l oop.

Удачи!

NB: Это не единственный способ сделать это. Например, вы также можете исключить все специальные символы из ввода, выполнить базовый c реверс для каждого слова внутри, что намного проще, чем то, что у вас есть сейчас, поскольку в наши дни строка имеет метод .reverse(), а затем , после всего этого, go через ваш исходный входной символ за символом, и для каждого специального символа, который вы найдете, вставьте этот символ в эту позицию в вашей выходной строке. Это тоже работает. Какую стратегию вы предпочитаете!

0 голосов
/ 05 августа 2020

Я бы подошел к этому следующим образом:

  1. Отслеживайте, где начинается текущее слово (или, что эквивалентно, где был последний не-словный символ). Он будет обновляться по мере продвижения go.
  2. Сканируем входную строку. Каждый раз, когда обнаруживается не-словесный символ (специальный символ или пробел), выведите обратное значение текущего слова, а затем несловный символ. Вы можете вывести обратное текущее слово путем индексации в обратном направлении от символа, не являющегося словом, до начала текущего слова. (Обратите внимание, что текущее слово может быть пустым; например, два специальных символа в строке).

Для области вывода я рекомендую StringBuilder, а не String; это будет более эффективно.

В коде это может выглядеть примерно так (где я изменил метод, чтобы возвращать результат, а не выводить его на консоль):

public String reverseWordInMyString(String str) {
    StringBuilder output = new StringBuilder(str.length()); // initialize full capacity
    int curWordStart = 0;
    // scan the input string
    for (int i = 0; i < str.length(); i++) {
        char curLetter = str.charAt(i);
        if (!Character.isLetter(char)) {
            // the current word has ended--output it in reverse
            for (int j = i-1; j >= curWordStart; j--) {
                output.append(str.charAt(j));
            }
            // output the current letter
            output.append(curLetter);
            // the next current word starts just after the current letter
            curWordStart = i + 1;
        }
    }
    // The last current word (if any) ends with the end of string,
    // not a special character, so add it (reversed) as well to output
    for (int j = str.length() - 1; j >= curWordStart; j--) {
        output.append(str.charAt(j));
    }

    return output.toString();
}
...