Reputation: 65
I have this code that is supposed to do what the title said, reverse the order of characters without changing the order of the words:
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;
}
}
It works fine if I enter a single word like "Hello"--it will output "olleH"--but as soon as it gets more complicated than one word it starts to output some weird things."Hello my name is" outputs "ollehem". I'm really new to Stack
s and this is my first time using them. I'm not sure if there is a logic error or improper use of Stack
s.
Upvotes: 2
Views: 163
Reputation: 5831
Here is how you can do it in-place without using any extra space (Not using stack):
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);
}
}
Output:
sihT si a tset
Upvotes: 0
Reputation: 24146
you're not outputting original spaces, this is why you're seeing strange results
here is fixed version:
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());
}
another version without stack, with in-place replacement:
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--;
}
}
Upvotes: 3
Reputation: 106
If you HAVE to use a stack, I would follow an algorithm like this:
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());
I'm not sure efficiency matters to you, but this algorithm would work in linear time, where n is the number of characters in the string.
Upvotes: 3