如何让StdIn.isEmpty()返回true?

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

我正在使用算法 Coursera 算法课程中提供的普林斯顿库中的 StdIn.isEmpty() 方法,但对其工作原理感到困惑。我有声明

while (!StdIn.isEmpty())

附带一些读取用户输入的代码,但我似乎无法跳出循环。根据我的理解,如果我按回车键而不输入任何文本,则意味着标准输入为空,并且 while 循环应该被打破。我查找了 isEmpty 的代码,但它没有澄清任何内容:

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

有人可以澄清标准输入的工作原理并帮助我纠正我对此方法的误解吗?

java eclipse algorithm stdin
4个回答
12
投票

在读取每个数字之前,程序使用 StdIn.isEmpty() 方法检查输入流中是否还有更多数字。我们如何表明我们没有更多数据可输入?按照惯例,我们键入一个特殊的字符序列,称为文件结尾序列。不幸的是,我们在现代操作系统上通常遇到的终端应用程序对这个极其重要的序列使用不同的约定。在本书中,我们使用 Ctrl-D... 计算机科学塞奇威克

因此

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,这意味着当身体没有被触摸时。


6
投票

我认为在 Mac 上您可以使用

CMD+D
(
⌘+D
) 来标记 shell 输入的结束。请参阅:https://www.jetbrains.com/help/idea/debug-tool-window-console.html

键盘快捷键

⌘D 组合键允许您发送 EOF(文件结束),即 表示无法从数据源读取更多数据。

关于 Coursera 课程的算法 - 第 1 部分中提供的普林斯顿库的问题,您可以稍微玩一下他们的代码,特别是在课程

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 项目
  2. 创建新的java包(将在src下)
  3. 为他们的示例创建新类,该类将有一个 main 方法
  4. 在项目中创建libs文件夹
  5. http://algs4.cs.princeton.edu/code/algs4.jar下载他们的代码并将该 jar 放在 libs 文件夹中
  6. 将该 lib 添加到项目 - 在 IntelliJ 的项目选项卡上,右键单击项目 > 打开模块设置 > 单击依赖项选项卡 > 单击“+” > JAR 或目录... > 从上面的 libs 文件夹中选择 jar
  7. 我更改了上面 while 循环中的代码,以便在 shell 上实现更好的用户交互(这里有创意 - 不使用 isEmpty(),而是使用检查 p 和 q 均为 0 来标记输入结束,例如.

现在要运行它,只需右键单击具有主静态方法的类的代码,然后选择“运行”(CTRL+SHIFT+R)。

如果您想在 while 循环后编写更多代码,这将避免可怕的 CMD+D 以及随之而来的一些问题 - 例如,我添加了代码来检查 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) {}
    }
}

2
投票
  1. Enter
    转到下一行
  2. 光标丢失
  3. 返回窗口/光标,尝试按
    Ctrl + Z
    StdIn.isEmpty()
    将返回
    true


0
投票

与算法 Coursera 课程提供的普林斯顿图书馆相同的

StdIn.isEmpty()
方法。

在 IntelliJ IDEA 中发送

EOF
的问题可能是由于与另一个快捷方式冲突,或者因为没有为
EOF
设置快捷方式。 可以通过更改 IDEA 快捷方式来修复,如下所示:

  1. 前往
    Settings
    ->
    Keymap
  2. 搜索
    eof
  3. 添加/更改任何你喜欢的快捷方式。

这应该允许您使用您设置的新键盘快捷键终止 Java 程序中的 while 循环。

© www.soinside.com 2019 - 2024. All rights reserved.