解决方案 »

  1.   

    补充一个问题:StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));和Scanner sc = new Scanner(new BufferedInputStream(System.in));性能上有多大差别?
      

  2.   

    额。。我发现几个问题,首先循环里应该是判断i<N,因为你的i是从0开始的。然后while循环里面的st.nextToken()没有必要,可以删掉,因为当你在执行 while(st.nextToken() !=StreamTokenizer.TT_EOL)时,已经执行了一次nextToken(),相当于你已经获取到了下一个token,如果你在while循环里又执行一次nextToken(),那么会有token丢失了。至于最后一行无法读取,是因为你最后一行没打回车。我帮你改好了,注意最后一行打回车哦,希望能帮到你~
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.StreamTokenizer;
    import java.text.ParseException;public static void main(String[] args) throws IOException, ParseException {

    StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    st.nextToken();
    int N=(int)st.nval;     //输入数据组数

    st.eolIsSignificant(true);   //设置识别行尾,否则无限输入
    st.ordinaryChar('/');           

    String tempN="",tempNum=""; for(int i=0;i<N;i++){  //由 i<=N 改成了 i<N
    while(st.nextToken() !=StreamTokenizer.TT_EOL){   
    //st.nextToken();  删掉这句
    if(st.ttype==StreamTokenizer.TT_WORD){ //字母
    tempN=st.sval;
    }
    else if(st.ttype==StreamTokenizer.TT_NUMBER){   //数字
    tempNum+=String.valueOf((int)st.nval)+"-";
    }
    }
    System.out.println(tempNum+" "+tempN);
    tempN="";
    tempNum="";
    }
    }
      

  3.   


    …不小心把调试中的代码发上来了,确实是<N和没有nextToken,这段代码跳过了前四行的姓名部分。
    不过最后一行没打回车是何解?
    我试了一下输入时多复制一空行、多复制一行并加上\n、在最后一行后加上\n(或\r),都还是少输入一行啊?
      

  4.   


    …不小心把调试中的代码发上来了,确实是<N和没有nextToken,这段代码跳过了前四行的姓名部分。
    不过最后一行没打回车是何解?
    我试了一下输入时多复制一空行、多复制一行并加上\n、在最后一行后加上\n(或\r),都还是少输入一行啊?

    代码的确是有问题的。。不好意思哈,可能我当时没看清楚,你在for循环前再加一个st.nextToken();就行了~
      

  5.   


    加上之后的效果是这样:之前是这样:即相当于在输入后不换行输出,仍然是少一行…是否和这两句有关系:st.eolIsSignificant(true);   //设为true时识别行尾的换行,否则视为空格,默认为false
    while(st.nextToken() !=StreamTokenizer.TT_EOL)  //这里是否要改成!=xx.TT_EOF(但是输入停不下来)
      

  6.   


    加上之后的效果是这样:之前是这样:即相当于在输入后不换行输出,仍然是少一行…是否和这两句有关系:st.eolIsSignificant(true);   //设为true时识别行尾的换行,否则视为空格,默认为false
    while(st.nextToken() !=StreamTokenizer.TT_EOL)  //这里是否要改成!=xx.TT_EOF(但是输入停不下来)

    奇怪,为什么我这里不是这样?我是可以的啊。你第一张图片中的最后一个没打回车啊?
      

  7.   


    尝试了一下,像这样逐行输入是可以显示所有输入的:
    2 →回车
    John 2001/05/12 →回车
    Tom 1814/09/06 →回车但是像题中那样直接输入:
    5
    John 2001/05/12
    Tom 1814/09/06
    Ann 2121/01/30
    James 1814/09/05
    Steve 1967/11/20
    会缺少最后一行数据。进一步修改了一下,去除for前面的nextToken,并把条件改为<=N:
     
    public static void main(String[] args) throws IOException, ParseException {          
        StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        st.nextToken();
        int N=(int)st.nval;     //输入数据组数
         
        st.eolIsSignificant(true);   //设置识别行尾,否则无限输入
        st.ordinaryChar('/');           
         
        String tempN="",tempNum="";
    //         st.nextToken(); // <-------这句去掉
        for(int i=0;i<=N;i++){    //<------- 改成 i<=N       
            while(st.nextToken() !=StreamTokenizer.TT_EOL){   
                if(st.ttype==StreamTokenizer.TT_WORD){        //字母           
                    tempN=st.sval;           
                }
                else if(st.ttype==StreamTokenizer.TT_NUMBER){   //数字
                    tempNum+=String.valueOf((int)st.nval)+"-";
                }
            }
            System.out.println(tempNum+" "+tempN);
            tempN="";
            tempNum="";           
        }
    }
    }
    /*在输入数据后多加一个空行,如下:
    5
    John 2001/05/12
    Tom 1814/09/06
    Ann 2121/01/30
    James 1814/09/05
    Steve 1967/11/20 * 
     */这样是可以正确输出所有数据的。
      

  8.   


    卧槽突然明白你说的少打个空格是什么意思了…输入题中的数据后会立即输出4行,然后发现程序运行还没结束,再按一下回车才会输出最后一行,如果用Scanner的话,这里是不需要多加上一个回车的。这样最后修正的代码如下 public static void main(String[] args) throws IOException, ParseException {     
        StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        st.nextToken();
        int N=(int)st.nval;     //输入数据组数
         
        st.eolIsSignificant(true);   //设置识别行尾,否则无限输入
        st.ordinaryChar('/');           
         
        String tempN="",tempNum="";     for(int i=0;i<=N;i++){    //<------- 改成 i<=N       
            while(st.nextToken() !=StreamTokenizer.TT_EOL){   
                if(st.ttype==StreamTokenizer.TT_WORD){        //字母           
                    tempN=st.sval;           
                }
                else if(st.ttype==StreamTokenizer.TT_NUMBER){   //数字
                    tempNum+=String.valueOf((int)st.nval)+"-";
                }
            }
            System.out.println(tempNum+" "+tempN);
            tempN="";
            tempNum="";           
        }
    }去掉了for前面的nextToken(会导致输出第一行和最后一行输入在同一行),循环条件改为<=N.
    复制输入数据后,再按一次回车,结果正确:
    加上一个判断就可以去掉输出中的空行:         if(i==N-1){
             System.out.print(tempNum+" "+tempN);
            }
    问题基本解决,十分感谢扩展:有没有方法,能像用Scanner输入那样,把输入直接复制过来即可,不需要再手动补一个回车,或者多复制一行空格?
      

  9.   


    卧槽突然明白你说的少打个空格是什么意思了…输入题中的数据后会立即输出4行,然后发现程序运行还没结束,再按一下回车才会输出最后一行,如果用Scanner的话,这里是不需要多加上一个回车的。这样最后修正的代码如下 public static void main(String[] args) throws IOException, ParseException {     
        StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        st.nextToken();
        int N=(int)st.nval;     //输入数据组数
         
        st.eolIsSignificant(true);   //设置识别行尾,否则无限输入
        st.ordinaryChar('/');           
         
        String tempN="",tempNum="";     for(int i=0;i<=N;i++){    //<------- 改成 i<=N       
            while(st.nextToken() !=StreamTokenizer.TT_EOL){   
                if(st.ttype==StreamTokenizer.TT_WORD){        //字母           
                    tempN=st.sval;           
                }
                else if(st.ttype==StreamTokenizer.TT_NUMBER){   //数字
                    tempNum+=String.valueOf((int)st.nval)+"-";
                }
            }
            System.out.println(tempNum+" "+tempN);
            tempN="";
            tempNum="";           
        }
    }去掉了for前面的nextToken(会导致输出第一行和最后一行输入在同一行),循环条件改为<=N.
    复制输入数据后,再按一次回车,结果正确:
    加上一个判断就可以去掉输出中的空行:         if(i==N-1){
             System.out.print(tempNum+" "+tempN);
            }
    问题基本解决,十分感谢扩展:有没有方法,能像用Scanner输入那样,把输入直接复制过来即可,不需要再手动补一个回车,或者多复制一行空格?
    你意思是一定要用 StreamTokenizer 来实现?
      

  10.   

    Scanner也是要按一下回车的,而且也是第一行输出和输入在同一行…思维混乱了
    这样问题就全部解决了
      

  11.   

    Scanner也是要按一下回车的,而且也是第一行输出和输入在同一行…思维混乱了
    这样问题就全部解决了
    OK,你可以这样想,如果你不打回车,那程序怎么知道你这一行什么时候结束,也许你后面还想输入呢?它不可能自己就把你的输入结束了吧?总该有个符号告诉它这行结束了。
      

  12.   


    因为PAT的不给java额外的时间,Scanner经常超时,StreamTokenizer则能满足大多数情况。