2016-01-15 2 views
2

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

package stackTests; 

import java.util.Scanner; 
import java.util.Stack; 


public class StackTest 
{ 
    Stack<Character> stack; 

    public StackTest() 
    { 
    stack = new Stack<Character>(); 
    } 

    public String reverseString(String str) 
    { 
    int start = 0; 
    int start2 = 0; 
    int size; 
    char space = ' '; 
    char[] cArr; 
    Scanner scan = new Scanner(str); 
    cArr = str.toCharArray(); 
    for (; start < cArr.length; start++) 
    { 
     if(cArr[start] == space || start == cArr.length - 1) 
     { 
     for (; start2 < stack.size(); start++) 
     { 
      System.out.print(stack.pop()); 
     } 
     } 
     else 
     { 
     stack.push(cArr[start]); 
     } 
     start2 = 0; 
    } 
    return str; 
    } 
} 

Он отлично работает, если я ввожу одно слово, например «Hello» - он выдает «olleH» - но как только он усложняется, чем одно слово, он начинает выводить некоторые странные вещи ». Привет, меня зовут" выводит "ollehem". Я действительно новичок в Stack и это мой первый раз, когда я их использую. Я не уверен, есть ли логическая ошибка или неправильное использование Stack.

+1

Это не читаемым. Отформатируйте свой код читаемым способом. – m0skit0

+3

Вам действительно нужно использовать стек? Является ли эта часть домашней работы? –

+0

Вы знаете, как использовать отладчик? – tnw

ответ

3

вы не выводя оригинальные места, поэтому вы видите странные результаты

здесь фиксирована версия:

public static void reverseString(final String str) { 
    final Stack<Character> stack = new Stack<>(); 
    for (int i = 0; i < str.length(); i++) { 
     final char c = str.charAt(i); 
     if (c == ' ') { 
      while (!stack.isEmpty()) 
       System.out.print(stack.pop()); 
      System.out.print(' '); 
     } else 
      stack.push(c); 
    } 
    while (!stack.isEmpty()) 
     System.out.print(stack.pop()); 
} 

другая версия без стека, с в месте замены:

public static void reverseString(final String str) { 
    final char[] chars = str.toCharArray(); 
    int start = 0; 
    for (int i = 0; i < chars.length; i++) { 
     if (chars[i] == ' ') { 
      reverse(chars, start, i - 1); 
      start = i + 1; 
     } 
    } 
    reverse(chars, start, chars.length - 1); 
    System.out.println(new String(chars)); 
} 

private static void reverse(final char[] chars, int s, int e) { 
    while (s < e) { 
     final char t = chars[s]; 
     chars[s] = chars[e]; 
     chars[e] = t; 
     s++; 
     e--; 
    } 
} 
+0

Хорошо, я вижу, что вы имеете в виду спасибо! –

+0

Я думаю, я просто подумал об этом с использованием массива, не знаю, почему я думал, что это хорошая идея. –

3

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

String myString = "Hello World"; 
Stack<Character> stack = new Stack<Character>(); 
StringBuilder sb = new StringBuilder(); 
String[] splitString = myString.split(" "); 

//Iterate through each word in the string 
for(String s : splitString){ 

    //Push each character of the word into LIFO stack 
    for(char c : s.toCharArray()){ 
     stack.push(c); 
    } 

    //Build new string with reverse ordered characters 
    while(!stack.isEmpty()){ 
     sb.append(stack.pop()); 
    } 

    //Append a space as long as it's not the last word of the original string 
    if(!s.equals(splitString[splitString.length - 1])) 
     sb.append(" "); 
} 

//Print the new string 
System.out.println(sb.toString()); 

Я не уверен, вопросы эффективности для вас, но этот алгоритм будет работать в линейном времени, где п является количество символов в строке.

+0

Не могли бы вы немного сломать свой процесс для меня, поскольку я не очень хорошо знаком с StringBuilder, так что я немного потерялся. –

+0

Код работает отлично, хотя спасибо! –

+0

Абсолютно. Строка в java является неизменным объектом. Это означает, что когда вы добавляете строку, это фактически создает совершенно новую строку в памяти, а не просто добавляет ее в предыдущую. StringBuilder - это объект, который позволяет вам безопасно (говорить по памяти) добавлять новые строки в объект StringBuilder. Для ваших целей вы также можете использовать простой объект String (просто замените StringBuilder на String myString = "" и замените операторы append на myString + = stack.pop()). –

0

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

public class ReverseWordsInplace { 

    public static void main(String[] args) { 
     reverseWords(new StringBuilder("This is a test")); 
    } 

    public static void reverseWords(StringBuilder s) { 
     StringBuilder str = new StringBuilder(s); 
     int startWordIndex = 0; 
     for (int i = 0; i < str.length(); i++) { 
      if (str.charAt(i) == ' ' || str.length() - 1 == i) { 
       int x = 0; 
       int endWordIndex = str.charAt(i) == ' ' ? i - 1 : i; 
       while (endWordIndex - x > startWordIndex + x) { 
        char c1 = str.charAt(startWordIndex + x); 
        char c2 = str.charAt(endWordIndex - x); 
        str.setCharAt(startWordIndex + x, c2); 
        str.setCharAt(endWordIndex - x, c1); 
        x++; 
       } 
       startWordIndex = i + 1; 
      } 
     } 
     System.out.println(str); 
    } 
} 

Выход:

отЭ С.И. TSET

Смежные вопросы