当从循环中的扫描仪读取时,它进入无限循环[重复]

问题描述 投票:0回答:2

这里有两个问题。当我尝试使用“递归迭代器”遍历这个本地二叉树时(迭代遍历树的迭代器,将元素放入队列,然后从队列前面删除元素)。迭代器倾向于向后迭代(从最大到最小)而不是顺序(从最小到最大)。此外,当我尝试使用ScannernextInt()读取用户输入时,程序进入无限循环。当用户输入无效数字时,我正试图抓住InputMismatchException。 在下面的代码段中,当用户没有输入数字以便程序继续正常时,我正在捕获InputMismatchException。 测试文件:

package assignments.unit9;
import java.util.*;
import static java.lang.System.*;
import java.io.*;
public class BinaryTreeTest
{
    private static BinaryTree<Item> tree;
    static Scanner user;

    public static void main(String... args)
    {
        user = new Scanner(System.in);
        int choice;
        do
        {
            out.println("1. Read data from disk");
            out.println("2. Print the tree in order");
            out.println("3. Search the tree");
            out.println("4. Delete from the tree");
            out.println("5. Count the nodes in the tree");
            out.print("0. Quit\n>");
            try
            {
                choice = user.nextInt();
            }
            catch(InputMismatchException e)
            {
                choice = -1;
            }
            switch(choice)
            {
                case 0:
                    exit(0);
                case 1:
                    try
                    {
                        readFromDisk();
                    }
                    catch(FileNotFoundException e)
                    {
                        err.println("Sorry, but the file could not be opened: " + e.getMessage());
                    }
                    break;
                case 2:
                    if(tree == null)
                    {
                        err.println("Must read file first");
                        break;
                    }
                    printTree();
                    break;
                case 3:
                    if(tree == null)
                    {
                        err.println("Must read file first");
                        break;
                    }
                    searchTree();
                    break;
                case 4:
                    if(tree == null)
                    {
                        err.println("Must read file first");
                        break;
                    }
//                  deleteFromTree();
                    break;
                case 5:
                    if(tree == null)
                    {
                        err.println("Must read file first");
                        break;
                    }
                    countNodes();
                    break;
                default:
                    err.println("Invalid choice. The available choices are:");
                    break;
            }
        }
        while(choice != 0);
    }

    public static void readFromDisk() throws FileNotFoundException
    {
        Scanner file = new Scanner(new File("file20.txt"));
        tree = new BinaryTree<Item>();
        if(file.hasNextInt())
            file.nextInt(); //skip the first integer
        while(file.hasNextInt())
        {
            tree.add(new Item(file.nextInt(), file.nextInt()));
        }
    }

    public static void printTree()
    {
        tree.inorder();
    }

    public static void searchTree()
    {
        out.println("Enter ID value to search for (-1 to return)");
        int search;
        Item searched;
        while((search = user.nextInt()) != -1)
        {
            out.println(searched = tree.find(new Item(search, 0)));
            if(searched == null)
                out.println("\b\b\b\b\bNo such part in stock");
        }
    }

    public static void countNodes()
    {
        out.println(tree.countNodes());
    }
}

在BinaryTree类中,我尝试以递归方式遍历它(请参阅iterator()和asQueue()):

package assignments.unit9;
import java.util.*;
public class BinaryTree<E extends Comparable<E>> implements Iterable<E>
{
    private TreeNode<E> root;

    public void add(E value)
    {
        if(root == null)
        {
            root = new TreeNode<E>(value);
        }
        else
        {
            TreeNode<E> temp = root, upFrom = null;
            boolean goesOnLeft = false;
            while(true)
            {
                if(temp == null)
                {
                    if(goesOnLeft)
                        upFrom.setLeft(new TreeNode<E>(value));
                    else
                        upFrom.setRight(new TreeNode<E>(value));
                    break;
                }
                else if(temp.getValue().compareTo(value) < 0)   //goes on left
                {
                    upFrom = temp;
                    temp = upFrom.getLeft();
                    goesOnLeft = true;
                    continue;
                }
                else    //goes on right
                {
                    upFrom = temp;
                    temp = upFrom.getRight();
                    goesOnLeft = false;
                    continue;
                }
            }
        }
    }

    public void inorder()
    {
        try
        {
            inorder(root);
        }
        catch(StackOverflowError e)
        {
            System.err.println("Increase stack size to print remaining elements");
        }
    }

    private void inorder(TreeNode<E> t)
    {
        if(t == null)
            return;
        inorder(t.getLeft());
        System.out.println(t.getValue());
        inorder(t.getRight());
    }

    private ArrayDeque<E> asQueue(TreeNode<E> t, ArrayDeque<E> toAdd)
    {
        try
        {
            if(toAdd == null)
                toAdd = new ArrayDeque&lt;E>();
            if(t == null)
                return toAdd;
            asQueue(t.getLeft(), toAdd);
            toAdd.addLast(t.getValue());
            asQueue(t.getRight(), toAdd);
            ret:
            return toAdd;
        }
        catch(StackOverflowError e)
        {
            throw new InternalError();
        }
    }

