【问题标题】:Comparing stack pop and queue dequeue in Java (palindromes)比较 Java 中的堆栈弹出和队列出列(回文)
【发布时间】:2012-06-08 16:14:03
【问题描述】:

完全披露:这是一个作业,所以请不要发布实际的代码解决方案!

我有一个任务要求我从用户那里获取一个字符串并将其传递到一个堆栈和一个队列中,然后使用这两个来比较字符以确定该字符串是否是回文。我已经编写了程序,但某处似乎存在一些逻辑错误。以下是相关代码:

public static void main(String[] args) {

    UserInterface ui = new UserInterface();
    Stack stack = new Stack();
    Queue queue = new Queue();
    String cleaned = new String();
    boolean palindrome = true;

    ui.setString("Please give me a palindrome.");
    cleaned = ui.cleanString(ui.getString());

    for (int i = 0; i < cleaned.length(); ++i) {
        stack.push(cleaned.charAt(i));
        queue.enqueue(cleaned.charAt(i));
    }

    while (!stack.isEmpty() && !queue.isEmpty()) {
        if (stack.pop() != queue.dequeue()) {
            palindrome = false;
        }
    }

    if (palindrome) {
        System.out.printf("%s is a palindrome!", ui.getString());
    } else
        System.out.printf("%s is not a palindrome :(", ui.getString());

    stack.dump();
    queue.clear();

}

 public class Stack {

   public void push(char c) {
    c = Character.toUpperCase(c);
    Node oldNode = header;
    header = new Node();
    header.setData(c);
    header.setNext(oldNode);
  }

  public char pop() {
    Node temp = new Node();
    char data;
    if (isEmpty()) {
        System.out.printf("Stack Underflow (pop)\n");
        System.exit(0);
    }
    temp = header;
    data = temp.getData();
    header = header.getNext();
    return data;
  }

}

public class Queue {

  public void enqueue(char c) {
    c = Character.toUpperCase(c);
    Node n = last;
    last = new Node();
    last.setData(c);
    last.setNext(null);
    if (isEmpty()) {
        first = last;
    } else n.setNext(last);     
  }

  public char dequeue() {
    char data;
    data = first.getData();
    first = first.getNext();
    return data;
  }

}

public String cleanString(String s) {
    return s.replaceAll("[^A-Za-z0-9]", "");
}

基本上,在 Eclipse 中通过调试器运行我的代码时,我的 pop 和 dequeue 方法似乎只选择某些字母数字。我正在使用replaceAll("[^A-Za-z0-9]", "") 来“清理”用户的任何非字母数字字符(!、?、& 等)的字符串。当我说它只选择某些字符时,似乎没有任何我可以辨别的模式。有什么想法吗?

【问题讨论】:

  • 您能举一个会导致程序失败的输入示例吗?我没有立即发现您的算法有任何问题。
  • 也许这对我来说是一个愚蠢的问题,但为什么在这种情况下使用 ++i 而不是 i++ 呢?
  • @tkuzzy 我一直在使用一些,但通常是“太热而无法发出声音”。我还将所有字符都设置为大写,所以不应该有任何由大小写引起的问题。
  • 对于某些编译器/语言,生成的代码实际上可能对 ++i 更有效。我认为它不会影响 Java。 (我不记得它可以变得更快的真正原因——与寄存器有关?)
  • @BlackVegetable 这只是一种风格偏好。一位非常特别的教授让我对它感兴趣。应该在高性能情况下更快,但在使用 Java 时我认为这并不重要。

标签: java linked-list palindrome


【解决方案1】:

假设您的队列和堆栈是正确的,您的一般算法可以正常工作(我使用 jdk 中的 Deque 实现尝试了这个)。由于您的任务涉及数据结构,我几乎只是采用了您的主要逻辑并用 ArrayDequeue 替换了数据结构,所以我不觉得我在为您回答这个问题。

    String word = "ooffoo";

    word = word.replaceAll("[^A-Za-z0-9]", "");

    Deque<Character> stack = new ArrayDeque<Character>(word.length());
    Deque<Character> queue = new ArrayDeque<Character>(word.length());

    for (char c : word.toCharArray()) {
        stack.push(c);
        queue.add(c);
    }

    boolean pal = true;

    while (! stack.isEmpty() && pal == true) {
        if (! stack.pop().equals(queue.remove())) {
            pal = false;
        }
    }

    System.out.println(pal);

【讨论】:

    【解决方案2】:

    我建议使用调试器来准确查看正在比较的内容,或者至少吐出一些打印行:

    while (!stack.isEmpty() && !queue.isEmpty()) {
        Character sc = stack.pop();
        Character qc = queue.dequeue();
        System.out.println(sc + ":" + qc);
        if (sc != qc) {
            palindrome = false;
        }
    }
    

    【讨论】:

    • 另外,养成对所有类进行单元测试的习惯。如果您的堆栈和队列实现按预期工作,那么您以后在处理其他事情时不太可能将它们搞砸并返回进行“稍微调整”。
    • 当用作循环增量器时,++i 和 i++ 完全相同。仅在使用实际返回值时才重要。在这种情况下,无论你使用 i++ 还是 ++i,结果都是一样的,因为没有人使用返回值。
    • 是的,我想现在我想这是有道理的。
    猜你喜欢
    • 1970-01-01
    • 2013-02-17
    • 2015-06-12
    • 1970-01-01
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    • 2013-09-18
    • 2011-12-01
    相关资源
    最近更新 更多