I am using the StdIn.isEmpty() method from the Princeton libraries provided in the Algorithms Coursera algorithms course but am confused as to how it works. I have the statement
while (!StdIn.isEmpty())
with some code enclosed that reads user input but I can't seem to break out of the loop. By my understanding if I hit enter without typing in any text that should mean that standard input is empty and the while loop should be broken. I looked up the code for isEmpty but it did not clarify anything:
public static boolean isEmpty() {
return !scanner.hasNext();
}
Can someone clarify how standard input works and help me fix my misunderstanding of this method?
I think that on Mac you can use CMD+D
(⌘+D
) to mark the end of input to the shell. See: https://www.jetbrains.com/help/idea/debug-tool-window-console.html
Keyboard Shortcuts
The ⌘D key combination allows you to send EOF (end of file), i.e. to signal that no more data can be read from a data source.
On the issue of the Princeton libraries provided in the Algorithms - Part 1 in Coursera's course, you can play a bit with their code, particularly in the class import edu.princeton.cs.algs4.StdIn;
. Their implementation that uses that code is probably not the most sophisticated to play with the concepts:
while (!StdIn.isEmpty()) {
int p = StdIn.readInt();
int q = StdIn.readInt();
if (!uf.connected(p, q)) {
uf.union(p, q);
StdOut.println(p + " " + q);
}
}
Here's what I did:
Now to run that just do right-click on the code that has the class with the main static method, and choose Run (CTRL+SHIFT+R).
This will avoid the dreaded CMD+D and some issues that go with it if you want to write more code after the while loop - for instance, I added code to check if 2 objects are connect:
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...
}
Here's my very quick and dirty approach to the problem:
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) {}
}
}
Before reading each number, the program uses the method StdIn.isEmpty() to check whether there are any more numbers in the input stream. How do we signal that we have no more data to type? By convention, we type a special sequence of characters known as the end-of-file sequence. Unfortunately, the terminal applications that we typically encounter on modern operating systems use different conventions for this critically important sequence. In this book, we use Ctrl-D... Computer Science Sedgewick
Therefore isEmpty
is actually isCtrl-D
.
Also, try StdIn.isEmpty()
in the terminal application without anything beforehand will leave you with no boolean but a standard input stream requesting inputs. So when a program like the following one runs:
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);
}
}
, the standard input stream pops out when decide the conditional while (!StdIn.isEmpty)
for the first time instead of StdIn.readDouble()
. If you then type in some numbers, return them, causing standard input stream to be non-empty, the program would then jump inside the while body. I found out this is the case by testing
> java Average
[DrJava Input Box] (And I hit Ctrl+D here)
Average is NaN
NaN means n = 0 which means the while body was left no touched.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With