我正在尝试开发一种方法来反转字符串中的元音。为此,我开发了自己的小堆栈。我正在向后遍历字符串两次,一次用我找到的每个元音填充堆栈,第二次用存储在堆栈顶部的元音替换元音。我添加了一堆print语句来确定它失败的地方,并且它似乎在setCharAt
方法失败了。出于测试目的,我提供了一个字符串aeiou
,我希望能够找回uoiea
。在每次迭代过程中,字符都会被替换,但不幸的是,它们不会保持这种状态。从下一次迭代开始,在前一次迭代中替换的字符将返回到之前的字符。结果,我回到ueiou
,其中只有字符串中的第一个字符符合预期(第三个字符是noop)。这是我的代码。任何提示都表示赞赏。
import java.util.*;
public class Solution {
static String result;
static class StackOfVowels {
static Node top;
public StackOfVowels() {
Node top = null;
}
static class Node {
Node next = null;
char vowel = '\0';
Node(char value) {
this.vowel = value;
}
}
public void push(char item) {
Node node = new Node(item);
if (top == null) {
top = node;
}
else {
node.next = top;
top = node;
}
}
public char top() {
if (top == null) throw new EmptyStackException();
return top.vowel;
}
public void pop() {
int result = -1;
if (top != null) {
result = top.vowel;
top = top.next;
}
}
}
public static String reverseVowels(String s) {
StackOfVowels stackOfVowels = new StackOfVowels();
for(int i = s.length()-1; i >= 0; i--) {
char c = s.charAt(i);
if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u')) {
System.out.println("Initial sequence of iterations identified vowel: " + c);
stackOfVowels.push(c);
System.out.println("Pushed to stack, current top is: " + stackOfVowels.top());
}
}
for(int j = s.length()-1; j >= 0; j--) {
char b = s.charAt(j);
if ((b == 'a') || (b == 'e') || (b == 'i') || (b == 'o') || (b == 'u')) {
System.out.println("Second sequence of iterations identified vowel: " + b);
StringBuilder newstr = new StringBuilder(s);
char d = stackOfVowels.top();
System.out.println("Variable d set to top of: " + stackOfVowels.top());
newstr.setCharAt(j, d);
result = newstr.toString();
System.out.println("Here is the new string: " + result);
stackOfVowels.pop();
System.out.println("Stack was popped");
}
}
return result;
}
public static void main(String[] args) {
String s = "aeiou";
reverseVowels(s);
System.out.println("Final result: " + result);
}
}
答案 0 :(得分:2)
使用StringBuilder newstr = new StringBuilder(s);
在第二个循环中生成一个新的StringBuilder
但是你总是用's'而不是'结果'来构建你的新StringBuilder。
不管怎样,最好不要在每次迭代中创建一个新的StringBuilder对象。
同样令人困惑的是你的方法有一个从未使用过的返回值。
以下方法应该有效:
public static String reverseVowels(String s) {
StackOfVowels stackOfVowels = new StackOfVowels();
for(int i = s.length()-1; i >= 0; i--) {
char c = s.charAt(i);
if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u')) {
System.out.println("Initial sequence of iterations identified vowel: " + c);
stackOfVowels.push(c);
System.out.println("Pushed to stack, current top is: " + stackOfVowels.top());
}
}
StringBuilder result_builder = new StringBuilder(s);
for(int j = s.length()-1; j >= 0; j--) {
char b = s.charAt(j);
if ((b == 'a') || (b == 'e') || (b == 'i') || (b == 'o') || (b == 'u')) {
System.out.println("Second sequence of iterations identified vowel: " + b);
char d = stackOfVowels.top();
System.out.println("Variable d set to top of: " + stackOfVowels.top());
result_builder.setCharAt(j, d);
stackOfVowels.pop();
System.out.println("Stack was popped");
}
}
result = result_builder.toString();
return result_builder.toString();
}
答案 1 :(得分:2)
我会稍微改变一下这个问题,首先我会使用正则表达式从String
中移除所有辅音以创建String
vowels
}。然后我将遍历String
的字符,使用StringBuilder
来构建输出(传递辅音,但使用之前创建的vowels
String
替换元音。像,
public static String reverseVowels(String s) {
// Match all consonants, and remove them. Reverse that String.
String vowels = new StringBuilder(s.replaceAll("[^AEIOUaeiou]", ""))
.reverse().toString();
StringBuilder sb = new StringBuilder();
for (int i = 0, p = 0; i < s.length(); i++) {
switch (Character.toLowerCase(s.charAt(i))) {
// Note that these fall-through...
case 'a': case 'e': case 'i': case 'o': case 'u':
sb.append(vowels.charAt(p++));
break;
default:
sb.append(s.charAt(i));
}
}
return sb.toString();
}
这是可以利用switch
和堕落行为的地方之一。
如果您使用的是Java 8+,则可以使用IntStream
表达相同内容并映射字符;像
String vowels = new StringBuilder(s.replaceAll("[^AEIOUaeiou]", ""))
.reverse().toString();
int[] counter = new int[1]; // <-- A bit of a kludge really.
return IntStream.range(0, s.length()).mapToObj(i -> {
switch (Character.toLowerCase(s.charAt(i))) {
case 'a': case 'e': case 'i': case 'o': case 'u':
return Character.toString(vowels.charAt(counter[0]++));
default:
return Character.toString(s.charAt(i));
}
}).collect(Collectors.joining());
答案 2 :(得分:2)
@Elliot答案略有改进(值得商榷)是使用原始StringBuilder
创建String
并仅在必要时替换
String vowels = new StringBuilder(s.replaceAll("[^AEIOUaeiou]", ""))
.reverse().toString();
StringBuilder sb = new StringBuilder(s);
for (int i = 0, p = 0; i < s.length(); i++) {
switch (Character.toLowerCase(s.charAt(i))) {
// Note that these fall-through...
case 'a': case 'e': case 'i': case 'o': case 'u':
sb.setCharAt(i, vowels.charAt(p++));
break;
default:
break;
}
}
return sb.toString();