这个作业属于哪个课程 | 2020面向对象程序设计张栋班 |
---|---|
这个作业要求在哪里 | 面向对象程序设计寒假作业3 |
这个作业的目标 | 继续完成作业二的编程题。 实现二位数和负数的处理。 |
作业正文 | -- |
其他参考文献 | https://www.cnblogs.com/fnlingnzb-learner/p/5964298.html |
-
编程题
- 继续完成作业二的编程题。
- 优化架构,思考代码的拓展性,比如我需要增加其他功能,如选择,循环语句怎么办。
- 思考:可以参考现有的编程语言,把这些语言的内容加入。如选择、循环语句、函数、或者扩大数字范围,支持负数等。
最初代码的局限性:1.不能输入大于十的汉字。 2.最终输出的结果范围仍在0-99内。
上一次优化解决了连续表达式的输入,这次主要解决输入二位数以及负数的问题。
参考同学的代码后,改用全局变量的二维数组存储汉字,使代码更简洁。
char number[15][5]={"零","一","二","三","四","五","六","七","八","九","十"};
于是单个汉字转换成数字的函数可改为
int translate(char x[]){ for(int i=0;i<=10;i++){ if(strcmp(x,number[i])==0){ return(i); break; } } }
现在要优化的是支持输入二位数。
二位数要转换成数字不能直接调用上述translate函数,要再定义一个int型的change函数,把个位数和十位数拆开利用translate转换再进行运算。在网上了解到了复制字符片段的函数strncpy,现在分几种情况考虑处理方法。
一个汉字长度为2,故可用strlen函数判断输入的类型。
若输入的是一位数或十,直接用translate转换。
若输入的是“五十”这类的整十数或11-19之间的数,则长度为4,这里定义一个变量shi数组存储十位数。比如截取“五十”的“五”赋给shi。
strncpy(shi,x,2); shi[2]='\0'; if(strcmp(shi,"十")==0) //11-19之间 return(translate(x+2)+10); else //大或等于20的整十数 return(translate(shi)*10);
若输入的是“五十二”这类一般的二位数,则进行以下处理:
strncpy(shi,x,2); shi[2]='\0'; return(translate(shi)*10+translate(x+4));
完整的change函数,该函数能实现二位数的输入,返回的是该二位数对应的数字:
int change(char x[]){ char shi[5]; if(strlen(x)==2) return(translate(x)); else if(strlen(x)==4){ strncpy(shi,x,2); shi[2]='\0'; if(strcmp(shi,"十")==0) //11-19之间 return(translate(x+2)+10); else //大或等于20的整十数 return(translate(shi)*10); } else if(strlen(x)==6){ strncpy(shi,x,2); shi[2]='\0'; return(translate(shi)*10+translate(x+4)); } }
对change函数进行测试:
char number[15][5]={"零","一","二","三","四","五","六","七","八","九","十"}; int translate(char x[]){ for(int i=0;i<=10;i++){ if(strcmp(x,number[i])==0){ return(i); break; } } } int change(char x[]){ char shi[5]; if(strlen(x)==2) return(translate(x)); else if(strlen(x)==4){ strncpy(shi,x,2); shi[2]='\0'; if(strcmp(shi,"十")==0) //11-19之间 return(translate(x+2)+10); else //大或等于20的整十数 return(translate(shi)*10); } else if(strlen(x)==6){ strncpy(shi,x,2); shi[2]='\0'; return(translate(shi)*10+translate(x+4)); } } int main(){ for(int i=1;i<=10;i++){ char a[100]; scanf("%s",a); printf("%d\n",change(a)); } return 0; }
接下来优化输出函数print_sum,使其能输出负数。
根据其本身的正负决定要不要加“负”,然后取其绝对值进行后续操作。
分成小或等于十,十到二十之间(中文没有“一十几”这种习惯),大或等于二十的整十数(中文没有“几十零”这种习惯)和大或等于二十的非整十数四类进行处理
void print_sum(int a){ if(a<0)printf("负"); int x=abs(a); if(x<=10) printf("%s",number[x]); else if(x>10&&x<20) printf("十%s",number[x%10]); else{ if(x%10==0) printf("%s十",number[x/10]); else printf("%s十%s",number[x/10],number[x%10]); } printf("\n");
测试print_sum函数:
char number[15][5]={"零","一","二","三","四","五","六","七","八","九","十"}; void print_sum(int a){ if(a<0)printf("负"); int x=abs(a); if(x<=10) printf("%s",number[x]); else if(x>10&&x<20) printf("十%s",number[x%10]); else{ if(x%10==0) printf("%s十",number[x/10]); else printf("%s十%s",number[x/10],number[x%10]); } printf("\n"); } int main(){ for(int i=1;i<=10;i++){ int a; scanf("%d",&a); print_sum(a); } return 0; }
完整代码:
#include#include<string.h> #include char number[15][5]={"零","一","二","三","四","五","六","七","八","九","十"}; int translate(char x[]){ for(int i=0;i<=10;i++){ if(strcmp(x,number[i])==0){ return(i); break; } } } int change(char x[]){ char shi[5]; if(strlen(x)==2) return(translate(x)); else if(strlen(x)==4){ strncpy(shi,x,2); shi[2]='\0'; if(strcmp(shi,"十")==0) //11-19之间 return(translate(x+2)+10); else //大或等于20的整十数 return(translate(shi)*10); } else if(strlen(x)==6){ strncpy(shi,x,2); shi[2]='\0'; return(translate(shi)*10+translate(x+4)); } } void print_sum(int a){ if(a<0)printf("负"); int x=abs(a); if(x<=10) printf("%s",number[x]); else if(x>10&&x<20) printf("十%s",number[x%10]); else{ if(x%10==0) printf("%s十",number[x/10]); else printf("%s十%s",number[x/10],number[x%10]); } printf("\n"); } int main() { char flag[10],money[10],symbol[10],a[10],b[10],c[10],d[10],shi[5]; int sum; scanf("%s%s%s%s",a,b,c,d); sum=change(d); scanf("%s",flag); while(1){ if(strcmp(flag,b)==0){ scanf("%s%s",symbol,money); if(strcmp(symbol,"增加")==0) sum+=change(money); else sum-=change(money); scanf("%s",flag); } else if(strcmp(flag,"看看")==0){ scanf("%s",b); print_sum(sum); scanf("%s",flag); } else if(strcmp(flag,"结束")==0) //这里改了一下,以“结束”终止程序,输入“看看”后仍可进行加减 break; else{ scanf("%s",money); if(strcmp(flag,"增加")==0) sum+=change(money); else sum-=change(money); scanf("%s",flag); } } return 0; }
测试结果如下:
再测试一组时就发现了问题:初始化不能为负数,且增加减少的值也不能为负。
出现这个问题的原因是change函数,中文转换成数字时没考虑正负。这个问题暂时还没想好处理方法= =
因为不知道怎么将字符串中间的一部分截取出来。
比如“负五十二”,我不知道要怎么提取出“五”;但如果是“五十二”,我就可以用strncpy函数提取出字符串头部的“五”。
总结
这次优化后程序支持负数的输出,支持二位数的输入。但仍有较大的局限性:比如数值范围仍在一百以内,不能输入负数,代码很长等。
希望在以后的学习中能够解决这些问题,提高解决问题的能力。