这个作业属于哪个课程 2020面对对象程序设计张栋
这个作业要求在哪里 面对对象程序设计寒假作业3
这个作业的目标 对代码进行优化
其他参考文献 strstr函数
  • 对作业要求的思考

本次作业描述中提到对代码所能提供的数据范围要求扩大,一种是能够满足的数据数位增多,另一种是令代码满足负数输入并计算的要求。
对此,我仔细看了我原来的代码,发现原来的代码函数虽然能满足二位数的计算,却没办法满足二位数乃至更大数据的转换...
以下是原代码关于中文转化成数字的函数

int chinese(char *c)
{
	char a[10];
	strcpy(a,c);
	if(!strcmp(a,"一"))return 1;
	else if(!strcmp(a,"二"))return 2;
	else if(!strcmp(a,"三"))return 3;
	else if(!strcmp(a,"四"))return 4;
	else if(!strcmp(a,"五"))return 5;
	else if(!strcmp(a,"六"))return 6;
	else if(!strcmp(a,"七"))return 7;
	else if(!strcmp(a,"八"))return 8;
	else if(!strcmp(a,"九"))return 9;
	else if(!strcmp(a,"十"))return 10;
	else return 0;	
}

而负数方面的数据我就更没有去考虑...

  • 对代码的改变

仔细思考了一波,感觉我将汉字字符串转化成阿拉伯数字,存入某个变量后进行计算再转化成汉字字符串输出的总体思路应该没啥毛病
然后我想了下如何去改变转化函数的问题,毕竟只是能实现零到十的转化对之后的计算有挺大麻烦的
以下是我转化数据进行计算的原代码

if(!strcmp(cal,"增加")&&strncmp(&num[2],&s[15],4)>=0)
		{
			strncpy(d,num,2);
			purse=purse+chinese(&d[0])*10+chinese(&num[4]);
		}
		else if(!strcmp(cal,"增加")&&strncmp(&num[2],&s[15],4)<0)
		purse=purse+chinese(&num[0]);
		else if(!strcmp(cal,"减少")&&strncmp(&num[2],&s[15],4)>=0)
		{	strncpy(d,num,2);
			purse=purse-chinese(&d[0])*10-chinese(&num[4]);
		}
		else 
			purse=purse-chinese(&num[0]);

这样的代码如果出了问题,改都改得吐血,这又坚定了我去改转化函数的决心...
我打算从数据是几位数来判断,用一定的四则运算转化数据,我先是了解了strstr函数,又发现了if与else if的一个性质,本来知道switch函数有这个性质,但switch语句在c中用不了字符串...经过了两次实验,我利用这个性质让函数优先判断出数据的最高位

        if(strstr(a,"万"))
	ins=10000;
	else if(strstr(a,"千"))
	ins=1000;
	else if(strstr(a,"百"))
	ins=100;
	else if(strstr(a,"十"))
	ins=10; 

	if(strstr(a,"万"))
	ins=10000;
	else if(strstr(a,"百"))
	ins=100;
	else if(strstr(a,"千"))
	ins=1000;
	else if(strstr(a,"十"))
	ins=10; 

在这之后,我又用了之前代码中对零到九的转换代码,并入这次的代码中

for(int i=ins,j=0,k;i!=0;i=i/10){
		strncpy(b,&a[j],2);
		if(strstr(b,"负")){
			q=-1;
			j=j+2;i=i*10;
			continue;
		}
		if(strstr(b,"一")) k=1;
		else if(strstr(b,"二")) k=2;
		else if(strstr(b,"三")) k=3;
		else if(strstr(b,"四")) k=4;
		else if(strstr(b,"五")) k=5;
		else if(strstr(b,"六")) k=6;
		else if(strstr(b,"七")) k=7;
		else if(strstr(b,"八")) k=8;
		else if(strstr(b,"九")) k=9;
		else if(strstr(b,"十")) k=10;
		else k=0;
		if(strstr(b,"零"))
		j=j+2;
		else
		j=j+4;	
		d=d+i*k;
	}
	d=d*q;

这其中需要注意的就是对零的判断

一千零九十三
一千四百九十五
在汉字语法中一个数位上的数字是零只用一个零就可以带过,而如果不是零的话,需要描述数位及数位上数字的大小,例如一千四百九十五中的四百

然后考虑更大的范围

