前言
使用的是《算法》第四版英文版,主要是习题解答。
书中jar包的导入请戳:算法(第四版)中algs4.jar下载和使用
EXERCISES
1.2.1
import edu.princeton.cs.algs4.Point2D;
import edu.princeton.cs.algs4.StdDraw;
import edu.princeton.cs.algs4.StdOut;
import java.util.Scanner;
public class Solution {
public static void main(String[] args) {
StdDraw.setPenColor(StdDraw.RED);
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
Point2D[] points = new Point2D[N];
double distance = 1.0;
for (int i = 0; i < N; i++) {
double x = Math.random();
double y = Math.random();
Point2D point = new Point2D(x, y);
if (points.length > 0) {
for (int j = 0; j < i; j++) {
if (point.distanceTo(points[j]) < distance)
distance = point.distanceSquaredTo(points[j]);
}
}
points[i] = point;
point.draw();
}
StdOut.println(distance);
}
}
1.2.2
import edu.princeton.cs.algs4.*;
import java.util.Scanner;
public class Solution {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
Interval1D[] intervals = new Interval1D[N];
for (int i = 0; i < N; i++) {
double minN = StdIn.readDouble(); // 在algs4包里面的输入
double maxN = StdIn.readDouble();
intervals[i] = new Interval1D(minN, maxN);
}
for (int i = 0; i < N - 1; i++) {
for (int j = i + 1; j < N; j++) {
boolean isIntersect = intervals[i].intersects(intervals[j]);
if (isIntersect) {
System.out.println(intervals[i] + " and " + intervals[j] + " is intersect");
}
}
}
}
}
1.2.3
import edu.princeton.cs.algs4.*;
import java.util.Scanner;
public class Solution {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
double minN = scanner.nextDouble();
double maxN = scanner.nextDouble();
Interval2D[] intervals = new Interval2D[N];
Point2D[] point2D1 = new Point2D[N];
Point2D[] point2D2 = new Point2D[N];
for (int i = 0; i < N; i++) {
double d1 = StdRandom.uniform(minN, maxN);
double d2 = StdRandom.uniform(minN, maxN);
double d3 = StdRandom.uniform(minN, maxN);
double d4 = StdRandom.uniform(minN, maxN);
double xMin = min(d1, d2);
double xMax = max(d1, d2);
double yMin = min(d3, d4);
double yMax = max(d3, d4);
point2D1[i] = new Point2D(xMin, xMax);
point2D2[i] = new Point2D(yMin, yMax);
intervals[i] = new Interval2D(new Interval1D(xMin, xMax), new Interval1D(yMin, yMax));
}
for (int i = 0; i < N; i++) {
intervals[i].draw();
}
int countIntersects = 0;
for (int i = 0; i < N - 1; i++) {
for (int j = i + 1; j < N; j++) {
if (intervals[i].intersects(intervals[j]))
countIntersects++;
}
}
int countContains = 0;
for (int i = 0; i < N - 1; i++) {
for (int j = i + 1; j < N; j++) {
if (intervals[i].contains(point2D1[j]) && intervals[i].contains(point2D2[j]))
countContains++;
}
}
System.out.println("The number of pairs of intervals that intersect is " + countIntersects);
System.out.println("The number of intervals that are contained in one another is " + countContains);
}
public static double min(double d1, double d2) {
return d1 < d2 ? d1 : d2;
}
public static double max(double d1, double d2) {
return d1 > d2 ? d1 : d2;
}
}
1.2.4
注:
String对象被final修饰,值是不可变的。
声明一个String类型的引用变量名为string1,在内存中创建一个String类型的对象值为"Hello",然后把这个对象的引用赋值给变量string1
// String string1 = "Hello";
这个变量可以被用于指向其他对象,但是对象的值不可变
重新在内存中创建一个String类型对象值为"world",将这个对象的引用赋值给变量string1
// string1 = "world";
如果内存中的对象没有引用指向它,那么JVM会自动回收
GC机制可以了解一下
四种引用类型可以了解一下
1.2.5
1.2.6
import java.util.Scanner;
public class Solution {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
String t = scanner.nextLine();
if (s.length() == t.length() && s.concat(s).indexOf(t) != -1)
System.out.println("Yes");
else
System.out.println("No");
}
}
1.2.7
1.2.8
略
1.2.9
答案请戳这:习题1.2.9解答
1.2.10
import edu.princeton.cs.algs4.StdDraw;
import edu.princeton.cs.algs4.StdRandom;
import java.util.Scanner;
public class Solution {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int max = scanner.nextInt();
StdDraw.setXscale(0, N + 1);
StdDraw.setYscale(-max, max);
StdDraw.line(0, 0, N + 1, 0);
StdDraw.setPenColor(StdDraw.MAGENTA);
StdDraw.setPenRadius(0.01);
VisualCounter visualCounter = new VisualCounter(N, max);
visualCounter.draw();
for (int i = 0; i < N; i++) {
if (StdRandom.bernoulli())
visualCounter.increment();
else
visualCounter.decrement();
visualCounter.draw();
}
}
}
class VisualCounter {
private final int N;
private final int max;
private int value;
private int operationCount;
public VisualCounter(int N, int max) {
this.N = N;
this.max = max;
this.value = 0;
this.operationCount = 0;
}
public void increment() {
if (operationCount++ < N && value < max)
value++;
}
public void decrement() {
if (operationCount++ < N && value > -max)
value--;
}
public void draw() {
StdDraw.point(operationCount, value);
}
}
1.2.11
public class SmartDate{
private final int month;
private final int day;
private final int year;
public SmartDate(int month, int day, int year) throws Exception {
this.year = year;
if (month <= 12)
this.month = month;
else
throw new Exception("month is illegal");
boolean a = ((month == 4) || (month == 6) || (month == 9) || (month == 11)); // 这些月份最多30天
boolean b = ((month == 1) || (month == 3) || (month == 5) || (month == 7) || (month == 8) // 这些月份最多31天
|| (month == 10) || (month == 12));
// 判断是否闰年
if (year % 4 ==0 && year % 100 != 0 || year % 400 == 0) {
if (month == 2 && day <= 29)
this.day = day;
else if (a && day <= 30)
this.day = day;
else if (b && day <= 31)
this.day = day;
else
throw new Exception("day is illegal");
} else {
if (month == 2 && day <= 28) {
this.day = day;
} else if (a && day <= 30)
this.day = day;
else if (b && day <= 31)
this.day = day;
else
throw new Exception("day is illegal");
}
}
public int getMonth() {
return month;
}
public int getDay() {
return day;
}
public int getYear() {
return year;
}
@Override
public String toString() {
return getMonth() + "/" + getDay() + "/" + getYear();
}
}
1.2.12
判断如何通过日期计算星期几:蔡勒公式和朴素做法
public class SmartDate{
.... // 省略部分为1.2.11
....
....
public String dayOfTheWeek() {
// 计算公式:w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7
// 0-星期日 1-星期一 2-星期二 3-星球三 4-星期四 5-星期5 6-星期六
int d = day;
int m = month;
int y = year;
int res = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400 + 1) % 7;
String[] weeks = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
return weeks[res];
}
}
1.2.13
class Transaction implements Comparable<Transaction> {
private String name;
private SmartDate date;
private double amount;
private String transaction;
public Transaction(String name, SmartDate date, double amount) {
this.name = name;
this.date = date;
this.amount = amount;
}
public Transaction(String transaction) {
this.transaction = transaction;
}
public String getName() {
return name;
}
public SmartDate getDate() {
return date;
}
public double getAmount() {
return amount;
}
@Override
public String toString() {
return "Transaction{" + getName() + " " + getDate() + " " + getAmount() + "}";
}
@Override
public int compareTo(Transaction o) {
if (this.amount > o.amount)
return 1;
else if (this.amount < o.amount)
return -1;
else
return 0;
}
}
1.2.14
import java.util.Objects;
class Transaction implements Comparable<Transaction> {
... // 省略部分为1.2.13
...
...
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null)
return false;
if (this.getClass() != o.getClass())
return false;
Transaction transaction = (Transaction) o;
if (!this.name.equals(transaction.name))
return false;
if (!this.date.equals(transaction.date))
return false;
if (this.amount != transaction.amount)
return false;
return true;
}
@Override
public int hashCode() {
return Objects.hash(name, date, amount, transaction);
}
}
CREATIVE PROBLEMS
1.2.15
import edu.princeton.cs.algs4.In;
public class Solution {
public static void main(String[] args) {
int[] datas = readInts(args[0]);
for (int i = 0; i < datas.length; i++) {
System.out.println(datas[i]);
}
}
public static int[] readInts(String name) {
In in = new In(name);
String input = in.readAll();
String[] words = input.split("\\s+");
int[] res = new int[words.length];
for (int i = 0; i < words.length; i++) {
res[i] = Integer.parseInt(words[i]);
}
return res;
}
}
1.2.16
class Rational {
private final long numerator;
private final long denominator;
public Rational(long numerator, long denominator) {
if (denominator == 0)
throw new RuntimeException("denominator is zero!!");
long r = gcd(numerator, denominator);
if (denominator < 0)
r = -r;
this.numerator = numerator / r;
this.denominator = denominator / r;
}
public Rational plus(Rational b) {
long d = denominator * b.denominator;
long n = numerator * b.denominator + denominator * b.numerator;
return new Rational(n, d);
}
public Rational minus(Rational b) {
long d = denominator * b.denominator;
long n = numerator * b.denominator - denominator * b.numerator;
return new Rational(n, d);
}
public Rational times(Rational b) {
long d = denominator * b.denominator;
long n = numerator * b.numerator;
return new Rational(n, d);
}
public Rational divides(Rational b) {
long d = denominator * b.denominator;
long n = numerator * b.numerator;
return new Rational(n, d);
}
public boolean equals(Rational that) {
if (this == that)
return true;
if (that == null)
return false;
if (this.getClass() != that.getClass())
return false;
return (numerator == that.numerator && denominator == that.denominator);
}
@Override
public String toString() {
if (this.denominator == 1)
return String.format("%d", this.numerator);
return String.format("%d/%d", this.numerator, this.denominator);
}
public static long gcd(long p, long q) {
if (p < 0)
p = -p;
if (q < 0)
q = -q;
if (q == 0)
return p;
long r = p % q;
return gcd(q, r);
}
}
1.2.17
class Rational {
.... // 省略部分和1.2.16相同
....
....
public Rational plus(Rational b) {
assert (denominator < Long.MAX_VALUE && denominator > Long.MIN_VALUE);
assert (b.denominator < Long.MAX_VALUE && b.denominator > Long.MIN_VALUE);
long d = denominator * b.denominator;
long n = numerator * b.denominator + denominator * b.numerator;
return new Rational(n, d);
}
}
1.2.18
public class Solution {
public static void main(String[] args) {
Accumulator accumulator = new Accumulator();
accumulator.addDataValue(2);
accumulator.addDataValue(3);
accumulator.addDataValue(4);
accumulator.addDataValue(8);
System.out.println(accumulator);
}
}
class Accumulator {
private double m;
private double s;
private int n;
public void addDataValue(double val) {
n++;
s = s + 1.0 * (n - 1) / n * (val - m) * (val - m);
m = m + (val - m) / n;
}
public double mean() {
return m;
}
public double var() {
return s / (n - 1);
}
public double stddev() {
return Math.sqrt(this.var());
}
public String toString() {
return String.format("%.5f %.5f", mean(), stddev());
}
}
1.2.19
略