commit 00a84fbc013dcff41dfc6152944b493dfbcf4191
Author: 王立苏 <467322500@qq.com>
Date: Sat Apr 17 14:46:32 2021 +0800
g08-v1.0.2
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..a221f6d
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/../../../../../:\AI_Study\AI2021\SearchFramework1.0.1\.idea/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/artifacts/framework1_0_1.xml b/.idea/artifacts/framework1_0_1.xml
new file mode 100644
index 0000000..2420375
--- /dev/null
+++ b/.idea/artifacts/framework1_0_1.xml
@@ -0,0 +1,6 @@
+
+ * The Locale used is: language = English, country = US. This is consistent + * with the formatting conventions with Java floating-point literals, + * command-line arguments (via {@link Double#parseDouble(String)}) + * and standard output. + *
+ * For additional documentation, see + * Section 3.1 of + * Computer Science: An Interdisciplinary Approach + * by Robert Sedgewick and Kevin Wayne. + *
+ * Like {@link Scanner}, reading a token also consumes preceding Java + * whitespace, reading a full line consumes + * the following end-of-line delimeter, while reading a character consumes + * nothing extra. + *
+ * Whitespace is defined in {@link Character#isWhitespace(char)}. Newlines + * consist of \n, \r, \r\n, and Unicode hex code points 0x2028, 0x2029, 0x0085; + * see + * Scanner.java (NB: Java 6u23 and earlier uses only \r, \r, \r\n). + * + * @author David Pritchard + * @author Robert Sedgewick + * @author Kevin Wayne + */ +public final class In { + + ///// begin: section (1 of 2) of code duplicated from In to StdIn. + + // assume Unicode UTF-8 encoding + private static final String CHARSET_NAME = "UTF-8"; + + // assume language = English, country = US for consistency with System.out. + private static final Locale LOCALE = Locale.US; + + // the default token separator; we maintain the invariant that this value + // is held by the scanner's delimiter between calls + private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\p{javaWhitespace}+"); + + // makes whitespace characters significant + private static final Pattern EMPTY_PATTERN = Pattern.compile(""); + + // used to read the entire input. source: + // http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html + private static final Pattern EVERYTHING_PATTERN = Pattern.compile("\\A"); + + //// end: section (1 of 2) of code duplicated from In to StdIn. + + private Scanner scanner; + + /** + * Initializes an input stream from standard input. + */ + public In() { + scanner = new Scanner(new BufferedInputStream(System.in), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + + /** + * Initializes an input stream from a socket. + * + * @param socket the socket + * @throws IllegalArgumentException if cannot open {@code socket} + * @throws IllegalArgumentException if {@code socket} is {@code null} + */ + public In(Socket socket) { + if (socket == null) throw new IllegalArgumentException("socket argument is null"); + try { + InputStream is = socket.getInputStream(); + scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + catch (IOException ioe) { + throw new IllegalArgumentException("Could not open " + socket, ioe); + } + } + + /** + * Initializes an input stream from a URL. + * + * @param url the URL + * @throws IllegalArgumentException if cannot open {@code url} + * @throws IllegalArgumentException if {@code url} is {@code null} + */ + public In(URL url) { + if (url == null) throw new IllegalArgumentException("url argument is null"); + try { + URLConnection site = url.openConnection(); + InputStream is = site.getInputStream(); + scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + catch (IOException ioe) { + throw new IllegalArgumentException("Could not open " + url, ioe); + } + } + + /** + * Initializes an input stream from a file. + * + * @param file the file + * @throws IllegalArgumentException if cannot open {@code file} + * @throws IllegalArgumentException if {@code file} is {@code null} + */ + public In(File file) { + if (file == null) throw new IllegalArgumentException("file argument is null"); + try { + // for consistency with StdIn, wrap with BufferedInputStream instead of use + // file as argument to Scanner + FileInputStream fis = new FileInputStream(file); + scanner = new Scanner(new BufferedInputStream(fis), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + catch (IOException ioe) { + throw new IllegalArgumentException("Could not open " + file, ioe); + } + } + + + /** + * Initializes an input stream from a filename or web page name. + * + * @param name the filename or web page name + * @throws IllegalArgumentException if cannot open {@code name} as + * a file or URL + * @throws IllegalArgumentException if {@code name} is {@code null} + */ + public In(String name) { + if (name == null) throw new IllegalArgumentException("argument is null"); + if (name.length() == 0) throw new IllegalArgumentException("argument is the empty string"); + try { + // first try to read file from local file system + File file = new File(name); + if (file.exists()) { + // for consistency with StdIn, wrap with BufferedInputStream instead of use + // file as argument to Scanner + FileInputStream fis = new FileInputStream(file); + scanner = new Scanner(new BufferedInputStream(fis), CHARSET_NAME); + scanner.useLocale(LOCALE); + return; + } + + // resource relative to .class file + URL url = getClass().getResource(name); + + // resource relative to classloader root + if (url == null) { + url = getClass().getClassLoader().getResource(name); + } + + // or URL from web + if (url == null) { + url = new URL(name); + } + + URLConnection site = url.openConnection(); + + // in order to set User-Agent, replace above line with these two + // HttpURLConnection site = (HttpURLConnection) url.openConnection(); + // site.addRequestProperty("User-Agent", "Mozilla/4.76"); + + InputStream is = site.getInputStream(); + scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + catch (IOException ioe) { + throw new IllegalArgumentException("Could not open " + name, ioe); + } + } + + /** + * Initializes an input stream from a given {@link Scanner} source; use with + * {@code new Scanner(String)} to read from a string. + *
+ * Note that this does not create a defensive copy, so the + * scanner will be mutated as you read on. + * + * @param scanner the scanner + * @throws IllegalArgumentException if {@code scanner} is {@code null} + */ + public In(Scanner scanner) { + if (scanner == null) throw new IllegalArgumentException("scanner argument is null"); + this.scanner = scanner; + } + + /** + * Returns true if this input stream exists. + * + * @return {@code true} if this input stream exists; {@code false} otherwise + */ + public boolean exists() { + return scanner != null; + } + + //// begin: section (2 of 2) of code duplicated from In to StdIn, + //// with all methods changed from "public" to "public static". + + /** + * Returns true if input stream is empty (except possibly whitespace). + * Use this to know whether the next call to {@link #readString()}, + * {@link #readDouble()}, etc will succeed. + * + * @return {@code true} if this input stream is empty (except possibly whitespace); + * {@code false} otherwise + */ + public boolean isEmpty() { + return !scanner.hasNext(); + } + + /** + * Returns true if this input stream has a next line. + * Use this method to know whether the + * next call to {@link #readLine()} will succeed. + * This method is functionally equivalent to {@link #hasNextChar()}. + * + * @return {@code true} if this input stream has more input (including whitespace); + * {@code false} otherwise + */ + public boolean hasNextLine() { + return scanner.hasNextLine(); + } + + /** + * Returns true if this input stream has more input (including whitespace). + * Use this method to know whether the next call to {@link #readChar()} will succeed. + * This method is functionally equivalent to {@link #hasNextLine()}. + * + * @return {@code true} if this input stream has more input (including whitespace); + * {@code false} otherwise + */ + public boolean hasNextChar() { + scanner.useDelimiter(EMPTY_PATTERN); + boolean result = scanner.hasNext(); + scanner.useDelimiter(WHITESPACE_PATTERN); + return result; + } + + + /** + * Reads and returns the next line in this input stream. + * + * @return the next line in this input stream; {@code null} if no such line + */ + public String readLine() { + String line; + try { + line = scanner.nextLine(); + } + catch (NoSuchElementException e) { + line = null; + } + return line; + } + + /** + * Reads and returns the next character in this input stream. + * + * @return the next {@code char} in this input stream + * @throws NoSuchElementException if the input stream is empty + */ + public char readChar() { + scanner.useDelimiter(EMPTY_PATTERN); + try { + String ch = scanner.next(); + assert ch.length() == 1 : "Internal (Std)In.readChar() error!" + + " Please contact the authors."; + scanner.useDelimiter(WHITESPACE_PATTERN); + return ch.charAt(0); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'char' value from the input stream, " + + "but no more tokens are available"); + } + } + + + /** + * Reads and returns the remainder of this input stream, as a string. + * + * @return the remainder of this input stream, as a string + */ + public String readAll() { + if (!scanner.hasNextLine()) + return ""; + + String result = scanner.useDelimiter(EVERYTHING_PATTERN).next(); + // not that important to reset delimeter, since now scanner is empty + scanner.useDelimiter(WHITESPACE_PATTERN); // but let's do it anyway + return result; + } + + + /** + * Reads the next token from this input stream and returns it as a {@code String}. + * + * @return the next {@code String} in this input stream + * @throws NoSuchElementException if the input stream is empty + */ + public String readString() { + try { + return scanner.next(); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'String' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code int}, + * and returns the {@code int}. + * + * @return the next {@code int} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as an {@code int} + */ + public int readInt() { + try { + return scanner.nextInt(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read an 'int' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read an 'int' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code double}, + * and returns the {@code double}. + * + * @return the next {@code double} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code double} + */ + public double readDouble() { + try { + return scanner.nextDouble(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'double' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'double' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code float}, + * and returns the {@code float}. + * + * @return the next {@code float} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code float} + */ + public float readFloat() { + try { + return scanner.nextFloat(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'float' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'float' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code long}, + * and returns the {@code long}. + * + * @return the next {@code long} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code long} + */ + public long readLong() { + try { + return scanner.nextLong(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'long' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'long' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code short}, + * and returns the {@code short}. + * + * @return the next {@code short} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code short} + */ + public short readShort() { + try { + return scanner.nextShort(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'short' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'short' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code byte}, + * and returns the {@code byte}. + *
+ * To read binary data, use {@link BinaryIn}.
+ *
+ * @return the next {@code byte} in this input stream
+ * @throws NoSuchElementException if the input stream is empty
+ * @throws InputMismatchException if the next token cannot be parsed as a {@code byte}
+ */
+ public byte readByte() {
+ try {
+ return scanner.nextByte();
+ }
+ catch (InputMismatchException e) {
+ String token = scanner.next();
+ throw new InputMismatchException("attempts to read a 'byte' value from the input stream, "
+ + "but the next token is \"" + token + "\"");
+ }
+ catch (NoSuchElementException e) {
+ throw new NoSuchElementException("attemps to read a 'byte' value from the input stream, "
+ + "but no more tokens are available");
+ }
+ }
+
+ /**
+ * Reads the next token from this input stream, parses it as a {@code boolean}
+ * (interpreting either {@code "true"} or {@code "1"} as {@code true},
+ * and either {@code "false"} or {@code "0"} as {@code false}).
+ *
+ * @return the next {@code boolean} in this input stream
+ * @throws NoSuchElementException if the input stream is empty
+ * @throws InputMismatchException if the next token cannot be parsed as a {@code boolean}
+ */
+ public boolean readBoolean() {
+ try {
+ String token = readString();
+ if ("true".equalsIgnoreCase(token)) return true;
+ if ("false".equalsIgnoreCase(token)) return false;
+ if ("1".equals(token)) return true;
+ if ("0".equals(token)) return false;
+ throw new InputMismatchException("attempts to read a 'boolean' value from the input stream, "
+ + "but the next token is \"" + token + "\"");
+ }
+ catch (NoSuchElementException e) {
+ throw new NoSuchElementException("attempts to read a 'boolean' value from the input stream, "
+ + "but no more tokens are available");
+ }
+ }
+
+ /**
+ * Reads all remaining tokens from this input stream and returns them as
+ * an array of strings.
+ *
+ * @return all remaining tokens in this input stream, as an array of strings
+ */
+ public String[] readAllStrings() {
+ // we could use readAll.trim().split(), but that's not consistent
+ // since trim() uses characters 0x00..0x20 as whitespace
+ String[] tokens = WHITESPACE_PATTERN.split(readAll());
+ if (tokens.length == 0 || tokens[0].length() > 0)
+ return tokens;
+ String[] decapitokens = new String[tokens.length-1];
+ for (int i = 0; i < tokens.length-1; i++)
+ decapitokens[i] = tokens[i+1];
+ return decapitokens;
+ }
+
+ /**
+ * Reads all remaining lines from this input stream and returns them as
+ * an array of strings.
+ *
+ * @return all remaining lines in this input stream, as an array of strings
+ */
+ public String[] readAllLines() {
+ ArrayList
+ * For additional documentation, see
+ * Section 3.1 of
+ * Computer Science: An Interdisciplinary Approach
+ * by Robert Sedgewick and Kevin Wayne.
+ *
+ * @author Robert Sedgewick
+ * @author Kevin Wayne
+ */
+public class Out {
+
+ // force Unicode UTF-8 encoding; otherwise it's system dependent
+ private static final String CHARSET_NAME = "UTF-8";
+
+ // assume language = English, country = US for consistency with In
+ private static final Locale LOCALE = Locale.US;
+
+ private PrintWriter out;
+
+ /**
+ * Initializes an output stream from a {@link OutputStream}.
+ *
+ * @param os the {@code OutputStream}
+ */
+ public Out(OutputStream os) {
+ try {
+ OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET_NAME);
+ out = new PrintWriter(osw, true);
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Initializes an output stream from standard output.
+ */
+ public Out() {
+ this(System.out);
+ }
+
+ /**
+ * Initializes an output stream from a socket.
+ *
+ * @param socket the socket
+ */
+ public Out(Socket socket) {
+ try {
+ OutputStream os = socket.getOutputStream();
+ OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET_NAME);
+ out = new PrintWriter(osw, true);
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Initializes an output stream from a file.
+ *
+ * @param filename the name of the file
+ */
+ public Out(String filename) {
+ try {
+ OutputStream os = new FileOutputStream(filename);
+ OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET_NAME);
+ out = new PrintWriter(osw, true);
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Closes the output stream.
+ */
+ public void close() {
+ out.close();
+ }
+
+ /**
+ * Terminates the current line by printing the line-separator string.
+ */
+ public void println() {
+ out.println();
+ }
+
+ /**
+ * Prints an object to this output stream and then terminates the line.
+ *
+ * @param x the object to print
+ */
+ public void println(Object x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints a boolean to this output stream and then terminates the line.
+ *
+ * @param x the boolean to print
+ */
+ public void println(boolean x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints a character to this output stream and then terminates the line.
+ *
+ * @param x the character to print
+ */
+ public void println(char x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints a double to this output stream and then terminates the line.
+ *
+ * @param x the double to print
+ */
+ public void println(double x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints a float to this output stream and then terminates the line.
+ *
+ * @param x the float to print
+ */
+ public void println(float x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints an integer to this output stream and then terminates the line.
+ *
+ * @param x the integer to print
+ */
+ public void println(int x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints a long to this output stream and then terminates the line.
+ *
+ * @param x the long to print
+ */
+ public void println(long x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints a byte to this output stream and then terminates the line.
+ *
+ * To write binary data, see {@link BinaryOut}.
+ *
+ * @param x the byte to print
+ */
+ public void println(byte x) {
+ out.println(x);
+ }
+
+
+
+ /**
+ * Flushes this output stream.
+ */
+ public void print() {
+ out.flush();
+ }
+
+ /**
+ * Prints an object to this output stream and flushes this output stream.
+ *
+ * @param x the object to print
+ */
+ public void print(Object x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a boolean to this output stream and flushes this output stream.
+ *
+ * @param x the boolean to print
+ */
+ public void print(boolean x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a character to this output stream and flushes this output stream.
+ *
+ * @param x the character to print
+ */
+ public void print(char x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a double to this output stream and flushes this output stream.
+ *
+ * @param x the double to print
+ */
+ public void print(double x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a float to this output stream and flushes this output stream.
+ *
+ * @param x the float to print
+ */
+ public void print(float x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints an integer to this output stream and flushes this output stream.
+ *
+ * @param x the integer to print
+ */
+ public void print(int x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a long integer to this output stream and flushes this output stream.
+ *
+ * @param x the long integer to print
+ */
+ public void print(long x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a byte to this output stream and flushes this output stream.
+ *
+ * @param x the byte to print
+ */
+ public void print(byte x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a formatted string to this output stream, using the specified format
+ * string and arguments, and then flushes this output stream.
+ *
+ * @param format the format string
+ * @param args the arguments accompanying the format string
+ */
+ public void printf(String format, Object... args) {
+ out.printf(LOCALE, format, args);
+ out.flush();
+ }
+
+ /**
+ * Prints a formatted string to this output stream, using the specified
+ * locale, format string, and arguments, and then flushes this output stream.
+ *
+ * @param locale the locale
+ * @param format the format string
+ * @param args the arguments accompanying the format string
+ */
+ public void printf(Locale locale, String format, Object... args) {
+ out.printf(locale, format, args);
+ out.flush();
+ }
+
+
+ /**
+ * A test client.
+ *
+ * @param args the command-line arguments
+ */
+ public static void main(String[] args) {
+ Out out;
+
+ // write to stdout
+ out = new Out();
+ out.println("Test 1");
+ out.close();
+
+ // write to a file
+ out = new Out("test.txt");
+ out.println("Test 2");
+ out.close();
+ }
+
+}
+
+/******************************************************************************
+ * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
+ *
+ * This file is part of algs4.jar, which accompanies the textbook
+ *
+ * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
+ * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
+ * http://algs4.cs.princeton.edu
+ *
+ *
+ * algs4.jar is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * algs4.jar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with algs4.jar. If not, see http://www.gnu.org/licenses.
+ ******************************************************************************/
diff --git a/src/algs4/util/StdIn.java b/src/algs4/util/StdIn.java
new file mode 100644
index 0000000..1123102
--- /dev/null
+++ b/src/algs4/util/StdIn.java
@@ -0,0 +1,696 @@
+/******************************************************************************
+ * Compilation: javac StdIn.java
+ * Execution: java StdIn (interactive test of basic functionality)
+ * Dependencies: none
+ *
+ * Reads in data of various types from standard input.
+ *
+ ******************************************************************************/
+
+package algs4.util;
+
+import java.util.ArrayList;
+import java.util.InputMismatchException;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+import java.util.Scanner;
+import java.util.regex.Pattern;
+
+/**
+ * The {@code StdIn} class provides static methods for reading strings
+ * and numbers from standard input.
+ * These functions fall into one of four categories:
+ *
+ * Generally, it is best not to mix functions from the different
+ * categories in the same program.
+ *
+ * Getting started.
+ * To use this class, you must have {@code StdIn.class} in your
+ * Java classpath. If you used our autoinstaller, you should be all set.
+ * Otherwise, either download
+ * stdlib.jar
+ * and add to your Java classpath or download
+ * StdIn.java
+ * and put a copy in your working directory.
+ *
+ * Reading tokens from standard input and converting to numbers and strings.
+ * You can use the following methods to read numbers, strings, and booleans
+ * from standard input one at a time:
+ *
+ * The first method returns true if standard input has no more tokens.
+ * Each other method skips over any input that is whitespace. Then, it reads
+ * the next token and attempts to convert it into a value of the specified
+ * type. If it succeeds, it returns that value; otherwise, it
+ * throws an {@link InputMismatchException}.
+ *
+ * Whitespace includes spaces, tabs, and newlines; the full definition
+ * is inherited from {@link Character#isWhitespace(char)}.
+ * A token is a maximal sequence of non-whitespace characters.
+ * The precise rules for describing which tokens can be converted to
+ * integers and floating-point numbers are inherited from
+ * Scanner,
+ * using the locale {@link Locale#US}; the rules
+ * for floating-point numbers are slightly different
+ * from those in {@link Double#valueOf(String)},
+ * but unlikely to be of concern to most programmers.
+ *
+ * As an example, the following code fragment reads integers from standard input,
+ * one at a time, and prints them one per line.
+ *
+ * Reading characters from standard input.
+ * You can use the following two methods to read characters from standard input one at a time:
+ *
+ * The first method returns true if standard input has more input (including whitespace).
+ * The second method reads and returns the next character of input on standard
+ * input (possibly a whitespace character).
+ *
+ * As an example, the following code fragment reads characters from standard input,
+ * one character at a time, and prints it to standard output.
+ *
+ * Reading lines from standard input.
+ * You can use the following two methods to read lines from standard input:
+ *
+ * The first method returns true if standard input has more input (including whitespace).
+ * The second method reads and returns the remaining portion of
+ * the next line of input on standard input (possibly whitespace),
+ * discarding the trailing line separator.
+ *
+ * A line separator is defined to be one of the following strings:
+ * {@code \n} (Linux), {@code \r} (old Macintosh),
+ * {@code \r\n} (Windows),
+ * {@code \}{@code u2028}, {@code \}{@code u2029}, or {@code \}{@code u0085}.
+ *
+ * As an example, the following code fragment reads text from standard input,
+ * one line at a time, and prints it to standard output.
+ *
+ * Reading a sequence of values of the same type from standard input.
+ * You can use the following methods to read a sequence numbers, strings,
+ * or booleans (all of the same type) from standard input:
+ *
+ * The first three methods read of all of remaining token on standard input
+ * and converts the tokens to values of
+ * the specified type, as in the corresponding
+ * {@code readDouble}, {@code readInt}, and {@code readString()} methods.
+ * The {@code readAllLines()} method reads all remaining lines on standard
+ * input and returns them as an array of strings.
+ * The {@code readAll()} method reads all remaining input on standard
+ * input and returns it as a string.
+ *
+ * As an example, the following code fragment reads all of the remaining
+ * tokens from standard input and returns them as an array of strings.
+ *
+ * Differences with Scanner.
+ * {@code StdIn} and {@link Scanner} are both designed to parse
+ * tokens and convert them to primitive types and strings.
+ * The main differences are summarized below:
+ *
+ * Historical note: {@code StdIn} preceded {@code Scanner}; when
+ * {@code Scanner} was introduced, this class was re-implemented to use {@code Scanner}.
+ *
+ * Using standard input.
+ * Standard input is a fundamental operating system abstraction on Mac OS X,
+ * Windows, and Linux.
+ * The methods in {@code StdIn} are blocking, which means that they
+ * will wait until you enter input on standard input.
+ * If your program has a loop that repeats until standard input is empty,
+ * you must signal that the input is finished.
+ * To do so, depending on your operating system and IDE,
+ * use either {@code
+ * Known bugs.
+ * Java's UTF-8 encoding does not recognize the optional
+ * byte-order mask.
+ * If the input begins with the optional byte-order mask, {@code StdIn}
+ * will have an extra character {@code \}{@code uFEFF} at the beginning.
+ *
+ * Reference.
+ * For additional documentation,
+ * see Section 1.5 of
+ * Computer Science: An Interdisciplinary Approach
+ * by Robert Sedgewick and Kevin Wayne.
+ *
+ * @author Robert Sedgewick
+ * @author Kevin Wayne
+ * @author David Pritchard
+ */
+public final class StdIn {
+
+ /*** begin: section (1 of 2) of code duplicated from In to StdIn. */
+
+ // assume Unicode UTF-8 encoding
+ private static final String CHARSET_NAME = "UTF-8";
+
+ // assume language = English, country = US for consistency with System.out.
+ private static final Locale LOCALE = Locale.US;
+
+ // the default token separator; we maintain the invariant that this value
+ // is held by the scanner's delimiter between calls
+ private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\p{javaWhitespace}+");
+
+ // makes whitespace significant
+ private static final Pattern EMPTY_PATTERN = Pattern.compile("");
+
+ // used to read the entire input
+ private static final Pattern EVERYTHING_PATTERN = Pattern.compile("\\A");
+
+ /*** end: section (1 of 2) of code duplicated from In to StdIn. */
+
+ private static Scanner scanner;
+
+ // it doesn't make sense to instantiate this class
+ private StdIn() { }
+
+ //// begin: section (2 of 2) of code duplicated from In to StdIn,
+ //// with all methods changed from "public" to "public static"
+
+ /**
+ * Returns true if standard input is empty (except possibly for whitespace).
+ * Use this method to know whether the next call to {@link #readString()},
+ * {@link #readDouble()}, etc will succeed.
+ *
+ * @return {@code true} if standard input is empty (except possibly
+ * for whitespace); {@code false} otherwise
+ */
+ public static boolean isEmpty() {
+ return !scanner.hasNext();
+ }
+
+ /**
+ * Returns true if standard input has a next line.
+ * Use this method to know whether the
+ * next call to {@link #readLine()} will succeed.
+ * This method is functionally equivalent to {@link #hasNextChar()}.
+ *
+ * @return {@code true} if standard input has more input (including whitespace);
+ * {@code false} otherwise
+ */
+ public static boolean hasNextLine() {
+ return scanner.hasNextLine();
+ }
+
+ /**
+ * Returns true if standard input has more input (including whitespace).
+ * Use this method to know whether the next call to {@link #readChar()} will succeed.
+ * This method is functionally equivalent to {@link #hasNextLine()}.
+ *
+ * @return {@code true} if standard input has more input (including whitespace);
+ * {@code false} otherwise
+ */
+ public static boolean hasNextChar() {
+ scanner.useDelimiter(EMPTY_PATTERN);
+ boolean result = scanner.hasNext();
+ scanner.useDelimiter(WHITESPACE_PATTERN);
+ return result;
+ }
+
+
+ /**
+ * Reads and returns the next line, excluding the line separator if present.
+ *
+ * @return the next line, excluding the line separator if present;
+ * {@code null} if no such line
+ */
+ public static String readLine() {
+ String line;
+ try {
+ line = scanner.nextLine();
+ }
+ catch (NoSuchElementException e) {
+ line = null;
+ }
+ return line;
+ }
+
+ /**
+ * Reads and returns the next character.
+ *
+ * @return the next {@code char}
+ * @throws NoSuchElementException if standard input is empty
+ */
+ public static char readChar() {
+ try {
+ scanner.useDelimiter(EMPTY_PATTERN);
+ String ch = scanner.next();
+ assert ch.length() == 1 : "Internal (Std)In.readChar() error!"
+ + " Please contact the authors.";
+ scanner.useDelimiter(WHITESPACE_PATTERN);
+ return ch.charAt(0);
+ }
+ catch (NoSuchElementException e) {
+ throw new NoSuchElementException("attempts to read a 'char' value from standard input, "
+ + "but no more tokens are available");
+ }
+ }
+
+
+ /**
+ * Reads and returns the remainder of the input, as a string.
+ *
+ * @return the remainder of the input, as a string
+ * @throws NoSuchElementException if standard input is empty
+ */
+ public static String readAll() {
+ if (!scanner.hasNextLine())
+ return "";
+
+ String result = scanner.useDelimiter(EVERYTHING_PATTERN).next();
+ // not that important to reset delimeter, since now scanner is empty
+ scanner.useDelimiter(WHITESPACE_PATTERN); // but let's do it anyway
+ return result;
+ }
+
+
+ /**
+ * Reads the next token from standard input and returns it as a {@code String}.
+ *
+ * @return the next {@code String}
+ * @throws NoSuchElementException if standard input is empty
+ */
+ public static String readString() {
+ try {
+ return scanner.next();
+ }
+ catch (NoSuchElementException e) {
+ throw new NoSuchElementException("attempts to read a 'String' value from standard input, "
+ + "but no more tokens are available");
+ }
+ }
+
+ /**
+ * Reads the next token from standard input, parses it as an integer, and returns the integer.
+ *
+ * @return the next integer on standard input
+ * @throws NoSuchElementException if standard input is empty
+ * @throws InputMismatchException if the next token cannot be parsed as an {@code int}
+ */
+ public static int readInt() {
+ try {
+ return scanner.nextInt();
+ }
+ catch (InputMismatchException e) {
+ String token = scanner.next();
+ throw new InputMismatchException("attempts to read an 'int' value from standard input, "
+ + "but the next token is \"" + token + "\"");
+ }
+ catch (NoSuchElementException e) {
+ throw new NoSuchElementException("attemps to read an 'int' value from standard input, "
+ + "but no more tokens are available");
+ }
+
+ }
+
+ /**
+ * Reads the next token from standard input, parses it as a double, and returns the double.
+ *
+ * @return the next double on standard input
+ * @throws NoSuchElementException if standard input is empty
+ * @throws InputMismatchException if the next token cannot be parsed as a {@code double}
+ */
+ public static double readDouble() {
+ try {
+ return scanner.nextDouble();
+ }
+ catch (InputMismatchException e) {
+ String token = scanner.next();
+ throw new InputMismatchException("attempts to read a 'double' value from standard input, "
+ + "but the next token is \"" + token + "\"");
+ }
+ catch (NoSuchElementException e) {
+ throw new NoSuchElementException("attempts to read a 'double' value from standard input, "
+ + "but no more tokens are available");
+ }
+ }
+
+ /**
+ * Reads the next token from standard input, parses it as a float, and returns the float.
+ *
+ * @return the next float on standard input
+ * @throws NoSuchElementException if standard input is empty
+ * @throws InputMismatchException if the next token cannot be parsed as a {@code float}
+ */
+ public static float readFloat() {
+ try {
+ return scanner.nextFloat();
+ }
+ catch (InputMismatchException e) {
+ String token = scanner.next();
+ throw new InputMismatchException("attempts to read a 'float' value from standard input, "
+ + "but the next token is \"" + token + "\"");
+ }
+ catch (NoSuchElementException e) {
+ throw new NoSuchElementException("attempts to read a 'float' value from standard input, "
+ + "but there no more tokens are available");
+ }
+ }
+
+ /**
+ * Reads the next token from standard input, parses it as a long integer, and returns the long integer.
+ *
+ * @return the next long integer on standard input
+ * @throws NoSuchElementException if standard input is empty
+ * @throws InputMismatchException if the next token cannot be parsed as a {@code long}
+ */
+ public static long readLong() {
+ try {
+ return scanner.nextLong();
+ }
+ catch (InputMismatchException e) {
+ String token = scanner.next();
+ throw new InputMismatchException("attempts to read a 'long' value from standard input, "
+ + "but the next token is \"" + token + "\"");
+ }
+ catch (NoSuchElementException e) {
+ throw new NoSuchElementException("attempts to read a 'long' value from standard input, "
+ + "but no more tokens are available");
+ }
+ }
+
+ /**
+ * Reads the next token from standard input, parses it as a short integer, and returns the short integer.
+ *
+ * @return the next short integer on standard input
+ * @throws NoSuchElementException if standard input is empty
+ * @throws InputMismatchException if the next token cannot be parsed as a {@code short}
+ */
+ public static short readShort() {
+ try {
+ return scanner.nextShort();
+ }
+ catch (InputMismatchException e) {
+ String token = scanner.next();
+ throw new InputMismatchException("attempts to read a 'short' value from standard input, "
+ + "but the next token is \"" + token + "\"");
+ }
+ catch (NoSuchElementException e) {
+ throw new NoSuchElementException("attempts to read a 'short' value from standard input, "
+ + "but no more tokens are available");
+ }
+ }
+
+ /**
+ * Reads the next token from standard input, parses it as a byte, and returns the byte.
+ *
+ * @return the next byte on standard input
+ * @throws NoSuchElementException if standard input is empty
+ * @throws InputMismatchException if the next token cannot be parsed as a {@code byte}
+ */
+ public static byte readByte() {
+ try {
+ return scanner.nextByte();
+ }
+ catch (InputMismatchException e) {
+ String token = scanner.next();
+ throw new InputMismatchException("attempts to read a 'byte' value from standard input, "
+ + "but the next token is \"" + token + "\"");
+ }
+ catch (NoSuchElementException e) {
+ throw new NoSuchElementException("attempts to read a 'byte' value from standard input, "
+ + "but no more tokens are available");
+ }
+ }
+
+ /**
+ * Reads the next token from standard input, parses it as a boolean,
+ * and returns the boolean.
+ *
+ * @return the next boolean on standard input
+ * @throws NoSuchElementException if standard input is empty
+ * @throws InputMismatchException if the next token cannot be parsed as a {@code boolean}:
+ * {@code true} or {@code 1} for true, and {@code false} or {@code 0} for false,
+ * ignoring case
+ */
+ public static boolean readBoolean() {
+ try {
+ String token = readString();
+ if ("true".equalsIgnoreCase(token)) return true;
+ if ("false".equalsIgnoreCase(token)) return false;
+ if ("1".equals(token)) return true;
+ if ("0".equals(token)) return false;
+ throw new InputMismatchException("attempts to read a 'boolean' value from standard input, "
+ + "but the next token is \"" + token + "\"");
+ }
+ catch (NoSuchElementException e) {
+ throw new NoSuchElementException("attempts to read a 'boolean' value from standard input, "
+ + "but no more tokens are available");
+ }
+
+ }
+
+ /**
+ * Reads all remaining tokens from standard input and returns them as an array of strings.
+ *
+ * @return all remaining tokens on standard input, as an array of strings
+ */
+ public static String[] readAllStrings() {
+ // we could use readAll.trim().split(), but that's not consistent
+ // because trim() uses characters 0x00..0x20 as whitespace
+ String[] tokens = WHITESPACE_PATTERN.split(readAll());
+ if (tokens.length == 0 || tokens[0].length() > 0)
+ return tokens;
+
+ // don't include first token if it is leading whitespace
+ String[] decapitokens = new String[tokens.length-1];
+ for (int i = 0; i < tokens.length - 1; i++)
+ decapitokens[i] = tokens[i+1];
+ return decapitokens;
+ }
+
+ /**
+ * Reads all remaining lines from standard input and returns them as an array of strings.
+ * @return all remaining lines on standard input, as an array of strings
+ */
+ public static String[] readAllLines() {
+ ArrayList
+ * Getting started.
+ * To use this class, you must have {@code StdOut.class} in your
+ * Java classpath. If you used our autoinstaller, you should be all set.
+ * Otherwise, either download
+ * stdlib.jar
+ * and add to your Java classpath or download
+ * StdOut.java
+ * and put a copy in your working directory.
+ *
+ * Here is an example program that uses {@code StdOut}:
+ *
+ * Differences with System.out.
+ * The behavior of {@code StdOut} is similar to that of {@link System#out},
+ * but there are a few technical differences:
+ *
+ * Reference.
+ * For additional documentation,
+ * see Section 1.5 of
+ * Computer Science: An Interdisciplinary Approach
+ * by Robert Sedgewick and Kevin Wayne.
+ *
+ * @author Robert Sedgewick
+ * @author Kevin Wayne
+ */
+public final class StdOut {
+
+ // force Unicode UTF-8 encoding; otherwise it's system dependent
+ private static final String CHARSET_NAME = "UTF-8";
+
+ // assume language = English, country = US for consistency with StdIn
+ private static final Locale LOCALE = Locale.US;
+
+ // send output here
+ private static PrintWriter out;
+
+ // this is called before invoking any methods
+ static {
+ try {
+ out = new PrintWriter(new OutputStreamWriter(System.out, CHARSET_NAME), true);
+ }
+ catch (UnsupportedEncodingException e) {
+ System.out.println(e);
+ }
+ }
+
+ // don't instantiate
+ private StdOut() { }
+
+ /**
+ * Terminates the current line by printing the line-separator string.
+ */
+ public static void println() {
+ out.println();
+ }
+
+ /**
+ * Prints an object to this output stream and then terminates the line.
+ *
+ * @param x the object to print
+ */
+ public static void println(Object x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints a boolean to standard output and then terminates the line.
+ *
+ * @param x the boolean to print
+ */
+ public static void println(boolean x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints a character to standard output and then terminates the line.
+ *
+ * @param x the character to print
+ */
+ public static void println(char x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints a double to standard output and then terminates the line.
+ *
+ * @param x the double to print
+ */
+ public static void println(double x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints an integer to standard output and then terminates the line.
+ *
+ * @param x the integer to print
+ */
+ public static void println(float x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints an integer to standard output and then terminates the line.
+ *
+ * @param x the integer to print
+ */
+ public static void println(int x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints a long to standard output and then terminates the line.
+ *
+ * @param x the long to print
+ */
+ public static void println(long x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints a short integer to standard output and then terminates the line.
+ *
+ * @param x the short to print
+ */
+ public static void println(short x) {
+ out.println(x);
+ }
+
+ /**
+ * Prints a byte to standard output and then terminates the line.
+ *
+ * To write binary data, see {@link BinaryStdOut}.
+ *
+ * @param x the byte to print
+ */
+ public static void println(byte x) {
+ out.println(x);
+ }
+
+ /**
+ * Flushes standard output.
+ */
+ public static void print() {
+ out.flush();
+ }
+
+ /**
+ * Prints an object to standard output and flushes standard output.
+ *
+ * @param x the object to print
+ */
+ public static void print(Object x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a boolean to standard output and flushes standard output.
+ *
+ * @param x the boolean to print
+ */
+ public static void print(boolean x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a character to standard output and flushes standard output.
+ *
+ * @param x the character to print
+ */
+ public static void print(char x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a double to standard output and flushes standard output.
+ *
+ * @param x the double to print
+ */
+ public static void print(double x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a float to standard output and flushes standard output.
+ *
+ * @param x the float to print
+ */
+ public static void print(float x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints an integer to standard output and flushes standard output.
+ *
+ * @param x the integer to print
+ */
+ public static void print(int x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a long integer to standard output and flushes standard output.
+ *
+ * @param x the long integer to print
+ */
+ public static void print(long x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a short integer to standard output and flushes standard output.
+ *
+ * @param x the short integer to print
+ */
+ public static void print(short x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a byte to standard output and flushes standard output.
+ *
+ * @param x the byte to print
+ */
+ public static void print(byte x) {
+ out.print(x);
+ out.flush();
+ }
+
+ /**
+ * Prints a formatted string to standard output, using the specified format
+ * string and arguments, and then flushes standard output.
+ *
+ *
+ * @param format the format string
+ * @param args the arguments accompanying the format string
+ */
+ public static void printf(String format, Object... args) {
+ out.printf(LOCALE, format, args);
+ out.flush();
+ }
+
+ /**
+ * Prints a formatted string to standard output, using the locale and
+ * the specified format string and arguments; then flushes standard output.
+ *
+ * @param locale the locale
+ * @param format the format string
+ * @param args the arguments accompanying the format string
+ */
+ public static void printf(Locale locale, String format, Object... args) {
+ out.printf(locale, format, args);
+ out.flush();
+ }
+
+ /**
+ * Unit tests some of the methods in {@code StdOut}.
+ *
+ * @param args the command-line arguments
+ */
+ public static void main(String[] args) {
+
+ // write to stdout
+ StdOut.println("Test");
+ StdOut.println(17);
+ StdOut.println(true);
+ StdOut.printf("%.6f\n", 1.0/7.0);
+ }
+
+}
+
+/******************************************************************************
+ * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
+ *
+ * This file is part of algs4.jar, which accompanies the textbook
+ *
+ * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
+ * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
+ * http://algs4.cs.princeton.edu
+ *
+ *
+ * algs4.jar is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * algs4.jar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with algs4.jar. If not, see http://www.gnu.org/licenses.
+ ******************************************************************************/
diff --git a/src/algs4/util/StdRandom.java b/src/algs4/util/StdRandom.java
new file mode 100644
index 0000000..ac5c56c
--- /dev/null
+++ b/src/algs4/util/StdRandom.java
@@ -0,0 +1,674 @@
+/******************************************************************************
+ * Compilation: javac StdRandom.java
+ * Execution: java StdRandom
+ * Dependencies: StdOut.java
+ *
+ * A library of static methods to generate pseudo-random numbers from
+ * different distributions (bernoulli, uniform, gaussian, discrete,
+ * and exponential). Also includes a method for shuffling an array.
+ *
+ *
+ * % java StdRandom 5
+ * seed = 1316600602069
+ * 59 16.81826 true 8.83954 0
+ * 32 91.32098 true 9.11026 0
+ * 35 10.11874 true 8.95396 3
+ * 92 32.88401 true 8.87089 0
+ * 72 92.55791 true 9.46241 0
+ *
+ * % java StdRandom 5
+ * seed = 1316600616575
+ * 96 60.17070 true 8.72821 0
+ * 79 32.01607 true 8.58159 0
+ * 81 59.49065 true 9.10423 1
+ * 96 51.65818 true 9.02102 0
+ * 99 17.55771 true 8.99762 0
+ *
+ * % java StdRandom 5 1316600616575
+ * seed = 1316600616575
+ * 96 60.17070 true 8.72821 0
+ * 79 32.01607 true 8.58159 0
+ * 81 59.49065 true 9.10423 1
+ * 96 51.65818 true 9.02102 0
+ * 99 17.55771 true 8.99762 0
+ *
+ *
+ * Remark
+ * ------
+ * - Relies on randomness of nextDouble() method in java.util.Random
+ * to generate pseudo-random numbers in [0, 1).
+ *
+ * - This library allows you to set and get the pseudo-random number seed.
+ *
+ * - See http://www.honeylocust.com/RngPack/ for an industrial
+ * strength random number generator in Java.
+ *
+ ******************************************************************************/
+
+package algs4.util;
+
+import java.util.Random;
+
+/**
+ * The {@code StdRandom} class provides static methods for generating
+ * random number from various discrete and continuous distributions,
+ * including uniform, Bernoulli, geometric, Gaussian, exponential, Pareto,
+ * Poisson, and Cauchy. It also provides method for shuffling an
+ * array or subarray and generating random permutations.
+ *
+ * By convention, all intervals are half open. For example,
+ *
+ * For additional documentation,
+ * see Section 2.2 of
+ * Computer Science: An Interdisciplinary Approach
+ * by Robert Sedgewick and Kevin Wayne.
+ *
+ * @author Robert Sedgewick
+ * @author Kevin Wayne
+ */
+public final class StdRandom {
+
+ private static Random random; // pseudo-random number generator
+ private static long seed; // pseudo-random number generator seed
+
+ // static initializer
+ static {
+ // this is how the seed was set in Java 1.4
+ seed = System.currentTimeMillis();
+ random = new Random(seed);
+ }
+
+ // don't instantiate
+ private StdRandom() { }
+
+ /**
+ * Sets the seed of the pseudo-random number generator.
+ * This method enables you to produce the same sequence of "random"
+ * number for each execution of the program.
+ * Ordinarily, you should call this method at most once per program.
+ *
+ * @param s the seed
+ */
+ public static void setSeed(long s) {
+ seed = s;
+ random = new Random(seed);
+ }
+
+ /**
+ * Returns the seed of the pseudo-random number generator.
+ *
+ * @return the seed
+ */
+ public static long getSeed() {
+ return seed;
+ }
+
+ /**
+ * Returns a random real number uniformly in [0, 1).
+ *
+ * @return a random real number uniformly in [0, 1)
+ */
+ public static double uniform() {
+ return random.nextDouble();
+ }
+
+ /**
+ * Returns a random integer uniformly in [0, n).
+ *
+ * @param n number of possible integers
+ * @return a random integer uniformly between 0 (inclusive) and {@code n} (exclusive)
+ * @throws IllegalArgumentException if {@code n <= 0}
+ */
+ public static int uniform(int n) {
+ if (n <= 0) throw new IllegalArgumentException("argument must be positive: " + n);
+ return random.nextInt(n);
+ }
+
+
+ /**
+ * Returns a random long integer uniformly in [0, n).
+ *
+ * @param n number of possible {@code long} integers
+ * @return a random long integer uniformly between 0 (inclusive) and {@code n} (exclusive)
+ * @throws IllegalArgumentException if {@code n <= 0}
+ */
+ public static long uniform(long n) {
+ if (n <= 0L) throw new IllegalArgumentException("argument must be positive: " + n);
+
+ // https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#longs-long-long-long-
+ long r = random.nextLong();
+ long m = n - 1;
+
+ // power of two
+ if ((n & m) == 0L) {
+ return r & m;
+ }
+
+ // reject over-represented candidates
+ long u = r >>> 1;
+ while (u + m - (r = u % n) < 0L) {
+ u = random.nextLong() >>> 1;
+ }
+ return r;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // STATIC METHODS BELOW RELY ON JAVA.UTIL.RANDOM ONLY INDIRECTLY VIA
+ // THE STATIC METHODS ABOVE.
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Returns a random real number uniformly in [0, 1).
+ *
+ * @return a random real number uniformly in [0, 1)
+ * @deprecated Replaced by {@link #uniform()}.
+ */
+ @Deprecated
+ public static double random() {
+ return uniform();
+ }
+
+ /**
+ * Returns a random integer uniformly in [a, b).
+ *
+ * @param a the left endpoint
+ * @param b the right endpoint
+ * @return a random integer uniformly in [a, b)
+ * @throws IllegalArgumentException if {@code b <= a}
+ * @throws IllegalArgumentException if {@code b - a >= Integer.MAX_VALUE}
+ */
+ public static int uniform(int a, int b) {
+ if ((b <= a) || ((long) b - a >= Integer.MAX_VALUE)) {
+ throw new IllegalArgumentException("invalid range: [" + a + ", " + b + ")");
+ }
+ return a + uniform(b - a);
+ }
+
+ /**
+ * Returns a random real number uniformly in [a, b).
+ *
+ * @param a the left endpoint
+ * @param b the right endpoint
+ * @return a random real number uniformly in [a, b)
+ * @throws IllegalArgumentException unless {@code a < b}
+ */
+ public static double uniform(double a, double b) {
+ if (!(a < b)) {
+ throw new IllegalArgumentException("invalid range: [" + a + ", " + b + ")");
+ }
+ return a + uniform() * (b-a);
+ }
+
+ /**
+ * Returns a random boolean from a Bernoulli distribution with success
+ * probability p.
+ *
+ * @param p the probability of returning {@code true}
+ * @return {@code true} with probability {@code p} and
+ * {@code false} with probability {@code 1 - p}
+ * @throws IllegalArgumentException unless {@code 0} ≤ {@code p} ≤ {@code 1.0}
+ */
+ public static boolean bernoulli(double p) {
+ if (!(p >= 0.0 && p <= 1.0))
+ throw new IllegalArgumentException("probability p must be between 0.0 and 1.0: " + p);
+ return uniform() < p;
+ }
+
+ /**
+ * Returns a random boolean from a Bernoulli distribution with success
+ * probability 1/2.
+ *
+ * @return {@code true} with probability 1/2 and
+ * {@code false} with probability 1/2
+ */
+ public static boolean bernoulli() {
+ return bernoulli(0.5);
+ }
+
+ /**
+ * Returns a random real number from a standard Gaussian distribution.
+ *
+ * @return a random real number from a standard Gaussian distribution
+ * (mean 0 and standard deviation 1).
+ */
+ public static double gaussian() {
+ // use the polar form of the Box-Muller transform
+ double r, x, y;
+ do {
+ x = uniform(-1.0, 1.0);
+ y = uniform(-1.0, 1.0);
+ r = x*x + y*y;
+ } while (r >= 1 || r == 0);
+ return x * Math.sqrt(-2 * Math.log(r) / r);
+
+ // Remark: y * Math.sqrt(-2 * Math.log(r) / r)
+ // is an independent random gaussian
+ }
+
+ /**
+ * Returns a random real number from a Gaussian distribution with mean μ
+ * and standard deviation σ.
+ *
+ * @param mu the mean
+ * @param sigma the standard deviation
+ * @return a real number distributed according to the Gaussian distribution
+ * with mean {@code mu} and standard deviation {@code sigma}
+ */
+ public static double gaussian(double mu, double sigma) {
+ return mu + sigma * gaussian();
+ }
+
+ /**
+ * Returns a random integer from a geometric distribution with success
+ * probability p.
+ * The integer represents the number of independent trials
+ * before the first success.
+ *
+ * @param p the parameter of the geometric distribution
+ * @return a random integer from a geometric distribution with success
+ * probability {@code p}; or {@code Integer.MAX_VALUE} if
+ * {@code p} is (nearly) equal to {@code 1.0}.
+ * @throws IllegalArgumentException unless {@code p >= 0.0} and {@code p <= 1.0}
+ */
+ public static int geometric(double p) {
+ if (!(p >= 0)) {
+ throw new IllegalArgumentException("probability p must be greater than 0: " + p);
+ }
+ if (!(p <= 1.0)) {
+ throw new IllegalArgumentException("probability p must not be larger than 1: " + p);
+ }
+ // using algorithm given by Knuth
+ return (int) Math.ceil(Math.log(uniform()) / Math.log(1.0 - p));
+ }
+
+ /**
+ * Returns a random integer from a Poisson distribution with mean λ.
+ *
+ * @param lambda the mean of the Poisson distribution
+ * @return a random integer from a Poisson distribution with mean {@code lambda}
+ * @throws IllegalArgumentException unless {@code lambda > 0.0} and not infinite
+ */
+ public static int poisson(double lambda) {
+ if (!(lambda > 0.0))
+ throw new IllegalArgumentException("lambda must be positive: " + lambda);
+ if (Double.isInfinite(lambda))
+ throw new IllegalArgumentException("lambda must not be infinite: " + lambda);
+ // using algorithm given by Knuth
+ // see http://en.wikipedia.org/wiki/Poisson_distribution
+ int k = 0;
+ double p = 1.0;
+ double expLambda = Math.exp(-lambda);
+ do {
+ k++;
+ p *= uniform();
+ } while (p >= expLambda);
+ return k-1;
+ }
+
+ /**
+ * Returns a random real number from the standard Pareto distribution.
+ *
+ * @return a random real number from the standard Pareto distribution
+ */
+ public static double pareto() {
+ return pareto(1.0);
+ }
+
+ /**
+ * Returns a random real number from a Pareto distribution with
+ * shape parameter α.
+ *
+ * @param alpha shape parameter
+ * @return a random real number from a Pareto distribution with shape
+ * parameter {@code alpha}
+ * @throws IllegalArgumentException unless {@code alpha > 0.0}
+ */
+ public static double pareto(double alpha) {
+ if (!(alpha > 0.0))
+ throw new IllegalArgumentException("alpha must be positive: " + alpha);
+ return Math.pow(1 - uniform(), -1.0/alpha) - 1.0;
+ }
+
+ /**
+ * Returns a random real number from the Cauchy distribution.
+ *
+ * @return a random real number from the Cauchy distribution.
+ */
+ public static double cauchy() {
+ return Math.tan(Math.PI * (uniform() - 0.5));
+ }
+
+ /**
+ * Returns a random integer from the specified discrete distribution.
+ *
+ * @param probabilities the probability of occurrence of each integer
+ * @return a random integer from a discrete distribution:
+ * {@code i} with probability {@code probabilities[i]}
+ * @throws IllegalArgumentException if {@code probabilities} is {@code null}
+ * @throws IllegalArgumentException if sum of array entries is not (very nearly) equal to {@code 1.0}
+ * @throws IllegalArgumentException unless {@code probabilities[i] >= 0.0} for each index {@code i}
+ */
+ public static int discrete(double[] probabilities) {
+ if (probabilities == null) throw new IllegalArgumentException("argument array must not be null");
+ double EPSILON = 1.0E-14;
+ double sum = 0.0;
+ for (int i = 0; i < probabilities.length; i++) {
+ if (!(probabilities[i] >= 0.0))
+ throw new IllegalArgumentException("array entry " + i + " must be non-negative: " + probabilities[i]);
+ sum += probabilities[i];
+ }
+ if (sum > 1.0 + EPSILON || sum < 1.0 - EPSILON)
+ throw new IllegalArgumentException("sum of array entries does not approximately equal 1.0: " + sum);
+
+ // the for loop may not return a value when both r is (nearly) 1.0 and when the
+ // cumulative sum is less than 1.0 (as a result of floating-point roundoff error)
+ while (true) {
+ double r = uniform();
+ sum = 0.0;
+ for (int i = 0; i < probabilities.length; i++) {
+ sum = sum + probabilities[i];
+ if (sum > r) return i;
+ }
+ }
+ }
+
+ /**
+ * Returns a random integer from the specified discrete distribution.
+ *
+ * @param frequencies the frequency of occurrence of each integer
+ * @return a random integer from a discrete distribution:
+ * {@code i} with probability proportional to {@code frequencies[i]}
+ * @throws IllegalArgumentException if {@code frequencies} is {@code null}
+ * @throws IllegalArgumentException if all array entries are {@code 0}
+ * @throws IllegalArgumentException if {@code frequencies[i]} is negative for any index {@code i}
+ * @throws IllegalArgumentException if sum of frequencies exceeds {@code Integer.MAX_VALUE} (231 - 1)
+ */
+ public static int discrete(int[] frequencies) {
+ if (frequencies == null) throw new IllegalArgumentException("argument array must not be null");
+ long sum = 0;
+ for (int i = 0; i < frequencies.length; i++) {
+ if (frequencies[i] < 0)
+ throw new IllegalArgumentException("array entry " + i + " must be non-negative: " + frequencies[i]);
+ sum += frequencies[i];
+ }
+ if (sum == 0)
+ throw new IllegalArgumentException("at least one array entry must be positive");
+ if (sum >= Integer.MAX_VALUE)
+ throw new IllegalArgumentException("sum of frequencies overflows an int");
+
+ // pick index i with probabilitity proportional to frequency
+ double r = uniform((int) sum);
+ sum = 0;
+ for (int i = 0; i < frequencies.length; i++) {
+ sum += frequencies[i];
+ if (sum > r) return i;
+ }
+
+ // can't reach here
+ assert false;
+ return -1;
+ }
+
+ /**
+ * Returns a random real number from an exponential distribution
+ * with rate λ.
+ *
+ * @param lambda the rate of the exponential distribution
+ * @return a random real number from an exponential distribution with
+ * rate {@code lambda}
+ * @throws IllegalArgumentException unless {@code lambda > 0.0}
+ */
+ public static double exp(double lambda) {
+ if (!(lambda > 0.0))
+ throw new IllegalArgumentException("lambda must be positive: " + lambda);
+ return -Math.log(1 - uniform()) / lambda;
+ }
+
+ /**
+ * Rearranges the elements of the specified array in uniformly random order.
+ *
+ * @param a the array to shuffle
+ * @throws IllegalArgumentException if {@code a} is {@code null}
+ */
+ public static void shuffle(Object[] a) {
+ validateNotNull(a);
+ int n = a.length;
+ for (int i = 0; i < n; i++) {
+ int r = i + uniform(n-i); // between i and n-1
+ Object temp = a[i];
+ a[i] = a[r];
+ a[r] = temp;
+ }
+ }
+
+ /**
+ * Rearranges the elements of the specified array in uniformly random order.
+ *
+ * @param a the array to shuffle
+ * @throws IllegalArgumentException if {@code a} is {@code null}
+ */
+ public static void shuffle(double[] a) {
+ validateNotNull(a);
+ int n = a.length;
+ for (int i = 0; i < n; i++) {
+ int r = i + uniform(n-i); // between i and n-1
+ double temp = a[i];
+ a[i] = a[r];
+ a[r] = temp;
+ }
+ }
+
+ /**
+ * Rearranges the elements of the specified array in uniformly random order.
+ *
+ * @param a the array to shuffle
+ * @throws IllegalArgumentException if {@code a} is {@code null}
+ */
+ public static void shuffle(int[] a) {
+ validateNotNull(a);
+ int n = a.length;
+ for (int i = 0; i < n; i++) {
+ int r = i + uniform(n-i); // between i and n-1
+ int temp = a[i];
+ a[i] = a[r];
+ a[r] = temp;
+ }
+ }
+
+ /**
+ * Rearranges the elements of the specified array in uniformly random order.
+ *
+ * @param a the array to shuffle
+ * @throws IllegalArgumentException if {@code a} is {@code null}
+ */
+ public static void shuffle(char[] a) {
+ validateNotNull(a);
+ int n = a.length;
+ for (int i = 0; i < n; i++) {
+ int r = i + uniform(n-i); // between i and n-1
+ char temp = a[i];
+ a[i] = a[r];
+ a[r] = temp;
+ }
+ }
+
+ /**
+ * Rearranges the elements of the specified subarray in uniformly random order.
+ *
+ * @param a the array to shuffle
+ * @param lo the left endpoint (inclusive)
+ * @param hi the right endpoint (exclusive)
+ * @throws IllegalArgumentException if {@code a} is {@code null}
+ * @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
+ *
+ */
+ public static void shuffle(Object[] a, int lo, int hi) {
+ validateNotNull(a);
+ validateSubarrayIndices(lo, hi, a.length);
+
+ for (int i = lo; i < hi; i++) {
+ int r = i + uniform(hi-i); // between i and hi-1
+ Object temp = a[i];
+ a[i] = a[r];
+ a[r] = temp;
+ }
+ }
+
+ /**
+ * Rearranges the elements of the specified subarray in uniformly random order.
+ *
+ * @param a the array to shuffle
+ * @param lo the left endpoint (inclusive)
+ * @param hi the right endpoint (exclusive)
+ * @throws IllegalArgumentException if {@code a} is {@code null}
+ * @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
+ */
+ public static void shuffle(double[] a, int lo, int hi) {
+ validateNotNull(a);
+ validateSubarrayIndices(lo, hi, a.length);
+
+ for (int i = lo; i < hi; i++) {
+ int r = i + uniform(hi-i); // between i and hi-1
+ double temp = a[i];
+ a[i] = a[r];
+ a[r] = temp;
+ }
+ }
+
+ /**
+ * Rearranges the elements of the specified subarray in uniformly random order.
+ *
+ * @param a the array to shuffle
+ * @param lo the left endpoint (inclusive)
+ * @param hi the right endpoint (exclusive)
+ * @throws IllegalArgumentException if {@code a} is {@code null}
+ * @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
+ */
+ public static void shuffle(int[] a, int lo, int hi) {
+ validateNotNull(a);
+ validateSubarrayIndices(lo, hi, a.length);
+
+ for (int i = lo; i < hi; i++) {
+ int r = i + uniform(hi-i); // between i and hi-1
+ int temp = a[i];
+ a[i] = a[r];
+ a[r] = temp;
+ }
+ }
+
+ /**
+ * Returns a uniformly random permutation of n elements.
+ *
+ * @param n number of elements
+ * @throws IllegalArgumentException if {@code n} is negative
+ * @return an array of length {@code n} that is a uniformly random permutation
+ * of {@code 0}, {@code 1}, ..., {@code n-1}
+ */
+ public static int[] permutation(int n) {
+ if (n < 0) throw new IllegalArgumentException("n must be non-negative: " + n);
+ int[] perm = new int[n];
+ for (int i = 0; i < n; i++)
+ perm[i] = i;
+ shuffle(perm);
+ return perm;
+ }
+
+ /**
+ * Returns a uniformly random permutation of k of n elements.
+ *
+ * @param n number of elements
+ * @param k number of elements to select
+ * @throws IllegalArgumentException if {@code n} is negative
+ * @throws IllegalArgumentException unless {@code 0 <= k <= n}
+ * @return an array of length {@code k} that is a uniformly random permutation
+ * of {@code k} of the elements from {@code 0}, {@code 1}, ..., {@code n-1}
+ */
+ public static int[] permutation(int n, int k) {
+ if (n < 0) throw new IllegalArgumentException("n must be non-negative: " + n);
+ if (k < 0 || k > n) throw new IllegalArgumentException("k must be between 0 and n: " + k);
+ int[] perm = new int[k];
+ for (int i = 0; i < k; i++) {
+ int r = uniform(i+1); // between 0 and i
+ perm[i] = perm[r];
+ perm[r] = i;
+ }
+ for (int i = k; i < n; i++) {
+ int r = uniform(i+1); // between 0 and i
+ if (r < k) perm[r] = i;
+ }
+ return perm;
+ }
+
+ // throw an IllegalArgumentException if x is null
+ // (x can be of type Object[], double[], int[], ...)
+ private static void validateNotNull(Object x) {
+ if (x == null) {
+ throw new IllegalArgumentException("argument must not be null");
+ }
+ }
+
+ // throw an exception unless 0 <= lo <= hi <= length
+ private static void validateSubarrayIndices(int lo, int hi, int length) {
+ if (lo < 0 || hi > length || lo > hi) {
+ throw new IllegalArgumentException("subarray indices out of bounds: [" + lo + ", " + hi + ")");
+ }
+ }
+
+ /**
+ * Unit tests the methods in this class.
+ *
+ * @param args the command-line arguments
+ */
+ public static void main(String[] args) {
+ int n = Integer.parseInt(args[0]);
+ if (args.length == 2) StdRandom.setSeed(Long.parseLong(args[1]));
+ double[] probabilities = { 0.5, 0.3, 0.1, 0.1 };
+ int[] frequencies = { 5, 3, 1, 1 };
+ String[] a = "A B C D E F G".split(" ");
+
+ StdOut.println("seed = " + StdRandom.getSeed());
+ for (int i = 0; i < n; i++) {
+ StdOut.printf("%2d ", uniform(100));
+ StdOut.printf("%8.5f ", uniform(10.0, 99.0));
+ StdOut.printf("%5b ", bernoulli(0.5));
+ StdOut.printf("%7.5f ", gaussian(9.0, 0.2));
+ StdOut.printf("%1d ", discrete(probabilities));
+ StdOut.printf("%1d ", discrete(frequencies));
+ StdOut.printf("%11d ", uniform(100000000000L));
+ StdRandom.shuffle(a);
+ for (String s : a)
+ StdOut.print(s);
+ StdOut.println();
+ }
+ }
+
+}
+
+/******************************************************************************
+ * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
+ *
+ * This file is part of algs4.jar, which accompanies the textbook
+ *
+ * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
+ * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
+ * http://algs4.cs.princeton.edu
+ *
+ *
+ * algs4.jar is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * algs4.jar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with algs4.jar. If not, see http://www.gnu.org/licenses.
+ ******************************************************************************/
diff --git a/src/algs4/util/Stopwatch.java b/src/algs4/util/Stopwatch.java
new file mode 100644
index 0000000..b8d228b
--- /dev/null
+++ b/src/algs4/util/Stopwatch.java
@@ -0,0 +1,110 @@
+/******************************************************************************
+ * Compilation: javac Stopwatch.java
+ * Execution: java Stopwatch n
+ * Dependencies: none
+ *
+ * A utility class to measure the running time (wall clock) of a program.
+ *
+ * % java8 Stopwatch 100000000
+ * 6.666667e+11 0.5820 seconds
+ * 6.666667e+11 8.4530 seconds
+ *
+ ******************************************************************************/
+
+package algs4.util;
+
+/**
+ * The {@code Stopwatch} data type is for measuring
+ * the time that elapses between the start and end of a
+ * programming task (wall-clock time).
+ *
+ * See {@link StopwatchCPU} for a version that measures CPU time.
+ * For additional documentation,
+ * see Section 1.4 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ *
+ * @author Robert Sedgewick
+ * @author Kevin Wayne
+ */
+
+
+public class Stopwatch {
+
+ private final long start;
+
+ /**
+ * Initializes a new stopwatch.
+ */
+ public Stopwatch() {
+ start = System.currentTimeMillis();
+ }
+
+
+ /**
+ * Returns the elapsed CPU time (in seconds) since the stopwatch was created.
+ *
+ * @return elapsed CPU time (in seconds) since the stopwatch was created
+ */
+ public double elapsedTime() {
+ long now = System.currentTimeMillis();
+ return (now - start) / 1000.0;
+ }
+
+
+ /**
+ * Unit tests the {@code Stopwatch} data type.
+ * Takes a command-line argument {@code n} and computes the
+ * sum of the square roots of the first {@code n} positive integers,
+ * first using {@code Math.sqrt()}, then using {@code Math.pow()}.
+ * It prints to standard output the sum and the amount of time to
+ * compute the sum. Note that the discrete sum can be approximated by
+ * an integral - the sum should be approximately 2/3 * (n^(3/2) - 1).
+ *
+ * @param args the command-line arguments
+ */
+ public static void main(String[] args) {
+ int n = Integer.parseInt(args[0]);
+
+ // sum of square roots of integers from 1 to n using Math.sqrt(x).
+ Stopwatch timer1 = new Stopwatch();
+ double sum1 = 0.0;
+ for (int i = 1; i <= n; i++) {
+ sum1 += Math.sqrt(i);
+ }
+ double time1 = timer1.elapsedTime();
+ StdOut.printf("%e (%.2f seconds)\n", sum1, time1);
+
+ // sum of square roots of integers from 1 to n using Math.pow(x, 0.5).
+ Stopwatch timer2 = new Stopwatch();
+ double sum2 = 0.0;
+ for (int i = 1; i <= n; i++) {
+ sum2 += Math.pow(i, 0.5);
+ }
+ double time2 = timer2.elapsedTime();
+ StdOut.printf("%e (%.2f seconds)\n", sum2, time2);
+ }
+}
+
+/******************************************************************************
+ * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
+ *
+ * This file is part of algs4.jar, which accompanies the textbook
+ *
+ * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
+ * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
+ * http://algs4.cs.princeton.edu
+ *
+ *
+ * algs4.jar is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * algs4.jar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with algs4.jar. If not, see http://www.gnu.org/licenses.
+ ******************************************************************************/
diff --git a/src/algs4/util/StopwatchCPU.java b/src/algs4/util/StopwatchCPU.java
new file mode 100644
index 0000000..4102749
--- /dev/null
+++ b/src/algs4/util/StopwatchCPU.java
@@ -0,0 +1,112 @@
+/******************************************************************************
+ * Compilation: javac StopwatchCPU.java
+ * Execution: java StopwtachCPU n
+ * Dependencies: none
+ *
+ * A version of Stopwatch.java that measures CPU time on a single
+ * core or processor (instead of wall clock time).
+ *
+ * % java8 StopwatchCPU 100000000
+ * 6.666667e+11 (1.05 seconds)
+ * 6.666667e+11 (7.50 seconds)
+ *
+ ******************************************************************************/
+
+package algs4.util;
+
+import java.lang.management.ThreadMXBean;
+import java.lang.management.ManagementFactory;
+
+/**
+ * The {@code StopwatchCPU} data type is for measuring
+ * the CPU time used during a programming task.
+ *
+ * See {@link Stopwatch} for a version that measures wall-clock time
+ * (the real time that elapses).
+ *
+ * @author Josh Hug
+ * @author Robert Sedgewick
+ * @author Kevin Wayne
+ */
+
+public class StopwatchCPU {
+ private static final double NANOSECONDS_PER_SECOND = 1_000_000_000;
+
+ private final ThreadMXBean threadTimer;
+ private final long start;
+
+ /**
+ * Initializes a new stopwatch.
+ */
+ public StopwatchCPU() {
+ threadTimer = ManagementFactory.getThreadMXBean();
+ start = threadTimer.getCurrentThreadCpuTime();
+ }
+
+ /**
+ * Returns the elapsed CPU time (in seconds) since the stopwatch was created.
+ *
+ * @return elapsed CPU time (in seconds) since the stopwatch was created
+ */
+ public double elapsedTime() {
+ long now = threadTimer.getCurrentThreadCpuTime();
+ return (now - start) / NANOSECONDS_PER_SECOND;
+ }
+
+ /**
+ * Unit tests the {@code StopwatchCPU} data type.
+ * Takes a command-line argument {@code n} and computes the
+ * sum of the square roots of the first {@code n} positive integers,
+ * first using {@code Math.sqrt()}, then using {@code Math.pow()}.
+ * It prints to standard output the sum and the amount of time to
+ * compute the sum. Note that the discrete sum can be approximated by
+ * an integral - the sum should be approximately 2/3 * (n^(3/2) - 1).
+ *
+ * @param args the command-line arguments
+ */
+ public static void main(String[] args) {
+ int n = Integer.parseInt(args[0]);
+
+ // sum of square roots of integers from 1 to n using Math.sqrt(x).
+ StopwatchCPU timer1 = new StopwatchCPU();
+ double sum1 = 0.0;
+ for (int i = 1; i <= n; i++) {
+ sum1 += Math.sqrt(i);
+ }
+ double time1 = timer1.elapsedTime();
+ StdOut.printf("%e (%.2f seconds)\n", sum1, time1);
+
+ // sum of square roots of integers from 1 to n using Math.pow(x, 0.5).
+ StopwatchCPU timer2 = new StopwatchCPU();
+ double sum2 = 0.0;
+ for (int i = 1; i <= n; i++) {
+ sum2 += Math.pow(i, 0.5);
+ }
+ double time2 = timer2.elapsedTime();
+ StdOut.printf("%e (%.2f seconds)\n", sum2, time2);
+ }
+}
+
+/******************************************************************************
+ * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
+ *
+ * This file is part of algs4.jar, which accompanies the textbook
+ *
+ * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
+ * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
+ * http://algs4.cs.princeton.edu
+ *
+ *
+ * algs4.jar is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * algs4.jar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with algs4.jar. If not, see http://www.gnu.org/licenses.
+ ******************************************************************************/
diff --git a/src/core/problem/Action.java b/src/core/problem/Action.java
new file mode 100644
index 0000000..07cbd6a
--- /dev/null
+++ b/src/core/problem/Action.java
@@ -0,0 +1,6 @@
+package core.problem;
+
+public abstract class Action {
+ public abstract void draw();
+ public abstract int stepCost();
+}
diff --git a/src/core/problem/Problem.java b/src/core/problem/Problem.java
new file mode 100644
index 0000000..b6ac544
--- /dev/null
+++ b/src/core/problem/Problem.java
@@ -0,0 +1,143 @@
+package core.problem;
+
+import core.solver.Node;
+import core.solver.heuristic.Predictor;
+
+import java.util.ArrayList;
+import java.util.Deque;
+
+/**
+ * 所有问题的抽象超类
+ * initialState
+ * goal
+ */
+public abstract class Problem {
+ //成员变量
+ protected State initialState;
+ protected State goal;
+ protected int size; //问题的规模:15-puzzle为4;寻路问题为Grid的边长;野人传教士为野人与传教士的人数
+
+ public Problem(State initialState, State goal) {
+ this.initialState = initialState;
+ this.goal = goal;
+ }
+
+ public Problem(State initialState, State goal, int size) {
+ this(initialState, goal);
+ this.size = size;
+ }
+
+ public State getInitialState() {
+ return initialState;
+ }
+
+ public State getGoal() {
+ return goal;
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+ public void setSize(int size) {
+ this.size = size;
+ }
+
+ public void setInitialState(State initialState) {
+ this.initialState = initialState;
+ }
+
+ public void setGoal(State goal) {
+ this.goal = goal;
+ }
+
+ /**
+ * 当前问题是否有解
+ * @return 有解,true; 无解,false
+ *
+ */
+ public abstract boolean solvable();
+
+ /**
+ * 从初始状态产生搜索树的根节点
+ * @param predictor 启发函数
+ * @return 当前问题的根结点
+ */
+ public final Node root(Predictor predictor) {
+
+ return new Node(initialState, null, null,
+ 0, predictor.heuristics(initialState, goal));
+ }
+
+ /**
+ * 生成node的所有合法的后继结点
+ * @param parent 父结点
+ * @param predictor 启发函数
+ *
+ * @return parent结点的所有子结点
+ */
+ public final Iterable extends Node> childNodes(Node parent, Predictor predictor) {
+ ArrayList
+ *
+ *
+ *
+ *
+ * while (!StdIn.isEmpty()) {
+ * double value = StdIn.readDouble();
+ * StdOut.println(value);
+ * }
+ *
+ *
+ *
+ *
+ * while (StdIn.hasNextChar()) {
+ * char c = StdIn.readChar();
+ * StdOut.print(c);
+ * }
+ *
+ *
+ *
+ *
+ * while (StdIn.hasNextLine()) {
+ * String line = StdIn.readLine();
+ * StdOut.println(line);
+ * }
+ *
+ *
+ *
+ *
+ * String[] words = StdIn.readAllStrings();
+ *
+ *
+ *
+ *
+ * public class TestStdOut {
+ * public static void main(String[] args) {
+ * int a = 17;
+ * int b = 23;
+ * int sum = a + b;
+ * StdOut.println("Hello, World");
+ * StdOut.printf("%d + %d = %d\n", a, b, sum);
+ * }
+ * }
+ *
+ *
+ *
+ * uniform(-1.0, 1.0)
returns a random number between
+ * -1.0
(inclusive) and 1.0
(exclusive).
+ * Similarly, shuffle(a, lo, hi)
shuffles the hi - lo
+ * elements in the array a[]
, starting at index lo
+ * (inclusive) and ending at index hi
(exclusive).
+ *