算法(第四版)练习 1.1.1 ~ 1.1.25

1.1.1

public class MyTest {
    public static void main(String[] args) {
        System.out.println((0 + 15) / 2);
        System.out.println(2.0e-6 * 100000000.1);
        System.out.println(true && false || true && true);
    }
} 

/*
output=
7
200.0000002
true
*/

 

1.1.2

public class MyTest {
    public static void main(String[] args) {
        System.out.println((1 + 2.236)/2);
        System.out.println(1 + 2 + 3 + 4.0);
        System.out.println(4.1 > 4);
        System.out.println(1 + 2 + "3");
    }
} 

/*
output=
1.618 (double)
10.0 (double)
true (boolean)
33 (int)String
*/

参考 P7 类型转换。 

 

1.1.3

public class MyTest {
    public static void main(String[] args) {
        String answer = (
            args[0].equals(args[1]) 
            && args[0].equals(args[2]) 
            && args[1].equals(args[2])) ? "equal" : "not equal";
            
        System.out.println(answer);
    }
} 

测试结果:

D:\labs>java MyTest 1 2 3
not equal

D:\labs>java MyTest 1 1 1
equal

 

1.1.4

 

1.1.5

import java.util.Scanner;

public class MyTest {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double x = 0, y = 0;
        x = scanner.nextDouble();
        y = scanner.nextDouble();
        if (x > 0 && x < 1 && y > 0 && y < 1) {
            System.out.println(true);
        } else {
            System.out.println(false);
        }
    }
} 

测试结果:

D:\labs>java MyTest
3
4
false

D:\labs>java MyTest
1
1
false

D:\labs>java MyTest
0.1
0.7
true

 

1.1.6

import java.util.Scanner;

public class MyTest {
    public static void main(String[] args) {
        int f = 0;
        int g = 1;
        for (int i = 0; i <= 15; ++i) {
            System.out.println(f);
            f = f + g;
            g = f - g;
        }
    }
} 

/*
output=
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
*/

 

1.1.7

public class MyTest {
    public static void main(String[] args) {
        double t = 9.0;
        while (Math.abs(t - 9.0/t) > .001) {
            t = (t + 9.0/t) / 2.0;
        }
        System.out.println(t);
        
        int sum = 0;
        for (int i = 1; i < 1000; ++i) {
            for (int j = 0; j < i; ++j) sum++;
        }
        System.out.println(sum);
        
        int sumB = 0;
        for (int i = 1; i < 1000; i *= 2) 
            for (int j = 0; j < 1000; ++j)
                sumB++;
        System.out.println(sumB);    
    }
} 
/*
output=
3.00009155413138
499500
10000
*/

[a] 3.00009

[b] 1 + 2 + ... + 999 = 499500

[c] 10000

 

1.1.8

public class MyTest {
    public static void main(String[] args) {
        System.out.println((int)'b');
        System.out.println('b' + 'c');
        System.out.println((char)('a' + 4));
    }
} 
/*
output=
b
197
e
*/

字符间相加、或者与数字相加时自动发生类型转换 char --> int ,第三个输出则把 int 强制转换为 char ,并且这个过程在编译期就已经完成了:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

public class MyTest {
    public MyTest() {
    }

    public static void main(String[] args) {
        System.out.println('b');
        System.out.println(197);
        System.out.println('e');
    }
}

 

1.1.9

书上有解答

 

1.1.10

书上有解答

 

1.1.11

public class MyTest {
    public static void print(Boolean[][] array) {
        for (int i = 0; i != array.length; ++i) {
            for (int j = 0; j != array[i].length; ++j) {
                System.out.println(i + "" + j + " " + (array[i][j] ? "*" : " "));
            }
        }
    }
    
    public static void main(String[] args) {
        Boolean[][] array = {{true, false, true}, 
                            {false, true, false}}; // direct initialization
        print(array);
    }
} 

 输出结果:

D:\labs>java MyTest
00 *
01
02 *
10
11 *
12

 

1.1.12

 

这道题是不是打印出错了?改为输出 a[i] :

import static java.util.stream.IntStream.range;
import static java.lang.System.out;

public class MyTest {
    public static void main(String[] args) {
        int[] a = new int[10];
        range(0, 10).forEach(i -> a[i] = 9 - i);
        range(0, 10).forEach(i -> a[i] = a[a[i]]);
        range(0, 10).forEach(i -> out.println(a[i]));
    }
} 
/*
output=
0
1
2
3
4
4
3
2
1
0
*/

 

1.1.13

import static java.util.stream.IntStream.range;
import static java.lang.System.out;

public class MyTest {
    public static void main(String[] args) {
        int[][] a = {{2, 3, 4}, {1, 2, 3}}; // direct initialization
        
        for (int j = 0; j != a[0].length; ++j) {
            for (int i = 0; i != a.length; ++i) {
                out.print(a[i][j] + " ");
            }
            out.println();
        }
    }
} 
/*
output=
2 1
3 2
4 3
*/

 

