java 如何使StdIn.isEmpty()返回true?

23c0lvtd  于 2023-05-21  发布在  Java
关注(0)|答案(4)|浏览(143)

我正在使用Coursera算法课程中提供的Princeton库中的StdIn.isEmpty()方法,但我对它的工作原理感到困惑。我拿到口供了

while (!StdIn.isEmpty())

其中包含一些读取用户输入的代码,但我似乎无法打破循环。根据我的理解,如果我不输入任何文本就按回车键,这应该意味着标准输入是空的,while循环应该被打破。我查看了isEmpty的代码,但它没有澄清任何事情:

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

有人能解释一下标准输入是如何工作的,并帮助我纠正我对这种方法的误解吗?

wwtsj6pe

wwtsj6pe1#

在阅读每个数字之前,程序使用方法StdIn.isEmpty()检查输入流中是否还有数字。我们如何发出没有更多数据要输入的信号?按照惯例,我们键入一个特殊的字符序列,称为文件结束序列。不幸的是,我们通常在现代操作系统上遇到的终端应用程序对这个至关重要的序列使用不同的约定。在本书中,我们使用Ctrl-D…* 计算机科学Sedgewick*
因此isEmpty实际上是isCtrl-D
此外,在终端应用程序中尝试StdIn.isEmpty(),而不事先做任何事情,将不会给您留下布尔值,而是一个标准的输入流请求输入。因此,当运行类似以下程序时:

public class Average
  {
     public static void main(String[] args)
     {  // Average the numbers on standard input.
        double sum = 0.0;
        int n = 0;
        while (!StdIn.isEmpty())
        {  // Read a number from standard input and add to sum.
           double value = StdIn.readDouble();
           sum += value;
           n++;
        }
        double average = sum / n;
        StdOut.println("Average is " + average);
     }
 }

,当第一次决定条件while (!StdIn.isEmpty)而不是StdIn.readDouble()时,标准输入流弹出。如果你输入一些数字,返回它们,导致标准输入流为非空,程序将跳转到while体中。我通过测试发现是这样的

> java Average
 [DrJava Input Box] (And I hit Ctrl+D here)
Average is NaN

NaN意味着n = 0,这意味着身体没有被触摸。

1sbrub3j

1sbrub3j2#

我认为在Mac上可以使用CMD+D⌘+D)来标记shell的输入结束。参见:https://www.jetbrains.com/help/idea/debug-tool-window-console.html

快捷键

D组合键允许您发送EOF(文件结束),即以发信号通知不能从数据源读取更多数据。
在Coursera课程的算法-第1部分中提供的Princeton库的问题上,您可以使用它们的代码,特别是在类import edu.princeton.cs.algs4.StdIn;中。他们使用这些代码的实现可能不是最复杂的概念:

while (!StdIn.isEmpty()) {
     int p = StdIn.readInt();
     int q = StdIn.readInt();

     if (!uf.connected(p, q)) {
         uf.union(p, q);
         StdOut.println(p + " " + q);
     }
}

我是这么做的
1.在IntelliJ中创建新的Java项目
1.创建新的Java包(将在src下)
1.为它们的例子创建一个新的类,它将有一个main方法
1.已在项目中创建libs文件夹
1.从http://algs4.cs.princeton.edu/code/algs4.jar下载了他们的代码,并将该jar放在libs文件夹中。
1.在IntelliJ的项目选项卡上,右键单击项目>打开模块设置>单击依赖项选项卡>单击'+' > JAR或目录...>从上面的libs文件夹中选择jar
1.我更改了上面while循环中的代码,以便在shell上有更好的用户交互(这里要有创意-而不是使用isEmpty(),例如,检查p和q是否都为0以标记输入结束。
现在要运行它,只需右键单击包含主静态方法的类的代码,然后选择Run(CTRL+SHIFT+R)。
这将避免可怕的CMD+D和一些问题,如果你想在while循环后编写更多的代码-例如,我添加了代码来检查2个对象是否连接:

StdOut.println("Check if 2 objects are connected: ");
try {
    Scanner reader = new Scanner(System.in);  // Reading from System.in
    System.out.println("Enter first object: ");
    int n = reader.nextInt(); // Scans the next token of the input as an int.
    System.out.println("Enter second object: ");
    int m = reader.nextInt(); // Scans the next token of the input as an int.
    StdOut.println(uf.connected(n, m) ? "Connected" : "Not Connected");
} catch(Exception e) {
    // whatever...
}

以下是我对这个问题的快速而肮脏的方法:

package com.algorithms;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.UF;

import java.util.Scanner;

public class Week1 {
    private static UF uf;

    public static void main(String[] args)
    {
        StdOut.println("Enter the total number of objects: ");
        int N = StdIn.readInt();

        StdOut.println("Enter the unions between any of those objects...");

        Week1.uf = new UF(N);
        while (true) {

            int p = StdIn.readInt();
            int q = StdIn.readInt();

            if (!uf.connected(p, q)) {
                Week1.uf.union(p, q);
                StdOut.println(p + " " + q);
            }

            if(p==0 && q==0) break;
        }
        checkIfConnected();
    }

    private static void checkIfConnected()
    {
        StdOut.println("Check if 2 objects are connected: ");
        try {
            Scanner reader = new Scanner(System.in);  // Reading from System.in
            System.out.println("Enter first object: ");
            int n = reader.nextInt(); // Scans the next token of the input as an int.
            System.out.println("Enter second object: ");
            int m = reader.nextInt(); // Scans the next token of the input as an int.
            StdOut.println(Week1.uf.connected(n, m) ? "Connected" : "Not Connected");
        } catch(Exception e) {}
    }
}
q0qdq0h2

q0qdq0h23#

1.按Enter到下一行
1.光标丢失
1.返回窗口/光标,尝试按Ctrl + ZStdIn.isEmpty()将返回true

relj7zay

relj7zay4#

与Coursera算法课程中提供的Princeton库中的StdIn.isEmpty()方法相同。
在IntelliJ IDEA中发送EOF的问题可能是由于与其他快捷方式冲突,或者因为没有为EOF设置快捷方式。我只是通过修改我的IDEA快捷方式来修复它,如下所示:
1.转到Settings-> Keymap
1.搜索eof
1.添加/更改任何你喜欢的快捷方式。
IDEA set EOF shortcut
这将允许您使用新设置的键盘快捷键终止Java程序中的while循环。

相关问题