算法(fourth edition)課後練習1.1

1.1.29 等值鍵

本質上是對於二分算法的拓展

這裏默認數組爲升序排列,找到中間值之後,只需滿足“中間值”比“鍵值”小(大),中間的下(上)一個值比“鍵值”大(小),"中間值"與鍵值“相等”要考慮到值重複的情況,同時邊界的問題也要考慮在內.

重複值的統計就相對來說簡單一些,這裏的思路是立足一點向前和向後統計累加,應該有更加優雅的解法.

// 返回小於鍵值的元素數量
public static int rankOfKey(int key, int[] a) {
        int lo = 0;
        int hi = a.length - 1;
        int mid = 0;
        while (lo <= hi) {
            mid = lo + (hi - lo) / 2;
            if (a[mid] < key) {
                lo = mid + 1;
                if (lo > hi || a[lo] > key) return lo;
            }
            else if (a[mid] > key) {
                hi = mid - 1;
                if (hi < 0)                 hi = 0;
                if (hi == 0 || a[hi] < key) return hi;
            }
            else {
                while (a[mid] == key)
                    if (mid > 0) mid--;
                    else         return 0;
                return mid + 1;
            }
        }
        return -1;
    }

    //返回等於該鍵值的數量
    public static int count(int key, int[] a) {
        int lo = 0;
        int hi = a.length - 1;
        int count = 0;
        int start;
        while (lo <= hi) {
            int mid = lo + (hi - lo) / 2;
            if (a[mid] < key) lo = mid + 1;
            else if (a[mid] > key) hi = mid - 1;
            else {
                count++;
                start = mid;
                while (mid < a.length - 1 && a[++mid] == key) count++;
                while (start > 0 && a[--start] == key) count++;
                return count;
            }
        }
        return 0;
    }

1.1.30 數組練習

判斷i,j是否互質,創建數組並賦值,利用阿基米德算法來解決這個問題。

import edu.princeton.cs.algs4.StdOut;

public class ArraysPra {
    public static void main(String[] args) {
        Boolean[][] a = createArray(10);
        for (int i = 0; i < a.length - 1; i++) {
            for (int j = 0; j < a.length - 1; j++) {
                StdOut.println("i: " + i + " j: " + j + " " + a[i][j]);
            }
        }
    }

    public static Boolean[][] createArray(int n) {
        Boolean[][] a = new Boolean[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i == 0 || j == 0) a[i][j] = true;
                else if (archimedes(i, j) <= 1) a[i][j] = true;
                else a[i][j] = false;
            }
        }
        return a;
    }

    // 阿基米德算法,求解最大公約數
    public static int archimedes(int m, int n) {
        // StdOut.println("m: " + m + " n: " + n);
        if (m % n == 0) return n;
        else return archimedes(n, m % n);
    }

}
    

1.1.31 隨機連接

這裏主要是熟悉api的調用,書中提到的繪圖方法。(不過這熟悉的三角計算是怎麼回事?)

import edu.princeton.cs.algs4.StdDraw;
import edu.princeton.cs.algs4.StdRandom;

import java.awt.Color;

public class Link {

    public static void randomConnection(int n, double p) {
        double r = 0.4;
        double x0 = 0.5;
        double y0 = 0.5;
        double angle = 360.0 / n;
        double[][] points = new double[n][2];
        StdDraw.setPenRadius(0.01);
        StdDraw.setPenColor(Color.gray);

        for (int i = 0; i < n; i++) {
            points[i][0] = x0 + r * Math.cos(angle * i * Math.PI / 180);
            points[i][1] = y0 + r * Math.sin(angle * i * Math.PI / 180);
            StdDraw.point(points[i][0], points[i][1]);
        }

        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                if (StdRandom.bernoulli(p))
                    StdDraw.line(points[i][0], points[i][1], points[j][0], points[j][1]);
            }
        }

    }

    public static void main(String[] args) {
        if (args.length == 2) {
            randomConnection(
                    Integer.parseInt(args[0]),
                    Double.parseDouble(args[1])
            );
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章