数据结构与算法分析--Java语言描述(第一章(1))

本人Java入门小白,最近在看数据结构与算法分析--Java语言描述这本书,发现书本后面的习题真的很难。费了九牛二虎之力也只能解决一部分,因此决定记录一下,以供后期继续学习。文章中的代码全部为自己手动敲得,当然也有部分是参考网上大神的,欢迎各位大神指导。

习题1.1

编写一个程序解决选择问题。

本文主要采用两种方法。

第一种是通过某种排序算法(例如,冒泡排序)以递减的顺序将数组排序,然后返回第k个元素即可。

第二种是先把前k个元素读入数组并(以递减的顺序)对其进行排序。接着将剩下的元素再逐个读入。当新元素被读到时,如果它小于数组中的第k个元素则忽略,否则就将其放到数组中正确的位置上,同时将数组中的一个元素挤出数组。当算法结束时,位于第k个位置上的元素即为想要的答案。

第一种方法:

    /**
     * 获取一组数中的第k个最大的数
     *
     * @param arr
     * @param k
     * @return
     */
    private static int getKthMaxNum1(int[] arr,int k){
        sortArrayByDesc(arr);
        return arr[k-1];
    }    

    /**
     * 冒泡排序(递减)
     *
     * @param arr
     */
    private static void sortArrayByDesc(int[] arr){
        for(int i = 0; i < arr.length - 1; i++){
           for(int j = 0; j < arr.length - 1 - i; j++){
               if(arr[j] < arr[j+1]) {
                   int temp = arr[j];
                   arr[j] = arr[j+1];
                   arr[j+1] = temp;
               }
           }
        }
    }

第二种方法:

    /**
     * 获取一组数中的第k个最大的数
     *
     * @param arr
     * @param k
     * @return
     */
    private static int getKthMaxNum2(int[] arr,int k){
        // 将前k个元素读入数组并降序排序
        int[] newArr = Arrays.copyOf(arr, k);
        sortArrayByDesc(newArr);
        //  将剩下的元素与数组中的元素进行比较,如果小于数组中的第k个元素则忽略;
        // 反之将其放到数组中正确的位置上,同时将数组中的一个元素挤出数组
        updateKthOfArray(arr, k, newArr);
        return newArr[k-1];
    }

    /**
     * 更新数组
     *
     * @param arr
     * @param k
     * @param newArr
     */
    private static void updateKthOfArray(int[] arr, int k, int[] newArr) {
        for(int i = k; i < arr.length; i++){
            // 大于数组中的第k个元素,将其放到数组中合适的位置
            for(int j = 0; j < k - 1; j++){
                if(arr[i] > newArr[j]){
                    newArr[j] = arr[i];
                    // 将newArr中j之后的所有元素都赋值为其本身前一位的元素的值
                    for(int m = k - 1; m > j; m--){
                        newArr[m] = newArr[m-1];
                    }
                }
                break;
            }
        }
    }

方法二也可以换一种思路。

    /**
     * 获取一组数中的第k个最大的数
     *
     * @param arr
     * @param k
     * @return
     */
    private static int getKthMaxNum2(int[] arr,int k){
        // 将前k个元素读入数组并降序排序
        int[] newArr = Arrays.copyOf(arr, k);
        sortArrayByDesc(newArr);
        // 将剩下的元素与数组中的第k个元素进行比较,如果小于则忽略;
        // 反之,则进行替换并重新对数组进行降序排序。
        for(int i = k; i < arr.length; i++){
            if(arr[k] > newArr[k-1]){
                newArr[k-1] = arr[k];
                sortArrayByDesc(newArr);
            }
        }
        return newArr[k-1];
    }

 问题拓展:如何向有序数组中添加新的元素?

    /**
     * 数组添加新元素
     *
     * @param arr
     * @param n
     */
    public static void insertElement(int[] arr,int n){
        int[] newArr = new int[arr.length + 1];
        for(int i = 0; i < arr.length; i++){
            if(n < arr[i]){
                newArr[i] = n;
                for(i = i + 1; i < newArr.length; i++){
                    newArr[i] = arr[i-1];
                }
            }else{
                newArr[i] = arr[i];
            }
        }
    }

习题1.2

编写一个程序求解字谜游戏问题。

public class Puzzle_Game {

    static final char[][] letters = new char[][]{
            {'t', 'h', 'i', 's'},
            {'w', 'a', 't', 's'},
            {'o', 'a', 'h', 'g'},
            {'f', 'g', 'd', 't'}
    };

    static String[] dic = {"this", "two", "fat", "that"};
    static int minLenth = letters.length;     //最小长度
    static List<String> list = new ArrayList<>();

