一,内容

        通过使用恰当的数据结构来替代复杂的代码。

 

二,习题

1、题目描述:本书出版之时,美国的个人收入所得税分为5种不同的税率,其中最大的税 率大约为40%.以前的情况则更为复杂,税率也更高。下面所示的程序文本采用25个if语句的合理方法来计算1978年的美国联邦所得税。税率序列为 0.14, 0.15, 0.16, 0.17, 0.18.....。序列中此后的计算大于0.01.有何建议呢?

if income <= 2200

tax = 0;

else if income <= 2700

tax = 0.14 * (income - 2200);

else if income <= 3200

tax = 70 + 0.15 * (income - 2700);

else if income <= 3700

tax = 145 + 0.16 * (income -3200);

else if income <= 4200

tax =225 + 0.17 * (income - 3700);

.......

else

tax =53090 + 0.70 * (income - 102200);

 

采用二分搜索定位到采用哪个分段函数,然后对应求出结果。

源码:

  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. int basetax[100];  
  5. int lowerbound[100];  
  6. double taxrate[100];  
  7.   
  8. int search(int lowerbound[],int income)  
  9. {  
  10.     int i=0;  
  11.     int j=99;  
  12.     int t=(i+j)/2;  
  13.       
  14.     while(1)  
  15.     {  
  16.           
  17.         if(income - lowerbound[t] 50 && income - lowerbound[t] >=0)  
  18.             return t;  
  19.         else if(income - lowerbound[t] 0) //在左侧寻找   
  20.             {  
  21.                 j=t;  
  22.                 t=(i+j)/2;  
  23.                   
  24.             }  
  25.         else  
  26.             {  
  27.                 i=t;  
  28.                 t=(i+j)/2;  
  29.             }             
  30.     }     
  31.     return  -1;  
  32.       
  33. }  
  34. int main()  
  35. {  
  36.     basetax[0]=0;  
  37.     lowerbound[0]=0;  
  38.     taxrate[0]=0;  
  39.       
  40.     basetax[1]=0;  
  41.     lowerbound[1]=2200;  
  42.     taxrate[1]=0.14;  
  43.       
  44.     for(int i=2;i<100;++i)  
  45.     {  
  46.         basetax[i]=75*i-80;  
  47.         lowerbound[i]=2200 + (i-1)*500;  
  48.         taxrate[i]=(double)(14 + i-1)/100;  
  49.       
  50.     }     
  51.       
  52.     if(search(lowerbound,salary))  
  53.     {  
  54.         int salary=2202;  
  55.         int j=search(lowerbound,salary);  
  56.   
  57.         double tax= basetax[j] +   (double)taxrate[j]*(salary -lowerbound[j]);  
  58.       
  59.         cout<<tax<<endl;  
  60.     }  
  61.       
  62.     return 0;  
  63. }  

 

2、

  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. int main()  
  5. {  
  6.     int t=0;  
  7.     int i,k;  
  8.     int  n=10;  
  9.     int c[10]={1,2,3,4,5,6,7,8,9,10};  
  10.     int a[10]={0};  
  11.     for(k=1;k<n;++k)  
  12.     {  
  13.         for(i=1;i<k;++i)  
  14.             a[k] = a[k-i] * c [i];  
  15.   
  16.         a[k] +=c[k+1];  
  17.     }  
  18.     for(i=0;i<n;++i)  
  19.         cout<<a[i]<<endl;  
  20.       
  21.     return 0;  
  22. }  


3、当要输入数据很多,且没有规律时,可以考虑编写一个格式信函发生器(form letter generator)用于解析格式信函模板(form letter schema)。将数据从控制层分离的好处在于:避免每次针对不同的数据编写不同的代码;当需要改变一些公用文本的输出方式时,直接编辑模板即可,并不需要对数据进行修改

题目要求:输入一个字母,输出一个字符数组,该数组要以图像的方式将该字母的大写打印出来。
对于26个字母,每个字母的外形并没有必然规律可循,最直接方法是编写26个函数,针对特定的字母编写特定的打印程序,这是个体力活,代码数量将非常巨大。联想上面的格式信函编程,可以考虑为字母的外形设计一个定制模板,自己规定一套模板编写的格式,然后写一个解析程序,每次打印字母时,只需解析字母对应的模板即可,这样主要的工作量就花在每个字母模板的编写上,当然模板的编写是相当简单的,将字母图形转化为相应的模板格式即可。例如: 一个字母可以利用length = 12, width = 9的矩阵来表示


