这个作业属于哪个课程 | 2020面向对象程序设计张栋班 |
---|---|
这个作业要求在哪里 | 面向对象程序设计寒假作业2 |
这个作业的目标 | 改进作业1中的代码 |
其他参考文献 | 无 |
改进作业1(编程题)中的代码
- 1、添加使用说明如下
欢迎使用,请按以下要求输入:
1.该程序仅支持两位数以内数字输入,计算结果也应保证在两位数范围内
2.在程序第一行应定义变量,遵循如下格式(整数 定义变量名 等于 定义数字)
3.输入数字请遵循以下规范:
(1~9):一~~九、
(11~19):十一~~十九、
(21~29、31~39、···):二十一~~二十九、三十一~~三十九、···
(10的倍数):十、二十、三十、···
4.变量增加减少请按照(定义变量名 增加/减少 数字)进行
5.查看变量结束程序请按如下格式(看看 定义变量名)
- 2、精简函数,考虑到需求是每个调用的函数尽量在15行以内,所以本次改进依然不考虑添加三位数计算的功能
- 首先对于以下代码,我拆分出汉字对比的功能,单独再列出一个
hz_judge
函数
- 首先对于以下代码,我拆分出汉字对比的功能,单独再列出一个
int hz_judge(char* str){
int i;
for(i=0;i<11;i++){
if(strcmp(str,hz[i])==0){
return i;
}
}
}
- 这里发现一个bug,在作业一中我写在注释里,现在再写一遍:如下代码:
int hz_to_num(char* str)
{
char a[10],b[10];
int len,i,j;
len=strlen(str);
if(len==4){
a[0]=str[0];
a[1]=str[1];
b[0]=str[2];
b[1]=str[3];
b[2]=0;//就是这边
if(strcmp(a,hz[10])==0){
return hz_judge(b)+10;
}
else{
return hz_judge(a)*10;
}
}
else if(len==6){
a[0]=str[0];
a[1]=str[1];
b[0]=str[4];
b[1]=str[5];
b[2]=0;//就是这边
return hz_judge(a)*10+hz_judge(b);
}
else if(len==2){
a[0]=str[0];
a[1]=str[1];
return hz_judge(a);
}
}
我需要在每一个b[1]=···后面补加一个b[2]=0才可正确识别汉字,否则会出现一些非常奇怪的东西。我目前怀疑是内存分配出了问题,还没有在别人电脑上试过。
- 这里我已经尽力简化代码,把关键代码尽量缩短到十五行以内,但是hz_to_num
函数还是超过十五行,我认为目前瓶颈在于将汉字的两个字节拆分开需要耗费四行代码,但是在还没学习到更好函数或者思想的前提下,这个问题很难得到解决,尽管可以通过将此方法再次拆分成函数,但是我认为治标不治本,而且考虑到题目所写的“一般”,所以也算勉强达到要求。
- 3、报错提醒:
- 首先在主函数中优化,加上错误提示如下:
- 输入错误!(应输入:等于 ~)
- 错误,请先定义变量!(应输入:整数 ~)
- 输入名称错误!(请输入:定义变量名)
- 输入名称错误!(请输入:定义变量名 或 看看)
- 其次,需要考虑输入数字如果不规范的检查方法,这里我思考许久,我认为首先应从规范数字输入下手,想到两种方法:一种是在
hz_to_num
中在计算对应数字值的时候进行判断格式是否错误,但是考虑到需求要求函数在十五行以内完成,我本来就超标,所以这个方法废弃;另一种是再写一个函数来对输入字符串中的每两位作判断,如满足要求,输入字符串的规范应在(零~十)内,但是这无法对整体进行判断,对此,我还需要考虑格式规范,以及如果格式不规范提示,我在hz_judge
中添加return -1
语句,用来判断如果中不存在十个数,方便报错处理,同样分三种情况,即长度为2、4、6时的对应情况,直接贴出代码:
- 首先在主函数中优化,加上错误提示如下:
int type_judge(char* num)
{
char a[10],b[10];
int len=strlen(num);
if(len==2){
if(hz_judge(num)==-1){
return 0;
}
}
else if(len==4)
{
a[0]=str[0];
a[1]=str[1];
b[0]=str[2];
b[1]=str[3];
b[2]=0;
if(strcmp(a,hz[10])!=0&&strcmp(b,hz[10])!=0){
return 0;
}
}
else if(len==6){
a[0]=str[0];
a[1]=str[1];
b[0]=str[2];
b[1]=str[3];
b[2]=0;
//回头发现不对
}
else{
return 0;
}
}
我这不是又写了一个和hz_to_num
函数相似的函数吗???,既然没有更好的方案,那么我就只好牺牲hz_to_num
函数,让他更长了。所以我直接在函数中加判断,如果结果不正确则返回-1,然后在主函数中再次添加判断,给出错误,下面给出代码:
int hz_to_num(char* str)
{
char a[3],b[3],c[3];
int len,i,j;
len=strlen(str);
if(len==4){
a[0]=str[0];
a[1]=str[1];
a[2]=0;
b[0]=str[2];
b[1]=str[3];
b[2]=0;
if((strcmp(a,hz[10])!=0&&strcmp(b,hz[10])!=0)||(strcmp(a,hz[10])==0&&strcmp(b,hz[10])==0)){
return -1;
}
else if(strcmp(a,hz[10])==0){
return hz_judge(b)+10;
}
else{
return hz_judge(a)*10;
}
}
else if(len==6){
a[0]=str[0];
a[1]=str[1];
a[2]=0;
c[0]=str[2];
c[1]=str[3];
c[2]=0;
b[0]=str[4];
b[1]=str[5];
b[2]=0;
if(strcmp(a,hz[1])==0||strcmp(c,hz[10])!=0||hz_judge(a)==-1||hz_judge(b)==-1){
return -1;
}
return hz_judge(a)*10+hz_judge(b);
}
else if(len==2){
if(hz_judge(str)==-1){
return -1;
}
return hz_judge(str);
}
}
- 小结:以上完成了对作业1(编程题)编程题的优化,但是仍然达到三位数计算的可行性,希望日后有望改进。下面附上代码以及测试数据:
#include<stdio.h>
#include<string.h>
char hz[11][10]={"零","一","二","三","四","五","六","七","八","九","十"};
char keywords[5][20]={"整数","等于","增加","减少","看看"};
int hz_judge(char* str){
int i;
for(i=0;i<11;i++){
if(strcmp(str,hz[i])==0){
return i;
}
}
return -1;
}
int calculate(int num,char* command,char* number){
int n;
if(strcmp(command,keywords[2])==0){
n=hz_to_num(number);
return num+=n;
}
else if(strcmp(command,keywords[3])==0){
n=hz_to_num(number);
return num-=n;
}
else{
return -1;
}
}
int hz_to_num(char* str)
{
char a[3],b[3],c[3];
int len,i,j;
len=strlen(str);
if(len==4){
a[0]=str[0];
a[1]=str[1];
a[2]=0;
b[0]=str[2];
b[1]=str[3];
b[2]=0;
if((strcmp(a,hz[10])!=0&&strcmp(b,hz[10])!=0)||(strcmp(a,hz[10])==0&&strcmp(b,hz[10])==0)){
return -1;
}
else if(strcmp(a,hz[10])==0){
return hz_judge(b)+10;
}
else{
return hz_judge(a)*10;
}
}
else if(len==6){
a[0]=str[0];
a[1]=str[1];
a[2]=0;
c[0]=str[2];
c[1]=str[3];
c[2]=0;
b[0]=str[4];
b[1]=str[5];
b[2]=0;
if(strcmp(a,hz[1])==0||strcmp(c,hz[10])!=0||hz_judge(a)==-1||hz_judge(b)==-1){
return -1;
}
return hz_judge(a)*10+hz_judge(b);
}
else if(len==2){
if(hz_judge(str)==-1){
return -1;
}
return hz_judge(str);
}
}
int num_to_hz(int num){
if(num>=10){
if(num%10==0){
if(num==10){
printf("%s
",hz[10]);
}
else{
printf("%s%s
",hz[num/10],hz[10]);
}
}
else{
if(num<20){
printf("%s%s
",hz[10],hz[num%10]);
}
else{
printf("%s%s%s
",hz[num/10],hz[10],hz[num%10]);
}
}
}
else{
printf("%s
",hz[num]);
}
}
int main(){
printf("欢迎使用,请按以下要求输入:
1.该程序仅支持两位数以内数字输入,计算结果也应保证在两位数范围内且不为负数
2.在程序第一行应定义变量,遵循如下格式(整数 定义变量名 等于 定义数字)
3.输入数字请遵循以下规范:
(1~9):一~~九、
(11~19):十一~~十九、
(21~29、31~39、···):二十一~~二十九、三十一~~三十九、···
(10的倍数):十、二十、三十、···
4.变量增加减少请按照(定义变量名 增加/减少 数字)进行
5.查看变量结束程序请按如下格式(看看 定义变量名)
");
char name[20],command[100][20];
int i=0,target;
scanf("%s",command[i++]);
if(strcmp(command[i-1],keywords[0])==0){
scanf("%s",name);
scanf("%s",command[i++]);
if(strcmp(command[i-1],keywords[1])==0){
scanf("%s",command[i++]);
target=hz_to_num(command[i-1]);
if(target==-1){
printf("数字格式出错,请参考要求第2点");
return 0;
}
}
else{
printf("输入错误!(应输入:等于 ~)
");
return 0;
}
}
else{
printf("错误,请先定义变量!(应输入:整数 ~)
");
return 0;
}
while(1){
scanf("%s",command[i++]);
if(strcmp(command[i-1],keywords[4])==0){
scanf("%s",command[i++]);
if(strcmp(command[i-1],name)==0){
num_to_hz(target);
return 0;
}
else{
printf("输入名称错误!(请输入:定义变量名)
");
return 0;
}
}
else if(strcmp(command[i-1],name)==0){
scanf("%s",command[i++]);
scanf("%s",command[i++]);
if(hz_to_num(command[i-1])==-1){
printf("数字格式出错,请参考要求第2点");
return 0;
}
if(calculate(target,command[i-2],command[i-1])==-1){
return 0;
}
else{
target=calculate(target,command[i-2],command[i-1]);
}
}
else{
printf("输入名称错误!(请输入:定义变量名 或 看看)
");
return 0;
}
}
}