    public static void main(String[] args){

        //1.找出最小长度
        for (String string : dic) {
            if(string.length() < minLenth)
                minLenth = string.length();
        }
        //2.枚举字谜数组
        getAllWords(minLenth);

        //3.检索是否存在在字谜中
        Set<String> list2 = new TreeSet<>();
        for (String str : list) {
            for(int i = 0; i < dic.length; i++){
                if(str.indexOf(dic[i]) != -1)
                    list2.add(dic[i]);
            }
        }

        //4.打印单词
        Iterator<String> it = list2.iterator();
        while (it.hasNext()){
            String next = it.next();
            System.out.print(next + ",");
        }
    }

    /**
     * 枚举字谜数组
     *
     * @param minLength
     */
    public static void getAllWords(int minLength){
        for(int i = 0; i < letters.length; i++){
            //横向和纵向
            char[] dir1 = new char[letters[i].length];
            char[] dir2 = new char[letters[i].length];
            for(int j = 0; j < letters[i].length; j++){
                dir1[j] = letters[i][j];    //横向
                dir2[j] = letters[j][i];    //纵向
            }
            list.add(String.valueOf(dir1));
            list.add(String.valueOf(dir2));
            //斜对角
            if(i >= minLength - 1){
                char[] dir3 = new char[i + 1];    //左上
                char[] dir4 = new char[i + 1];    //左下
                char[] dir5 = new char[i + 1];    //右上
                char[] dir6 = new char[i + 1];    //右下
                int k = 0, l = i, t = letters.length - 1;
                while(l >= 0){
                    dir3[k] = letters[k][l];
                    dir4[k] = letters[t][l];
                    dir5[k] = letters[l][t];
                    dir6[k] = letters[letters.length - l - 1][t];
                    k++;
                    l--;
                    t--;
                }
                charReverse(dir3);
                charReverse(dir4);
                charReverse(dir5);
                charReverse(dir6);
            }
        }
    }

    /**
     * 字符反转
     *
     * @param c
     */
    public static void charReverse(char[] c){
        char[] c2 = new char[c.length];
        int j = 0;
        for(int i = c.length - 1; i >= 0; i--, j++){
            c2[j] = c[i];
        }
        list.add(String.valueOf(c2));
        list.add(String.valueOf(c));
    }
}

习题1.3

只使用处理I/O的printDigit方法,编写一种方法以输出任意double型量(可以是负的)。

    /**
     * 只使用处理IO的printDigit方法,编写一种方法以输出任意double型量(可以是负的)。
     *
     * @param num
     */
    public static void printNum(double num) {
        if (num < 0) {
            num = -num;
            System.out.print("-");
        }
        //整数部分
        int integral = (int) num;
        printOut(integral);

        //小数部分
        double fraction = num - integral;
        if(fraction != 0){
            System.out.print(".");
        }
        printDouble(fraction);
        System.out.println();

    }

    /**
     * 打印输出整数
     *
     * @param n
     */
    private static void printOut(int n) {
        if (n >= 10) {
            printOut(n / 10);
        }
         System.out.print(n % 10);
    }

    /**
     * 打印输出小数
     *
     * @param fraction
     */
    private static void printDouble(double fraction) {
        if (fraction < 1 && fraction >= 0.00001) {
            System.out.print((int) (fraction * 10) % 10);
            printDouble(fraction * 10 - (int) (fraction * 10));
        }
    }

习题1.5

编写递归方法,返回数N的二进制表示中1的个数。

方法一:不用递归

    /**
     * 返回数N的二进制表示中1的个数
     *
     * @param N
     * @return
     */
    public static int getOnes(int N) {
        int i = 0;
        while(N >= 1){
            if (N % 2 != 0) {
                i++;
            }
            N = N / 2;
        }
        return i;
    }

方法二:使用递归

    /**
     * 递归做法,返回数N的二进制表示中1的个数
     * @param N
     * @return
     */
    public static int Ones(int N){
        //递归终点有两个,n为1则返回1,n为0则返回0
        if(N < 2){
            return N;
        }
        //此为递归过程,如果为奇数,结果加1,如果为偶数,结果加0。
        return N % 2 + Ones(N/2);
    }

拓展:如何将整数转为二进制数?

    /**
     * 将整数转为二进制数
     *
     * @param N
     */
    public static void printForOne(int N) {
        String str = "";
        while (N >= 1) {
            str += N % 2;
            N = N / 2;
        }
        //反转
        String s = charReverse(str.toCharArray());
        System.out.println(s);
    }

    /**
     * 反转字符数组
     *
     * @param chars
     */
    public static String charReverse(char[] chars) {
        char[] ch = new char[chars.length];
        int j = 0;
        for (int i = chars.length - 1; i >= 0; i--, j++) {
            ch[j] = chars[i];
        }
        String string = String.valueOf(ch);
        return string;
    }
发布了19 篇原创文章 · 获赞 2 · 访问量 1448

猜你喜欢

转载自blog.csdn.net/Bonbon_wen/article/details/81329901