x x x x x x x x x
x x x x x x x x x
x x x x x x x x x
      x x x      
      x x x      
      x x x      
      x x x      
      x x x      
      x x x      
x x x x x x x x x
x x x x x x x x x
x x x x x x x x x
 
 
任何字母都可以在这张表示出来,每个点就像一个像素点。下面就对字母I和L进行模板编码,编码要求
 
(1)用尽可能简单的方式表示上面的图像;
(2)方便程序解析;
(3)必须适用于所有的情况
 
根据书上给出的编码结构,上图可表示为:
39x
63b3x3b
39x
 
编码规则: 第一列表示要打印的行数,,后面的数字代表每行要打印的字符个数,个数后面紧跟要打印的字符,并用空格隔开。这里字母b表示空格。根据上述规则,字母L编码如下
93x6b
39x
 
x x x            
x x x            
x x x            
x x x            
x x x            
x x x            
x x x            
x x x            
x x x            
x x x x x x x x x
x x x x x x x x x
x x x x x x x x
x

4、日期处理

这里把所有相关的处理函数放出来。

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4.   
  5. int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};   
  6. typedefstruct _date   
  7. {  
  8. int year, month, day;   
  9. }date;  
  10.   
  11. //看是否是闰年  
  12. int leap(int year)   
  13. {  
  14. return (0 == year % 4 && year % 100) || year % 400 == 0;   
  15. }  
  16.   
  17. //看是时间是否有效  
  18. int legal(date a)   
  19. {  
  20. if (a.month <0 || a.month > 12) return 0;   
  21. if (a.month == 2) return a.day > 0 && a.day <= (28 + leap(a.year));   
  22. return a.day >0 && a.day <= days[a.month -1];   
  23. }  
  24.   
  25.   
  26. //比较时间  
  27. int datecmp(date a, date b)   
  28. {  
  29. if (a.year != b.year) return a.year - b.year;   
  30. if (a.month != b.month) return a.month - b.month;   
  31. return a.day - b.day;   
  32. }  
  33.   
  34.   
  35. //计算周几?  
  36. int weekday(date a)   
  37. {  
  38. inttm = a.month >= 3 ? (a.month - 2) : (a.month + 10);   
  39. int ty = a.month >= 3 ? (a.year) : (a.year - 1);   
  40. return (ty + ty/4 - ty/100 + ty/400 + (int)(2.6 * tm - 0.2) + a.day) % 7;   
  41. }  
  42.   
  43. //时间化为天数  
  44. int date2int(date a)   
  45. {  
  46. int i ;   
  47. int ret = a.year * 365 + (a.year - 1) / 4 - (a.year -1) / 100 + (a.year - 1) / 400;   
  48. days[1] += leap(a.year);  
  49. for (i = 0; i a.month - 1; ret += days[i++]);   
  50. days[1] = 28;  
  51. return ret + a.day;   
  52. }  
  53.   
  54. //天数化为时间  
  55. date int2date(int a)   
  56. {  
  57. date ret;  
  58. int i = 0;   
  59. ret.year = a/146097*400;  
  60. for (a %= 146097; a >= 365+leap(ret.year);   
  61. -= 365 + leap(ret.year), ret.year++);  
  62. days[i] += leap(ret.year);  
  63. for (ret.month = 1; a >= days[ret.month - 1]; a -= days[ret.month - 1], ret.month++);  
  64. days[1] = 28;  
  65. ret.day = a + 1;  
  66. return ret;   
  67. }  
  68.   
  69. //计算距离  
  70. int dist(date a, date b)   
  71. {  
  72. int ad = date2int(a);   
  73. int bd = date2int(b);   
  74. return ad - bd > ? ad - bd : bd - ad;   
  75. }  
  76.   
  77.   
  78. //生成日历  
  79. void cal(date a)   
  80. {  
  81. int i, w, j, k;   
  82. a.day = 1;  
  83. if (a.month == 2) { k = days[a.month - 1] + leap(a.year);}   
  84. else k = days[a.month - 1];   
  85.   
  86. printf(" %2d月%4d年 \n", a.month, a.year);  
  87. printf("日 一 二 三 四 五 六\n");  
  88. w = weekday(a);  
  89. i = w % 7;while (i--) printf(" "); printf("%2d", 1);   
  90. if (w % 7 == 6) printf("\n"); ++w;   
  91.   
  92. for (i = 1; i <= k; ++i, w = (w + 1) % 7)   
  93. {  
  94. if (w % 7 == 0) printf("%2d", i);   
  95. else printf(" %2d", i);   
  96. if (w % 7 == 6) printf("\n");  
  97. }  
  98. }  