    public Iterator<E> iterator()
    {
        return new Iterator<E>()
        {
            private ArrayDeque<E> d = asQueue(root, null);

            public E next()
            {
                return d.pop();
            }

            public boolean hasNext()
            {
                return !d.isEmpty();
            }

            public void remove()
            {
                throw new UnsupportedOperationException();
            }
        };
    }

    public int countNodes()
    {
        int toReturn = 0;
        for(E elem : this)
            ++toReturn;
        return toReturn;
    }

    public E find(E toFind)
    {
        for(E elem : this)
        {
            if(elem.equals(toFind))
                return elem;
        }
        return null;
    }
}

TreeNode类:

package assignments.unit9;
import java.util.Objects;
public class TreeNode<T>
{
    private T value;
    private TreeNode<T> left, right;

    /**
     * Constructs a new TreeNode value with the left and right pointers {@code null}.
     * 
     * @param value the item to be referenced
     * 
     * @throws NullPointerException if {@code value} is {@code null}.
     */
    public TreeNode(T value)
    {
        this.value = Objects.requireNonNull(value);
    }

    /**
     * Constructs a new TreeNode value with the specified left and right pointers.
     * 
     * @param value the item to be referenced
     * @param left the TreeNode value to the left.
     * @param right the TreeNode value to the right.
     * 
     * @throws NullPointerException if {@code value} is {@code null}.
     */
    public TreeNode(T value, TreeNode<T> left, TreeNode<T> right)
    {
        this.value = Objects.requireNonNull(value);
        this.left = left;
        this.right = right;
    }

    public T getValue()
    {
        return value;
    }

    public TreeNode<T> getLeft()
    {
        return left;
    }

    public TreeNode<T> getRight()
    {
        return right;
    }

    public void setValue(T value)
    {
        this.value = Objects.requireNonNull(value);
    }

    public void setLeft(TreeNode<T> left)
    {
        this.left = left;
    }

    public void setRight(TreeNode<T> right)
    {
        this.right = right;
    }
}

数据类型(项目):

package assignments.unit9;
import java.util.*;
public class Item implements Comparable<Item>
{

    private int myID;
    private int myInv;

    //Comparators
    public static class IDComparator implements Comparator<Item>
    {
        public int compare(Item i1, Item i2)
        {
            return i1.getID() - i2.getID();
        }

        @Override
        public boolean equals(Object obj)
        {
            return obj instanceof IDComparator;
        }
    }

    public static class InvComparator implements Comparator<Item>
    {
        public int compare(Item i1, Item i2)
        {
            return i1.getInv() - i2.getInv();
        }

        @Override
        public boolean equals(Object obj)
        {
            return obj instanceof InvComparator;
        }
    }

    public Item(int id, int inv)
    {
        myID = id;
        myInv = inv;
    }

    public int getID()
    {
        return myID;
    }  
    public int getInv()
    {
        return myInv;
    }
    public int compareTo(Item i)
    {
        if(i == null)
            throw new NullPointerException();
        return this.myID - i.myID;
    }

    @Override
    public boolean equals(Object otherObject)
    {
        Item i;
        try
        {
            i = (Item) otherObject;
            return myID == i.myID;
        }
        catch(ClassCastException ex)
        {
            return false;
        }
    }
    public String toString()
    {
        return "ID: " + myID + "\tInventory number: " + myInv + "\n";
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(myID, myInv);
    }
}

这是输入文件。对不起,如果这很多:

20
       196        60
     18618        64
      2370        65
     18410        56
     18465        27
     19967        45
     17911        96
       184        14
     18871        69
     14088        92
     18061         3
       206        31
     13066         8
     12705        14
     15917        51
     15814        60
     15320        82
      8303        90
      7282        73
     12328        63
java java.util.scanner infinite-loop binary-search-tree
2个回答
1
投票

您的打印输出功能以相反的顺序打印节点,因为这是您存储它们的方式;你的二叉树在左边而不是在右边有较大的值,因为你的'add'函数中有一个“>”而不是“<”。改变它,它们出现增加而不是减少。

我仍然没有看到你无限循环的条件,我自己也没有。将程序放入调试器并跟踪它的运行情况,直到找到它为止。老实说,我认为我已经在这个问题上做得不够了(我没有Java 7并且不得不将它回填到Java 6来运行它),而且我还在继续。


0
投票

好的,问题解决了。问题是,当我需要一个<时,我输入了一个>,所以我最后得到的是左边较大的值和右边较小的值,所以我的inorder遍历是向后的。其次,捕捉InputMismatchException引起的无限循环是Scanner类中的一个错误:

  1. 程序启动,启动循环调用in.nextInt()块中的try
  2. 当用户输入非数字时,扫描仪会抛出一个InputMismatchException,它会将流量转移到catch块,这会将choice设置为-1,从而导致显示无效的文本块。
  3. 但奇怪的是,在下一次迭代中,当调用nextInt()时,它会立即抛出异常而不是获取输入,如果将一个print语句添加到catch块中就可以看到。谢谢所有帮助过我的人。
© www.soinside.com 2019 - 2024. All rights reserved.