zoukankan      html  css  js  c++  java
  • 0x01算法设计与分析复习(一)习题解答

    参考书籍:算法设计与分析——C++语言描述(第二版)

    练习一

    1. 逆序输出正整数的各位数(递归算法求解)
    #include <stdio.h>
    //逆序输出正整数的各位数(递归算法求解)
    void print(unsigned int n)
    {
        printf("%d", n%10);//基础情况
        if(n>=10){
            print(n/10);//递归部分
        }
    }
    int main()
    {
        unsigned int n;
        scanf("%d", &n);
        print(n);
    
        return 0;
    }

    实验结果:

    123456
    654321
    Press any key to continue.
    1. 汉诺塔问题
    //hanoi,汉诺塔问题求解
    //将x柱上的n个圆盘经z柱移动到y柱上,任何时刻大盘不能在小盘上
    
    #include <stdio.h>
    
    void move(int n, char x, char y)//将圆盘x从x移到y上
    {
        printf("move %d from %c to %c
    ", n, x, y);
    
    }
    
    void Hanoi(int n, char x, char z, char y)//将n个圆盘经z从x移到y
    {
        if(n>0){
            Hanoi(n-1, x, y, z);//将n-1个盘从x移到z
            move(n, x, y);//将n盘从x移到y
            Hanoi(n-1, z, x, y);//将n-1个盘从z移到y
        }
    
    }
    
    int main()
    {
        int n = 0;
        char x = 'X', y = 'Y', z = 'Z';
        scanf("%d", &n);
    
        Hanoi(n, x, z, y);
    
        return 0;
    }

    实验结果:

    3
    move 1 from X to Y
    move 2 from X to Z
    move 1 from Y to Z
    move 3 from X to Y
    move 1 from Z to X
    move 2 from Z to Y
    move 1 from X to Y
    
    Press any key to continue.
    1. 排列产生算法
    //排列产生算法
    //给定n个自然数{0, 1, 2, ..., n-1},输出该集合所有可能的排列(permutation)
    
    #include <stdio.h>
    #include <stdlib.h>
    
    int i = 0;
    //arr[0]~arr[k-1]排好,求arr[k]到arr[n-1]的排列
    void Perm(int arr[], int k, int n)
    {
        if(k == n-1){
            for(int i = 0; i<n; i++)
                printf("%d ", arr[i]);
            printf("
    ");
            i++;
        } else if(k>=0){
            //从arr[k]~arr[n-1]中拿出一个加入到已经排好的队中
            for(int i = k; i<n; i++){
                int tmp = arr[k];
                arr[k] = arr[i];
                arr[i] = tmp;
                Perm(arr, k+1, n);
                arr[i] = arr[k];
                arr[k] = tmp;
            }
        }
    }
    
    int main()
    {
        int *arr = NULL, n = 0;
        scanf("%d", &n);
        arr = (int *)malloc(sizeof(int)*n);
        for(int i = 0; i<n; i++)
            arr[i] = i;
    
        Perm(arr, 0, n);
        printf("%d
    ", i);
        return 0;
    }

    实验结果:

    3
    0 1 2
    0 2 1
    1 0 2
    1 2 0
    2 1 0
    2 0 1
    6
    
    Press any key to continue.
    1. 给出n!的递归定义式,并设计一个递归函数计算n!
    /*n!的递归定义
      n! = n*(n-1)!,n>0;
      n! = 1,n = 0;
      */
    
    #include <stdio.h>
    
    int fact(int n)
    {
        if(n == 0)
            return 0;
        else if(n>1){
            return n*fact(n-1);
        }
    }
    int main()
    {
        int n = 0;
        scanf("%d", &n);
    
        printf("%d
    ", fact(n));
    
        return 0;
    }

    实验结果:

    4
    24
    
    Press any key to continue.
    1. 写一个递归算法和一个迭代算法计算二项式系数:
      Cmn=Cmn1+Cm1n1=n!m!(nm)!
    #include <stdio.h>
    #include <stdlib.h>
    //递归算法
    int func1(int n, int m)
    {
        if (m > n)
            return 0;
        if (n == m || m == 0)
            return 1;
        else if (n>0 && m>0)
            return func1(n - 1, m) + func1(n - 1, m - 1);
    
    }
    
    //迭代算法
    int func2(int n, int m)
    {
        int i = 0, j = 0;
        int **record = (int **)malloc((n + 1) * sizeof(int *));
        for (i = 0; i<n+1; i++)
            record[i] = (int *)malloc((m + 1) * sizeof(int));
        //记录矩阵
        for (i = 0; i<n + 1; i++)
            for (j = 0; j<m + 1; j++) {
                if (i < j)
                    record[i][j] = 0;
                if (i == j || j == 0)
                    record[i][j] = 1;
                else if (i >0 && j> 0)
                    record[i][j] = record[i - 1][j] + record[i - 1][j - 1];
            }
        return record[n][m];
    }
    
    int main()
    {
        int n = 0, m = 0;
        scanf("%d %d", &n, &m);
    
        printf("%d
    ", func1(n, m));
    
        printf("%d
    ", func2(n, m));
    
        return 0;
    }

    实验结果:

    4 2
    function 1: 6
    function 2: 6
    
    Press any key to continue.
    
    1. 给定一个字符串s和一个字符x,编写递归算法实现下列功能:
      (1)检查x是否在s中
      (2)计算x在s中出现的次数
      (3)删除s中所有的x
    /*
    给定一个字符串s和一个字符x,编写递归算法实现下列功能:
    (1)检查x是否在s中
    (2)计算x在s中出现的次数
    (3)删除s中所有的x
    */
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    //检查x是否在s中
    void XinS(char *s, char x)
    {
        if(s[0] != 0){
            if(x == s[0])
                printf("YES
    ");
            else {
                XinS(s+1, x);
            }
        } else 
            printf("NO
    ");
    
    }
    
    //计算x在s中出现的次数
    int CountX(char *s, char x)
    {
        int count = 0;
        if(s[0] != 0){
            if(s[0] == x)
                count++;
            count += CountX(s+1, x);
        }
    
        return count;
    }
    
    //删除s中所有的x
    char *DelX(char *s, char x)
    {
        static int j = 0;
        static char tmp[100] = {''};
        if(s[0] != 0){
            if(s[0] != x){
                tmp[j++] = s[0];
            }
            DelX(s+1, x);
        } else
            return tmp;
    } 
    
    int main()
    {
        char x, s[100] = {''}, *tmp;
        scanf("%s", s);
        getchar();//接收空字符;
        scanf("%c", &x);
        //(1)
        XinS(s, x);
        //(2)
        printf("%d
    ", CountX(s,x));
        //(3)
        tmp = DelX(s,x);
        memcpy(s, tmp, strlen(tmp)+1);
        printf("%s
    ", s);
        return 0;
    }

    实验结果:

    asdfgts
    s
    YES
    2
    adfgt
    
    Press any key to continue.
    1. 写一个C++函数求解:给定正整数n,确定n是否是它所有因子之和
    //写一个C++函数求解:给定正整数n,确定n是否是它所有因子之和
    //因子就是所有可以整除这个数的数,不包括这个数自身
    int ex7(unsigned int n)
    {
        int k=2, flag = n-1;
        while(k*k<n){
            if(n%k == 0){
                flag -= k;
                flag -= n/k;
            }
            k++;
        }
        if(k*k == n){
            flag -=k;
        }
        return (flag==0);
    }

    实验结果:

    15
    NO
    
    Press any key to continue.
    1. S是有n个元素的集合,S的幂集是S所有可能的子集组成的集合。例如,S=a,b,c,S=(),(a),(b),(c),(a,b),(a,c),(b,c),(a,b,c)。写一个C++递归函数,以S为输入,输出S的幂集。

    练习二

    1. 矩阵转置
      (1)设计一个C/C++程序实现一个n×m的矩阵转置。原矩阵保存在二维数组中。
      (2)使用全局变量count,改写矩阵转置程序,并运行修改后的程序,以确定改程序的程序步
      (3)计算此程序的渐进时间复杂度

    2. 证明:若f(n)=amnm+am1nm1++a1n+a0m次多项式,且am>0,则f(n)=Ω(nm).

      :不妨令c=12max{a0,a1,,am},n0=2,当nn0时,有

      cg(n)12(nm+nm1++n+1)12(nm+1nm1n)nm

      根据定义有:f(n)=Ω(nm)

    3. 运用主定理求T(n)=2T(n/4)+n,T(1)=3的渐进界

      :根据主定理,a=2,b=4,f(n)=n,log24=12,显然f(n)=n=Θ(nlogab),所以

    T(n)=Θ(nlogablogn)=Θ(nlogn)

  • 相关阅读:
    运维工程师的四个阶段
    必须知道的Linux内核常识详解
    Centos7/RHEL7 开启kdump
    sort实现ip排序
    如何判断是否开启超线程
    Django---进阶12
    Django---进阶11
    前端---进阶8
    前端---进阶7
    前端---进阶6
  • 原文地址:https://www.cnblogs.com/born2run/p/9581373.html
Copyright © 2011-2022 走看看