第5题,解法是hash表中带hash。第一个以ic, tic 等做hash

首先根据后缀找到hash_set,再把余下的字段,依次在hash_set中查找,并取出最长的。

  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<string>  
  4. #include<iterator>  
  5. #include<iostream>  
  6. #include<algorithm>  
  7. #include<hash_map>  
  8. #include<hash_set>  
  9.   
  10. usingnamespace std;   
  11. usingnamespace stdext;   
  12.   
  13. char *p[] = {"et-ic","al-is-tic","s-tic","p-tic","-lyt-ic","ot-ic","an-tic",  
  14. "n-tic","c-tic","at-ic","h-nic","n-ic","m-ic","l-lic","b-lic","-clic","l-ic",  
  15. "h-ic","f-ic","d-ic","-bic","a-ic","-mac","i-ac"};  
  16.   
  17.   
  18. void build_map(hash_map<string, hash_set<string>& dict)   
  19. {  
  20. constint n = sizeof(p)/sizeof(char *);   
  21. for (int i = 0; i n; ++i)   
  22. {  
  23. string line = p[i]; reverse(line.begin(), line.end());  
  24. int pos = line.find('-');  
  25. dict[line.substr(0, pos)].insert(line.substr(pos + 1, line.length() - pos - 1));   
  26. }  
  27. }  
  28.   
  29. string lookup(hash_map<string, hash_set<string>& dict, string word)   
  30. {  
  31. string line = word; reverse(line.begin(), line.end());  
  32. int pos = line.find('-');  
  33. string ret;  
  34.   
  35. hash_map<string, hash_set<string>::iterator iter;  
  36. if (dict.end() != (iter = dict.find(line.substr(0, pos))))   
  37. {  
  38. hash_set<string> &h = iter->second;  
  39. string temp = line.substr(pos + 1, line.length() - pos - 1);   
  40. for (int j = 1; j <= temp.length(); ++j)   
  41. {  
  42. string c = temp.substr(0, j);  
  43. if (h.find(c) != h.end() && c.length() > ret.length())   
  44. ret = c;  
  45. }  
  46. }  
  47. ret = iter->first +"-" + ret;  
  48. reverse(ret.begin(), ret.end());  
  49. return ret;   
  50. }  
  51. int main(void)  
  52. {  
  53. string sline;  
  54. hash_map<string, hash_set<string> dict;  
  55. build_map(dict);  
  56.   
  57. while (cin >> sline)   
  58. {  
  59. cout <lookup(dict, sline) <endl;  
  60. }  
  61. return 0;   
  62. }  


 


6、这个可以用python来写,下面先看一下示例代码。

模板文件/tmp/win03.domain.template

  1. [python] view plaincopy;SetupMgrTag  
  2. [Unattended]  
  3.   
  4. [GuiUnattended]  
  5. AdminPassword=${admin_password}  
  6. EncryptedAdminPassword=NO  
  7.   
  8. OEMSkipRegional=1  
  9.   
  10. [UserData]  
  11. ComputerName=${computer_name}  


 


代码

  1. [python] view plaincopyimport os   
  2.   
  3. Template =None  
  4. if Template isNone:  
  5. t = __import__('Cheetah.Template', globals(), locals(),   
  6. ['Template'], -1)  
  7. Template = t.Template  
  8.   
  9. fp = open('/tmp/unattend.xml','w')  
  10. tem = open('/tmp/win03.domain.template').read()  
  11. domain_list = {'computer_name':'computer',  
  12. 'admin_password':'admin',  
  13. 'Use':'Use'}  
  14. info = str(Template(tem, searchList=[domain_list]))  
  15. fp.write(info)  
  16. fp.close()  


