编程珠玑——–第三章习题笔记

  • Post author:
  • Post category:其他


3.1

利用数组,一维数组顺序存储收入梯度,二分查找,可以将固定税额和税率作为一条记录和收入梯度关联(做法太多不一一列举)

3.2

\#include  < iostream \>  
using namespace std;  
int recursion(int *a,int *c, int num, int index);
void recursion2(int *a,int *c, int num, int index);

int main()  
{  
    int t=0;  
    int i,k;  
    int m=10;  
    int c[15]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};  
    int a[14]={0};
    int *a1 = a;
    int *a2 = c;  
//    for(k=1;k<m;++k)  
//    {  
//        for(i=1;i<k;++i)  
//            a[k] += a[k-i] * c [i-1];  
//  
//        a[k] +=c[k+1];  
//    } // 0.2604s 
    //recursion(a1,a2,m,1);//0.2331s 优化尾递归后 
    recursion2(a1,a2,m,1);//0.3167s 未使用尾递归优化写法 
    for(i=0;i<m;++i)  
        cout<<a[i]<<endl;  

    return 0;  
}  

// 优化尾递归 
int recursion(int *a,int *c, int num, int index){
    //printf("num=%d index=%d", num,index);
    if (num != index) {
        int k = index;
        int i = 1;
        for(;i<k;++i)  
            *(a+k) += *(a+k-i) * *(c+i-1);  
            //printf("%d ", *(a+k-i));

        *(a+k) += *(c+k+1); 
        return recursion(a,c,num,index+1);
    }
    return 0; 
}

// 普通尾递归 
void recursion2(int *a,int *c, int num, int index){
    //printf("num=%d index=%d", num,index);
    if (num != index) {
        int k = index;
        int i = 1;
        for(;i<k;++i)  
            *(a+k) += *(a+k-i) * *(c+i-1);  
            //printf("%d ", *(a+k-i));

        *(a+k) += *(c+k+1); 
        recursion2(a,c,num,index+1);
    }
}

这个故事告诉我们尾递归时间上类似迭代(其实本质就是迭代),循环也是跌迭代,普通递归是递归(本质是参数压栈),尾递归的实现要依赖相关的引擎(以后抽空专门写一篇尾递归的介绍 期限是今年!!!!)

3.3

这道题 和3.8一样

这里写图片描述

因为26个字母,所以需要2个七段显示设备,比如A显示为01,字符数组为”10111110001010”,0表示未点亮的部分(这里首先要列举出数字0-9的所有 7段显示情况)

3.4

三个问题

第一个:检查闰年,一维数组存放每个月天数(这里存的是非闰年),year 差值* 365 + 中间month天数合+day差值+几个闰年-初始日期是否经过2月份(经过为1不经过为0)-初始日期是否经过2月份(经过为0不经过为1)

第二个:给定一个参照日期,输入日期和参照日期的天数(第一个问题)取模7

第三个:确定该月1号和参照日期的天数求得星期几,然后迭代到月底,每到星期六格式化换行,并在第一个日期前格式化输入(星期几的索引-0)个空格

3.5

我观察了一下,发现这里可以使用之前的标识变味词的方法,将最后一个“-”后的字母作为标识符归,“-”后相同的连字符归为一类,并按标识符顺序排序(这里也可以哈希存储每一个标识符),然后相同办法提取单词标识符,查找对应标识符下有没有对应的连字符(二分或者哈希)

3.6

这个要看用什么实现node.js实现的思路是设置变量名,再生成一个通用文档用模板字符串赋值,读取数据库文件将数据放入模板字符串变量,如果用C的话可以用一个字符数组来存储通用模板,将其中的变量做标识,等数据库操作数据返回后遍历通用模板取代对应变量生成新的定制文档。

3.7

这里我的思路是建立 标识1-单词完整拼写,标识2-押韵词的索引关系,然后排序二分查找

3.8

2 16 = 65532 < 99999

这道题我的思路是先把所有数字的单个情况表示出来,0表示这一段不存在,1表示存在,遍历每个数字

这个问题的障碍点在于格式化输出七段图!!!

这里套了

http://blog.csdn.net/zhuangxiaobin/article/details/39006679

这位博主的答案,C的输出怎么说呢。。。真伟大。。很佩服早年做dos系统图形化界面的前辈,都是一个个字符拼过去的

#include < iostream > 
#include < math.h >  
#include < string >  
using namespace std;  
//字符模板,从上往下依次为为数字0-9  
bool table[][7]={{1,1,1,0,1,1,1},  
                 {0,0,1,0,0,1,0},  
                 {1,0,1,1,1,0,1},  
                 {1,0,1,1,0,1,1},  
                 {0,1,1,1,0,1,0},  
                 {1,1,0,1,0,1,1},  
                 {1,1,0,1,1,1,1},  
                 {1,0,1,0,0,1,0},  
                 {1,1,1,1,1,1,1},  
                 {1,1,1,1,0,1,1}};  
//辅助显示用的,总共输出五行,记录每一行每一位的状态  
int DiplayTable [5][5]={0};  

void Display(int input)  
{  


    int figure[5]={0};  
    int f;  
    int i,k,j;  
    //依次取出五位数  
    for(k = 0;k<5;k++)  
    {  
        int p = int(pow(double(10),double(4-k)));  
        figure[k] = input/p;  
        input -= figure[k]*p;  
    }  
    //依次求取每一行每一位的状态,1 3 5行必定为横向,标记为4,2和4行各有三种情况,分别标记为1 2 3  
    for(i = 0;i<5;i++)  
    {  
        f=figure[i]; 

        if(table[f][0])  
            DiplayTable[i][0] = 4;  

        if(table[f][1]&&!table[f][2])  
            DiplayTable[i][1] = 1;  
        if(!table[f][1]&&table[f][2])  
            DiplayTable[i][1] = 2;  
        if(table[f][1]&&table[f][2])  
            DiplayTable[i][1] = 3;  

        if(table[f][3])  
            DiplayTable[i][2] = 4;  

        if(table[f][4]&&!table[f][5])  
            DiplayTable[i][3] = 1;  
        if(!table[f][4]&&table[f][5])  
            DiplayTable[i][3] = 2;  
        if(table[f][4]&&table[f][5])  
            DiplayTable[i][3] = 3;  
        if(table[f][6])  
            DiplayTable[i][4] = 4;  

    }  
    //按显示模板输出  
    for (i=0;i<5;i++)  
    {  
        for(j=0;j<5;j++)  
        {  
            switch(DiplayTable[j][i])  
            {  
            case 0:cout<<"    ";break;  
            case 1:cout<<"|   ";break;  
            case 2:cout<<"   |";break;  
            case 3:cout<<"|  |";break;  
            case 4:cout<<" -- ";break;  
            }  
            cout<<"      ";  
        }  
        cout<<endl;  
    }  


}  

int main()  
{  
    int i;  
    cin>>i;  

    Display(i);  
    return 0;  
}  



版权声明:本文为qq_36936155原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。