以下是上述例子的代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
	int ins,d=0,q=1;
	char a[20],b[20];
	scanf("%s",a);
	if(strstr(a,"万"))
	ins=10000;
	else if(strstr(a,"千"))
	ins=1000;
	else if(strstr(a,"百"))
	ins=100;
	else if(strstr(a,"十"))
	ins=10; 
	for(int i=ins,j=0,k;i!=0;i=i/10){
		strncpy(b,&a[j],2);
		if(strstr(b,"负")){
			q=-1;
			j=j+2;i=i*10;
			continue;
		}
		if(strstr(b,"一")) k=1;
		else if(strstr(b,"二")) k=2;
		else if(strstr(b,"三")) k=3;
		else if(strstr(b,"四")) k=4;
		else if(strstr(b,"五")) k=5;
		else if(strstr(b,"六")) k=6;
		else if(strstr(b,"七")) k=7;
		else if(strstr(b,"八")) k=8;
		else if(strstr(b,"九")) k=9;
		else if(strstr(b,"十")) k=10;
		else k=0;
		if(strstr(b,"零"))
		j=j+2;
		else
		j=j+4;	
		d=d+i*k;
	}
	d=d*q;
	printf("%d %d\n",d,ins);
	for(int i=ins,j=0,k=d;i!=0;i=i/10){
		if(k<0){
			k=-k;
			printf("负"); 
		}
		switch(k/i)
		{
			case 1:printf("一");break; 
			case 2:printf("二");break;
			case 3:printf("三");break;
			case 4:printf("四");break;
			case 5:printf("五");break;
			case 6:printf("六");break;
			case 7:printf("七");break;
			case 8:printf("八");break;
			case 9:printf("九");break;
			case 0:printf("零");break; 
		}
		if(k/i==0)
		continue;
		switch(i){
			case 10000:printf("万");break;
			case 1000:printf("千");break;
			case 100:printf("百");break; 
			case 10:printf("十");break;
		}
		k=k-i*(k/i);
	}
	return 0;
} 

将改变后的函数放入入原代码中

#include<stdio.h>
#include<string.h>
#include<math.h>
int main()
{
	int chinese(char *c);
	void arab(int n);
	int purse; 
	char s[50],a[5]="钱包",cal[10],num[20];
	gets(s);
	purse=chinese(&s[15]);
	printf("%d\n",purse);
	while(strcmp(a,"钱包")==0){
		scanf("%s",a);
		scanf("%s",cal);
		if(!strcmp(a,"看看"))break;
		scanf("%s",num);
		if(!strcmp(cal,"增加"))
			purse=purse+chinese(&num[0]);
		else
			purse=purse-chinese(&num[0]);
		printf("%d\n",purse); 
	}
	arab(purse);
	return 0; 
}
int chinese(char *c)
{
	int degree(char a[25]);
	int ins,d,q=1;
	char a[20],b[20];
	strcpy(a,c);
	ins=degree(a);
	for(int i=ins,j=0,k;i!=0;i=i/10){
		strncpy(b,&a[j],2);
		if(strstr(b,"负")){
			q=-1;
			j=j+2;i=i*10;
			continue;
		}
		if(strstr(b,"一")) k=1;
		else if(strstr(b,"二")) k=2;
		else if(strstr(b,"三")) k=3;
		else if(strstr(b,"四")) k=4;
		else if(strstr(b,"五")) k=5;
		else if(strstr(b,"六")) k=6;
		else if(strstr(b,"七")) k=7;
		else if(strstr(b,"八")) k=8;
		else if(strstr(b,"九")) k=9;
		else if(strstr(b,"十")) k=10;
		else k=0;
		if(strstr(b,"零"))
		j=j+2;
		else
		j=j+4;	
		d=d+i*k;
	}	
	d=d*q;
	return d;
}
void arab(int n) 
{
	int ins,k=0;
	for (int i=n;i!=0;i=i/10)
	k++;
	ins=pow(10,k-1);
	for(int i=ins,j=0,k=n;i!=0;i=i/10){
		if(k<0){
			k=-k;
			printf("负"); 
		}
		switch(k/i)
		{
			case 1:printf("一");break; 
			case 2:printf("二");break;
			case 3:printf("三");break;
			case 4:printf("四");break;
			case 5:printf("五");break;
			case 6:printf("六");break;
			case 7:printf("七");break;
			case 8:printf("八");break;
			case 9:printf("九");break;
			case 0:printf("零");break; 
		}
		if(k/i==0)
		continue;
		switch(i){
			case 10000:printf("万");break;
			case 1000:printf("千");break;
			case 100:printf("百");break; 
			case 10:printf("十");break;
		}
		k=k-i*(k/i);
	}
}
int degree(char a[25]){
	int ins;
	if(strstr(a,"万"))
	ins=10000;
	else if(strstr(a,"千"))
	ins=1000;
	else if(strstr(a,"百"))
	ins=100;
	else if(strstr(a,"十"))
	ins=10;
	return ins; 
}

结果



然后的话我考虑了下到十万乃至百万的情况...到了这个数位又要对百万十万进行特别判断,在汉语语法中百万其实是涵盖了百万,十万和万三个数位,甚至还要拆开例如五百九十七万...

五百万六千七百八十九
六千七百八十九
5006789
6789
到这里的话数据范围有点扩不下去了...
负数范围我在扩范围的时候顺便加进去了...对负进行判断,像零那样处理