算法第四版习题解答(1.2 Data Abstraction)

本文档详细解答了《算法》第四版的部分习题,包括随机生成距离最远的点、区间交集判断、二维区间交集计数、字符串连接、日期操作、有理数运算、统计交易数据、计算概率分布以及实现特定算法等,涵盖了数据结构和算法的基础应用。
摘要由CSDN通过智能技术生成

前言

使用的是《算法》第四版英文版,主要是习题解答。

书中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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值