1.1.14

import static java.util.stream.IntStream.range;
import static java.lang.System.out;

public class MyTest {
    public static int lg(int N) {
        final int BASE = 2;
        int power = 0;
        int product = 1;
        while (product <= N) {
            product = product * BASE;
            ++ power;
        }
        return (power - 1);
    }
    
    public static void main(String[] args) {
        range(1, 10).forEach(i -> out.print(lg(i) + " "));
    }
} 
/*
output=
0 1 1 2 2 2 2 3 3
*/

 

1.1.15

import static java.util.stream.IntStream.range;
import static java.lang.System.out;

public class MyTest {
    public static int[] histogram(int[] a, int M) {
        int[] temp = new int[M];
        for (int x : a) {
            if (x >= 0 && x < M) {
                temp[x]++;
            }
        }
        return temp;
    }
    
    /**
     * Returns the maximum value in this array.
     */
    public static int getMax(int[] a) {
        int max = a[0];
        for (int i = 1; i != a.length; ++i) {
            if (a[i] > max) max = a[i];
        }
        return max;
    } 
    
    public static void main(String[] args) {
        int[] a = {1, 2, 2, 3, 4, 5, 5, 6, 7};
        int[] x = histogram(a, getMax(a) + 1);
        for (int i = 0; i != x.length; ++i) {
            out.println(i + " " + x[i]);
        }
    }
}
/*
output=
0 0
1 1
2 2
3 1
4 1
5 2
6 1
7 1
*/

 

1.1.16

import static java.util.stream.IntStream.range;
import static java.lang.System.out;

public class MyTest {
    public static String exR1(int n) {
        if (n <= 0) return "";
        return exR1(n-3) + n + exR1(n-2) + n;
    }
    public static void main(String[] args) {
        out.println(exR1(6));
    }
}
/*
output=
311361142246
*/

 

1.1.17

书上有解答

 

1.1.18

import static java.util.stream.IntStream.range;
import static java.lang.System.out;

public class MyTest {
    /**
     * Returns a*b
       */
    public static int mystery(int a, int b) {if (b == 0) return 0;
        if (b % 2 == 0) return mystery(a+a, b/2);
        return mystery(a+a, b/2) + a;
    }
    
    /**
     * Returns a^b
     */
    public static int mystery2(int a, int b) {
        if (b == 0) return 1;
        if (b % 2 == 0) return mystery2(a*a, b/2);
        return mystery2(a*a, b/2) * a;
    }
    
    public static void main(String[] args) {
        out.println(mystery(2, 25));
        out.println(mystery(3, 11));
        out.println(mystery2(2, 25));
        out.println(mystery2(3, 11));
    }
}
/*
output=
50
33
33554432
177147
*/

 

1.1.19

参考:http://www.jianshu.com/p/fedc9188b3a0

import static java.util.stream.IntStream.range;
import static java.lang.System.out;
// Fibonacci
public class MyTest {
    public static long F(int N) {
        if (N == 0) return 0;
        if (N == 1) return 1;
        return F(N-1) + F(N-2);
    }
    
    public static void main(String[] args) {
        for (int N = 0; N < 100; ++N) {
            out.println(N + " " + F(N));
        }
    }
}

第一次运算 10 秒钟内计算到了 40+ ,然后开始越来越慢,49 到 50 感觉用掉了近 5 分钟;

第二次运算进行了稍精确的时间记录(存在一定系统误差),结果如下:

计算出 F(44) 用时约 9 秒;

计算出 F(45) 用时约 5 秒;

计算出 F(46) 用时约 8 秒;

计算出 F(47) 用时约 15 秒;

计算出 F(48) 用时约 24 秒;

计算出 F(49) 用时约 39 秒;

计算出 F(50) 用时约 65 秒;

计算出 F(51) 用时约 105 秒;

容易看出计算 F(N) 的用去的时间大致等于 计算 F(N-1) 与 计算 F(N-2) 的用去的时间之和。

 一个小时之内能够得到 F(N) 结果的最大 N 值是 56 (手算 。。。)

改进版:

import static java.util.stream.IntStream.range;
import static java.lang.System.out;
import java.math.BigInteger;

// Fibonacci
public class MyTest {
    /* initialization */
    private static final int LENGTH = 1000;
    private static BigInteger[] fibonacci = new BigInteger[LENGTH]; // null
    
    static {
        fibonacci[0] = BigInteger.valueOf(0);
        fibonacci[1] = BigInteger.valueOf(1);
    }
    
    /* work */
    public static BigInteger F(int N) {
        if (fibonacci[N] != null) return fibonacci[N];
        fibonacci[N] = F(N-1).add(F(N-2));
        return fibonacci[N];
    }
    
    public static void main(String[] args) {
        for (int N = 0; N < 100; ++N) {
            out.println(N + " " + F(N));
        }
    }
}

 

