Steque 和 API 实现

Posted

技术标签:

【中文标题】Steque 和 API 实现【英文标题】:Steque and the API implementations 【发布时间】:2016-04-15 05:37:58 【问题描述】:

一个 steque 是一个堆栈结束队列,它是一种数据类型,它实现了 push、pop 和 enqueue 以及您希望添加的任何其他功能。

请注意,我正在使用基于链表的方法来实现 steque。下面是我的整个 Steque 类的代码,我遇到的问题是,每当我尝试从 steque 中弹出一些元素或迭代它时,我都会得到 NullPointerException。 push() 和 enqueue() 方法在我测试时似乎工作得很好,我确实彻底检查了我的 pop() 和 iterator(),但似乎找不到任何可能导致任何 NullPointerException 的错误。对于我的代码如何解决这个问题的任何帮助将不胜感激!

public class Steque<Item> implements Iterable<Item> 
    private int N;
    private Node first;
    private Node last;

    private class Node 
        private Item item;
        private Node next;
        private Node prev;
    

    /**
     * create an empty steque
     */
    public Steque() 
        N = 0;
        first = null;
        last = null;
    

    /**
     * pop (return) the first item on top of stack and modify first
     * accordingly to refer to next node.
     */
    public Item pop() 
        if (isEmpty()) throw new RuntimeException("Steque underflow");
        Item item = first.item;
        first = first.next;
        N--;
        return item;
    

    /**
     * push item on top of the stack and modify the first pointer
     * to refer to the newly added item.
     */
    public void push(Item item) 
        Node oldfirst = first;
        Node first = new Node();
        first.item = item;
        first.next = oldfirst;
        if (oldfirst != null)
            oldfirst.prev = first;
        ++N;
    

    /**
     * push item on bottom of the stack and reset the last pointer
     * to refer to the newly added item.
     */
    public void enqueue(Item item) 
        Node oldlast = last;
        Node last = new Node();
        last.item = item;
        last.prev = oldlast;
        if (oldlast != null)
            oldlast.next = last;
        ++N;
    

    public Item peek() 
        if (isEmpty()) throw new RuntimeException("Steque underflow");
        return first.item;
    

    public boolean isEmpty() 
        return N == 0;
    

    public int size() 
        return N;
    

    /**
     *  prints the steque from top to bottom

    private void printState() 
        System.out.println("Printing steque below: top --> bottom ");
        for (Node idx = this.first; idx!= null; idx = idx.next) 
            System.out.print(idx.item + " - ");
        
        System.out.println();
    
    */

    public String toString() 
        StringBuilder s = new StringBuilder();
        for (Item i : this) 
            s.append(i + " ");
        
        return s.toString().trim();
    

    public Iterator iterator() 
        return new LIFOIterator();
    

    /**
     * iterator that implements hasNext(), next(), and remove().
     */
    private class LIFOIterator implements Iterator<Item>
       // support LIFO iteration
        private Node current = first;
        public boolean hasNext()  return current.next != null; 
        public void remove() 
            Node n = first;
            while (n.next.next != null) 
                n = n.next;
            
            n.next = null;
            --N;
        

        public Item next() 
            if (!hasNext()) 
                throw new NoSuchElementException();
            Item item = current.item;
            current = current.next;
            return item;
        
    

    /**
     * a simple test client
     */
    public static void main(String[] args) 
        Steque<String> steq = new Steque<String>();
        while (!StdIn.isEmpty()) 
            String item = StdIn.readString();
            if (!item.equals("-")) 
                //steq.push(item);
                steq.enqueue(item);
            
            /*
            else if (!steq.isEmpty()) 
                System.out.print(steq.pop() + " ");
            
            */
        
        System.out.println("(" + steq.size() + " left on steque)");
        Iterator itr = steq.iterator();
        System.out.println("printing steque of strins below: ");
        while(itr.hasNext()) 
            System.out.print(itr.next() + " ");
        
    

注意:我在这里省略了所有的 import 语句,但它们确实包含在我的程序中,因此保证此代码中没有“未定义的方法”或“未声明的标识符”错误。

【问题讨论】:

StdIn 类型不是标准 Java 类型。这使得很难复制和粘贴您的程序并尝试查找错误。 您的lastfirst 没有以任何方式连接。尝试在新的 steque 上执行下一个代码:steq.enqueue("asd"); steq.pop(); @user3707125 last 和 first 不应该直接连接,它们代表顶部和底部堆栈,如果你愿意的话,在堆栈中。 @jah 是的,我知道这一点。 StdIn 是由一些普林斯顿 CS 教授编写和定义的,旨在“帮助”学生以最少的 Java 知识进行学习。如果您要复制和粘贴来测试代码,则可能需要使用扫描仪。 【参考方案1】:

问题是,当您仅使用 enqueue 方法时,您的 first 变量不会被填充。

因此,访问该字段的方法会触发 NPE。

hasNext 通过current 使用该字段。

IMO 的解决方案是在 enqueue 中捕获 N == 0 的特殊元素,并用可用元素填充第一个元素。

我试过了

if(N==0)
  first = last

在 enqueue 中初始化 last 之后,它可以在没有 NPE 的情况下工作。

【讨论】:

我明白你的意思,我已经对我的 push() 和 enqueue() 方法进行了相应的更改,但是每当我尝试调用这两种方法时,我仍然会收到 NPE,我在 push() 中所做的更改) 是我添加了 else 情况,如果 steque 最初是空的,那么我将设置 last = first。出于同样的原因,在我的 enqueue() 方法中,我添加了 else 条件,如果 steque 最初是空的,那么我将设置 first = last。关于这仍然给我NPE的任何建议?非常感谢:) 你真的不需要“其他情况”。您只需要一个如上所示的 if 条件。显然在last初始化之后。我检查了入队,它在没有 NPE 的情况下工作。也许你应该发布相应的 sn-ps。 我一直在测试我的代码,真的无法弄清楚我在以下哪个方法中出错了,我在此处附加了多个 pop()、push() 和 enqueue() cmets,因为它们不适合单个评论块:public Item pop() if (isEmpty()) throw new RuntimeException("Steque underflow");Item item = first.item;first = first.next;N--;if (isEmpty()) last = null; return item; 这是我的 push() 方法: public void push(Ite​​m item) Node oldfirst = first;节点优先 = new Node(); first.item = 项目; first.next = oldfirst; if (oldfirst != null) oldfirst.prev = first; else // 如果只有一个元素 last = first; ++N; 即使在我阅读了规则之后,也不确定如何在评论中格式化代码的 sn-p,但这是我的 enqueue() 方法:
--- --- public void enqueue(项目 item) 节点 oldlast = last;上一个节点 = 新节点();最后一个项目 = 项目; last.prev = oldlast; if (oldlast != null) oldlast.next = last; if (last.prev == null) first = last; ++N;

以上是关于Steque 和 API 实现的主要内容,如果未能解决你的问题,请参考以下文章

node.js api 网关实现和护照认证

高德地图api实现地址和经纬度的转换(python)

WebHook和API 及.NetFramework 实现

通过Eolinker实现API设计

API 版本控制和重用版本更新的现有实现

微服务架构开发实战:API网关意义和常见API网关的实现方式