如果采用C++实现,并且${}里面的代单词表明是要被替换的单词。那么处理方法如下:

  1. [python] view plaincopyvoid Template(char *fname, char *temp_fname, map<string, string>& dict)   
  2. {  
  3. ofstream output(fname);  
  4. ifstream temp(temp_fname);  
  5. string line;  
  6. while (getline(temp, line, '\n'))  
  7. {  
  8. int bpos =0;  
  9. string::size_type pos =0;  
  10. while (string::npos != (pos = line.find("${", bpos)))   
  11. {  
  12. string::size_type epos = line.find("}", pos);   
  13. string t = line.substr(pos +2, epos - pos -2);  
  14. cout << t <endl;  
  15. map<string, string>::iterator iter = dict.find(t);  
  16. if (dict.end() != iter)   
  17. {  
  18. line.replace(pos, epos - bpos +1, iter->second);  
  19. bpos += iter->second.length();  
  20. }  
  21. else  
  22. {  
  23. bpos = epos +1;  
  24. }  
  25. }  
  26. output <line <<"\n\r";  
  27. }  
  28. temp.close();  
  29. output.close();  
  30. }  



7、略去,比较扯

8、2^16 = 65536个数。所以5个七段显示器肯定是够用的。

因为最大的数 65535 有五位数。

    1. #include <iostream>  
    2. #include <memory>  
    3. using namespace std;  
    4.   
    5. void  showNumber(int i)  
    6. {  
    7.     int j=i;  
    8.     switch(j)  
    9.     {  
    10.         case 0:printf(" --\n");break;  
    11.         case 1:printf("|");break;  
    12.         case 2:printf("  |\n");break;  
    13.         case 3:printf(" --\n");break;  
    14.         case 4:printf("|");break;  
    15.         case 5:printf("  |\n");break;  
    16.         case 6:printf(" --\n");break;  
    17.         default :break;   
    18.     };  
    19. }  
    20. void  showNullNumber(int i)  
    21. {  
    22.     switch(i)  
    23.     {  
    24.         case 0:printf("\n");break;  
    25.         case 1:printf(" ");break;  
    26.         case 2:printf("   \n");break;  
    27.         case 3:printf("");break;  
    28.         case 4:printf(" ");break;  
    29.         case 5:printf("   \n");break;  
    30.         case 6:printf("\n");break;  
    31.         default :break;   
    32.     };  
    33. }  
    34.   
    35. void GraphFigure(int i)  
    36. {  
    37.     int show[7];  
    38.     int show0[]={1,1,1,0,1,1,1};  
    39.     int show1[]={0,1,0,0,1,0,0};  
    40.     int show2[]={1,0,1,1,1,0,1};  
    41.     int show3[]={1,0,1,1,0,1,1};  
    42.     int show4[]={0,1,1,1,0,1,0};  
    43.     int show5[]={1,1,0,1,0,1,1};  
    44.     int show6[]={1,1,0,1,1,1,1};  
    45.     int show7[]={1,0,1,0,0,1,0};  
    46.     int show8[]={1,1,1,1,1,1,1};  
    47.     int show9[]={1,1,1,1,0,1,1};  
    48.       
    49.       
    50.     switch(i)  
    51.     {  
    52.         case 0:memcpy(show,show0,sizeof(show));break;  
    53.         case 1:memcpy(show,show1,sizeof(show));break;  
    54.         case 2:memcpy(show,show2,sizeof(show));break;  
    55.         case 3:memcpy(show,show3,sizeof(show));break;  
    56.         case 4:memcpy(show,show4,sizeof(show));break;  
    57.         case 5:memcpy(show,show5,sizeof(show));break;  
    58.         case 6:memcpy(show,show6,sizeof(show));break;  
    59.         case 7:memcpy(show,show7,sizeof(show));break;  
    60.         case 8:memcpy(show,show8,sizeof(show));break;  
    61.         case 9:memcpy(show,show9,sizeof(show));break;  
    62.         default :break;   
    63.     };  
    64.     for(int i=0;i<7;++i)  
    65.     {  
    66.         if(1 == show[i])  
    67.             showNumber(i);  
    68.         else  
    69.             showNullNumber(i);  
    70.     }  
    71.   
    72. }  
    73. int main()  
    74. {  
    75.    for(int i=0;i<10;++i)  
    76.    {      
    77.        GraphFigure(i);  
    78.        cout<<"\n\n";  
    79.       
    80.    }  
    81.     return 0;  
posted on 2015-01-18 16:21  风云逸  阅读(751)  评论(0编辑  收藏  举报