1.1.20

import static java.util.stream.IntStream.range;
import static java.lang.System.out;

public class MyTest {
    // ln(N!) = ln(N) + ln(N-1) + ... + ln (1) 
    public static double lnFac(int N) {
        if (N == 1) return 0;
        return Math.log(N) + lnFac(N-1);
    }
    
    public static void main(String[] args) {
        for (int N = 1; N < 100; ++N) {
            out.println("ln(" + N + "!) " + lnFac(N));
        }
    }
}

 

1.1.21

import static java.util.stream.IntStream.range;
import static java.lang.System.out;
import java.util.*;  

public class MyTest {
    private static List<Player> players = new ArrayList<>();
    
    public static void save(String data) {
        String[] temp = data.split(" ");    
        String name = temp[0];
        int hit = Integer.parseInt(temp[1]);
        int total = Integer.parseInt(temp[2]);
        double hitRate = hit / (double)total;
        
        Player player = new Player(name, hit, total, hitRate);
        players.add(player);
    }
    
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        while (scanner.hasNextLine()) {
            String data = scanner.nextLine();
            save(data);
        }
        
        for (Player x : players) {
            out.println(x.getName() + " " + x.getHit() 
                + " " + x.getTotal() + " " 
                + String.format("%.2f", x.getHitRate()));
        };
    }
}

class Player {
    
    private String name;
    private int hit;
    private int total;
    private double hitRate;
    
    public Player(String name, int hit, int total, double hitRate) {
        this.name = name;
        this.hit = hit;
        this.total = total;
        this.hitRate = hitRate;
    }
    
    public String getName() {
        return name;
    }
    
    public int getHit() {
        return hit;
    }
    
    public int getTotal() {
        return total;
    }
    
    public double getHitRate() {
        return hitRate;
    }
}

/*
test:
wja 3 9
lyd 10 100
xfs 22 30
^Z
wja 3 9 0.33
lyd 10 100 0.10
xfs 22 30 0.73
*/

 

1.1.22

import static java.util.stream.IntStream.range;
import static java.lang.System.out;
import java.util.*;  

public class MyTest {
    private static int k;
    
    public static int rank(int key, int[] a) {
        return rank(key, a, 0, a.length - 1);
    }
    
    public static int rank(int key, int[] a, int lo, int hi) {
        // Prints lo and hi, depth of recursion. 
        out.print(k++ + ": ");
        for (int i = 0; i <= hi; ++i) {
            if (i == lo || i == hi) out.print(i);
            else out.print(" ");
        } 
        out.println();
        
        if (lo > hi) return -1;
        int mid = lo + (hi - lo) / 2;
        if (key < a[mid]) return rank(key, a, lo, mid - 1);
        else if (key > a[mid]) return rank(key, a, mid + 1, hi);
        else return mid;
    }
    
    public static void main(String[] args) {
        int[] a = {3, 2, 5, 7, 1, 11, 4, 22, 13, 15, 17, 12, 10};
        Arrays.sort(a);
        out.println("rank=" + rank(5, a));
    }
}

/*
output=
0: 0           12
1: 0    5
2:    3 5
rank=4
*/

 

1.1.23

 

1.1.24

import static java.util.stream.IntStream.range;
import static java.lang.System.out;
import java.util.*;  

public class MyTest {
    public static int gcd(int p, int q) {
        out.println("p=" + p + " ,q=" + q);
        if (p%q == 0) return q;
        else return gcd(q, p%q);
    }
    
    public static void main(String[] args) {
        out.println("answer=" + gcd(Integer.parseInt(args[0]), Integer.parseInt(args[1])));
    }
}

/*
test:
D:\labs>java MyTest 1111111 1234567
p=1111111 ,q=1234567
p=1234567 ,q=1111111
p=1111111 ,q=123456
p=123456 ,q=7
p=7 ,q=4
p=4 ,q=3
p=3 ,q=1
answer=1
*/

 

1.1.25

摘自:数学归纳法证明欧几里德算法

欧几里德的算法关键在于证明等式gcd(a,b)=gcd(b,a mod b)的正确性。
定理:a,b为正整数,则gcd(a,b)=gcd(b,a mod b)
证明:
k,r为整数,设r = a mod b,则a可以表示成a=kb+r。
假设d是{a,b}的一个公约数,则d整除a,d整除b,而r=a-kb,因此d整除r,d也是b和r的公约数。
假设d是{b,r}的一个公约数,则d整除b,d整除r,而a=kb+r,因此d整除a, d也是a和b的公约数。
因此{a,b}和{b,r}的公因子集合是一样的。特别地,{a,b}的最大共因子和{b,r}的最大公因子是一样的,即gcd(a,b)=gcd(b,a mod b)。
posted @ 2017-09-12 16:36  xkfx  阅读(525)  评论(0编辑  收藏  举报