寒假作业三
作业描述 | 作业详情
-|-|-
这个作业属于哪个课程 | 2020年面向对象程序设计
这个作业要求在哪 | 面向对象程序设计寒假作业3
这个作业的目的 | 1.继续完成编程题,优化架构 2.发布博客
作业正文 | 面向对象程序设计寒假作业3
其他参考文献 | 无
编程题(请使用C语言或者C++完成以下题目):
1.继续完成作业二的编程题。
2.优化架构,思考代码的拓展性,比如我需要增加其他功能,如选择,循环语句怎么办。
3.思考:可以参考现有的编程语言,把这些语言的内容加入。如选择、循环语句、函数、或者扩大数字范围,支持负数等。
编程题要求:
读题,提取出题目的要求。
分解需求,把需求分解为几个你觉得不太相关的模块。
思考每个模块怎么写,可以从简单的模块开始写。
对于不会的问题进行查阅资料。
对于每一个模块设计测试用例。
详细记录下以上每一步,并写在博客中。
不要求完全做出来,但要求记录详细。
建议博客长度不少于1000字(不包含代码)。
解释:
1.单元测试:对每一个函数进行测试,这代表了你需要把代码分到不同的文件,使用不同的主函数切换测试/运行。
2.编译脚本:运行该脚本后无需任何输入就能自动编译全部代码,并输出编译结束的代码。
3.测试脚本:运行该脚本后可以自动的编译并运行所有测试样例,并输出测试结果。
分解需求
主要有数字与汉字相互转化和汉字符号转化为计算符号的问题
优化架构
通过定义全局变量以及将程序以函数形式编译,当需要加入循环判断等过程时,只需要再编译一个函数并且调用之前的函数叠加解决问题。
思考
主要在扩大范围上,在单元测试后有观点。
单元测试
数字转汉字(扩大数字范围)
#include <stdio>
int nunber (int);
void wan (int);
void qian (int);
void bai (int,int);
void shi (int,int);
void ge (int,int);
void judge (int);
int main()
{printf("数字转汉字
");
freopen("数字转汉字.txt","r",stdin);
int num;
for(int j=1;j<=5;j++)//测五个测试点
{
scanf("%d",&num);
judge(num);
if(num==0){
printf("零");
}
printf("
");
}
}
void judge(int num)
{
if(num>9999)
{
wan(num);
}
else if(num>999)
{
qian(num);
}
else if(num>99)
{
bai(num,1);
}
else if(num>9)
{
shi(num,1);
}
else if(num>-1)
{
ge(num,1);
}
}
int number(int num)
{
if(num==1)
{printf("一");}
else if(num==2)
{printf("二");}
else if(num==3)
{printf("三");}
else if(num==4)
{printf("四");}
else if(num==5)
{printf("五");}
else if(num==6)
{printf("六");}
else if(num==7)
{printf("七");}
else if(num==8)
{printf("八");}
else if(num==9)
{printf("九");}
}
void wan(int num)
{
number(num/10000);
printf("万");
qian(num-10000*(num/10000));
}
void qian(int num)
{
if(num/1000==0)
{
bai(num-1000*(num/1000),0);
}
else
{
number(num/1000);
printf("千");
bai(num-1000*(num/1000),1);
}
}
void bai(int num,int zero)
{
if(num/100==0)
{
shi(num-100*(num/100),0);
}
else
{
if(ZERO_TRUE==zero) printf("零");
number(num/100);
printf("百");
shi(num-100*(num/100),1);
}
}
void shi(int num,int zero)
{
if(num/10==0){ge(num-10*(num/10),0);}
else
{
if(0==zero) printf("零");
number(num/10);
printf("十");
ge(num-10*(num/10),1);
}
}
void ge(int num,int zero)
{
if(num==0)
{
;
}
else
{
if(0==zero)printf("零");
number(num);
}
}
图片:
解题思路:
将输入的数字按照万位、千位、百位、十位、个位的顺序分别提取数字,即通过除10取余的方法提取出各个位上的数字,然后通过函数转换成零到九的汉字形式。按照汉字语法,在一到九的汉字后面加上十、百、千、万的字样,以此解决题目中的输入输出问题。当面对较大数时,只要运算未溢出,这种方法就能解决问题。
个人认为:
在数字转汉字的问题上,我扩大范围的方法其实与之前题目所需的条件的实现方法没有本质上的区别,但从另一种角度来说,这种方法的适用性较广,可以适用于较大范围内的数字转汉字的问题,有一定的可推广性。当然,我知道这种方法比较的简单直接,换句话说也比较麻烦,在万之后对于十万,百万,千万又要提出新的语言条件。我也希望我能够在之后的一些学习中能以更加优质的方法解决这列问题。
汉字转数字
首先是零到十的过程
#include<stdio.h>
#include<string.h>
int main()
{
char num[150];
int i;
freopen("汉字转数字1.0.txt","r",stdin);
for(i=1;i<=11;i++)
{
scanf("%s",num);
if(strcmp(num,"零")==0)
printf("0
");
else if(strcmp(num,"一")==0)
printf("1
");
else if(strcmp(num,"二")==0)
printf("2
");
else if(strcmp(num,"三")==0)
printf("3
");
else if(strcmp(num,"四")==0)
printf("4
");
else if(strcmp(num,"五")==0)
printf("5
");
else if(strcmp(num,"六")==0)
printf("6
");
else if(strcmp(num,"七")==0)
printf("7
");
else if(strcmp(num,"八")==0)
printf("8
");
else if(strcmp(num,"九")==0)
printf("9
");
else if(strcmp(num,"十")==0)
printf("10
");
}
}
图片:
扩展到有两个汉字的情况,即十几和整十
此时将上个主函数转化成函数应用于此程序
#include<stdio.h>
#include<string.h>
int number_a(char numb[150]);
int main()
{
char num[150],number[150];
int a,i;
freopen("汉字转数字2.0.txt","r",stdin);
for(i=1;i<=5;i++)//每次测五个点
{
scanf("%s",num);
strncpy(number,num+2,2);
num[2]=' ';
number[2]=' ';
if(number_a(num)==10)
a=10+number_a(number);
else
a=10*number_a(num);
if((a>=10&&a<=20)||(a%10==0&&a>20))
printf("%d
",a);
}
}
int number_a(char numb[150])
{
if(strcmp(numb,"零")==0)
return 0;
else if(strcmp(numb,"一")==0)
return 1;
else if(strcmp(numb,"二")==0)
return 2;
else if(strcmp(numb,"三")==0)
return 3;
else if(strcmp(numb,"四")==0)
return 4;
else if(strcmp(numb,"五")==0)
return 5;
else if(strcmp(numb,"六")==0)
return 6;
else if(strcmp(numb,"七")==0)
return 7;
else if(strcmp(numb,"八")==0)
return 8;
else if(strcmp(numb,"九")==0)
return 9;
else if(strcmp(numb,"十")==0)
return 10;
}
图片
再扩展到三个汉字的情况,即几十几(只要稍微改动上面的代码)
#include<stdio.h>
#include<string.h>
int number_a(char numb[150]);
int main()
{
char num[150],number[150];
int a,i;
freopen("汉字转数字3.0.txt","r",stdin);
for(i=1;i<=5;i++)//每次测五个点
{
scanf("%s",num);
strncpy(number,num+4,2);
num[2]=' ';
number[2]=' ';
if(number_a(num)==10)
a=10+number_a(number);
else
a=10*number_a(num);
if(a>20&&a<=99&&a%10!=0)
printf("%d
",a);
}
}
int number_a(char numb[150])
{
if(strcmp(numb,"零")==0)
return 0;
else if(strcmp(numb,"一")==0)
return 1;
else if(strcmp(numb,"二")==0)
return 2;
else if(strcmp(numb,"三")==0)
return 3;
else if(strcmp(numb,"四")==0)
return 4;
else if(strcmp(numb,"五")==0)
return 5;
else if(strcmp(numb,"六")==0)
return 6;
else if(strcmp(numb,"七")==0)
return 7;
else if(strcmp(numb,"八")==0)
return 8;
else if(strcmp(numb,"九")==0)
return 9;
else if(strcmp(numb,"十")==0)
return 10;
}
图片:
解题思路:
这道题我的解法其实就是利用原先的程序,将其写成函数后多次运用于新的函数,在已知汉字字数的情况下,利用跳过汉字再判断,得到应有位的数字后再将其乘上10,使其达到该位的应有数字,再与其他位的数字相加,得到最终的数字。最后,为防止输出出错,我在最后加入验证数字范围的判断条件,进一步保证输出结果的正确性。
个人认为:
这道题我的解法在一定程度上拓展了范围,但是再拓展下去有一定的麻烦,例如如果拓展到三位数的情况,一百一十一,有5个字,要跳过2,4字;一百五十,有4个字,要跳过2,4字;一百零五,有四个字,要跳过2,3字;五百,只有2个字,要跳过第2字;综上,三位数一共有4种情况,相较于一位数1种情况,两位数3种情况,数量有一定的增多,即随着位数的增加,情况在不断的增多。
改进措施:
我首先想到用strlen函数测量汉字的长度,再通过验证第二位汉字得到最高位,但由于存在例如一千零九十九和一千一百五十,故此法不可行;进而我认为可以通过逐位判断的方法判断规律,在此条件下,我把零看作一个标志。其流程是:首先用strlen测量长度,得到循环次数,判断第一二位汉字得到最高位与最高位数字,接着判断第三位汉字,如果第三位汉字是零则跳一位,如果第三位是数字则跳两位,以此类推,并且,在碰到零跳一位后,还要判断再后一位的汉字以确定位数,而当始终未遇见零则不需要判断位。
加减乘除
#include<stdio.h>
#include<string.h>
int add(int num,char ope[100],int cha_num);//处理加减乘除转化
int main()
{
char fuhao[150];
int x,y,i,s;
freopen("加减乘除.txt","r",stdin);
for(i=1;i<=4;i++)//加减乘除四个测试点
{
scanf("%d %s %d",&x,fuhao,&y);
if(strcmp(fuhao,"增加")==0)
s=x+y;
if(strcmp(fuhao,"减少")==0)
s=x-y;
if(strcmp(fuhao,"乘以")==0)
s=x*y;
if(strcmp(fuhao,"除以")==0)
s=x/y;
printf("%d
",s);
}
return 0;
}
图片:
解题思路:这条代码我没有什么简化思路,只能单纯把加减乘除汉字换成运算符号使用。
ps结语:
之前的作业总是在截止时间过后才做完,来不及上交,希望这次的完成都可以达标。(>.<)