从字符堆栈构造String的有效且简洁的方法是什么?

时间:2017-10-13 10:44:28

标签: java java-8 stack

假设我有一个堆栈 -

O (stack top)
L
L
E
H (stack bottom)

将其转换为“HELLO”的简洁方法是什么

现在我这样做 -

private static String getString(Stack<Character> charStack) {
  StringBuilder output = new StringBuilder();

  while (!charStack.isEmpty()) {
      output.append(charStack.pop());    
  }

  return output.reverse().toString();
}

3 个答案:

答案 0 :(得分:7)

使用mapCollectors,可以采用一种方法来处理相关代码:

return charStack.stream().map(Object::toString).collect(Collectors.joining());

编辑 :从评论(1)(2)可见,如果清空堆栈是故意的操作,您可以将代码更新为包括如下行为:

String output = charStack.stream().map(Object::toString).collect(Collectors.joining());
charStack.clear();
return output;

答案 1 :(得分:2)

注意

我无意中认为您正在搜索更快的版本。但是我决定将讨论留在这里,因为它可能对未来的读者有用。

分析

您可以使用给定的输入无法获得更好的版本,至少在谈论复杂性类时。您的Stack只能从最后一个项目遍历到第一个项目,而不能遍历String正确顺序

您不能直接使用您的最终String首先需要撤消的知识。

让我们来看看您的代码,让我们用n表示您的代码大小:

private static String getString(Stack<Character> charStack) {
    StringBuilder output = new StringBuilder();

    // Yields n iterations
    while (!charStack.isEmpty()) {
        output.append(charStack.pop());    
    }

    // reverse creates n iterations
    // toString creates n iterations
    return output.reverse().toString();
}

我们总共有3 * n次迭代产生O(n)

已知大小

如果知道堆栈的大小,您可以尝试使用数组(Stack没有size方法)。它们的优点是可以在任何方向上遍历和编辑它们而无需额外费用。看一下下面的例子:

int size = ...
char[] textChars = new char[size];

// Yields n iterations
for (int i = 0; i < size; i++) {
    // Reversely set the array
    // Setting is done in constant time
    textChars[size - i - 1] = charStack.pop();
}

// Convert the textChars to String
// without using reverse methods
// Yields n iterations
String text = String.valueOf(textChars);

我们总共有2 * n次迭代,也产生O(n)

如果你知道尺寸,它可能会稍微快一些。然而,差异不会那么大,O(n)也是如此。

尺寸未知

如果您不知道可以与char[]交换ArrayList<Character>的尺寸(LinkedList也会有效,但可能会更慢):

ArrayList<Character> textChars = new ArrayList<>();

// Yields n iterations
for (char c : charStack) {
    // Set the ArrayList
    // Setting is done in constant time
    textChars.add(charStack.pop());
}

// Unfortunately there is no nice method
// to directly convert ArrayList to String
StringBuilder sb = new StringBuilder();

// Reversely iterate the ArrayList, the reverse
// direction comes at no additional cost
// Yields n iterations
for (int i = textChars.size() - 1; i >= 0; i--) {
    sb.append(textChars.get(i));
}

// Yields n iterations
String text = sb.toString();

现在我们有大约3 * n次迭代,但由于ArrayListCharacter而导致更大的开销。如果没有进行实验,我会说如果尺寸未知,你的方法比任何一种都好。

答案 2 :(得分:0)

请注意,charStack.pop()实际上从堆栈中移除元素 - 您确定它是否有意?

你可以这样做而不删除元素:

private static String getString(Stack<Character> charStack) {
    StringBuilder output = new StringBuilder();

    for (Character c : charStack) {
        output.append(c);    
    }

    return output.reverse().toString();
}