面向对象程序设计寒假作业2编程题
这个作业属于哪个课程 | 2020面向对象程序设计张栋班 |
这个作业要求在哪里 | 面向对象程序设计寒假作业2 |
这个作业的目标 | 改进作业1中的代码 |
这个作业的地址 | 点这里 |
其他参考文献 | 无 |
1.在草稿上写了一些小于9位的中文数字,寻找规律:
{
1.在没有0出现的情况下:如 9千 9百 9十 9 万 9千 9百 9十 9;
数字展现了绝妙的规律:数字加位数。。数字加位数。。数字加位数。。。。(除了个位的位数忽略和中间插入‘万’)
于是想到通过判断每个单位及前面的数字大小,来得到num的大小;
2.在只有一个0出现的情况下:
1.0出现在个位:如 9千9百9十9 万 9千9百9十9
--> 9千9百9十9 万 9千9百9十
去掉个位,需特殊考虑
2.0在其他位置:如 9千9百9十9 万 9千9百9十9
--> 9千 零 9十9 万 零 9百 零 9
将该位置的数字和单位 - > 零
3.在多个0出现的情况下:
1.个位不为零:如 9千9百9十9 万 9千9百9十9
--> 9千 零 9 万 零 9百 零 9
多个零连在一起时合并为一个零
2.个位为零:如 9千9百9十9 万 9千9百9十9
--> 9千 零 9 万 零 9百
去掉个位的同时,个位之前若有零,也要去掉
4.十作汉字开头省略一,需特殊考虑:(一)十五,二十五,(一)十万,二十万
}
2.将汉字转化为数字的具体思路
{
定义整型变量 a=0;
每找到一个单位:a+=单位前数字*单位;
单位为 万 时特殊:a+=单位前数字;a*=10000;
单位为 十 时特殊:若十作为汉字开头,十前数字默认为1;
因为个位没单位,最后加上个位;
个位为0时汉字省略了零,不需要加上个位;
}
3.汉字的ASCII编码占2位,以下是所需每个汉字的ASCII
{
十:-54,-82;
百:-80,-39;
千:-57,-89;
万:-51,-14; 虽然汉字的ASCII编码占两位,
零:-63,-29; 但左侧所有汉字ASCII码第二位各不相等,
一:-46,-69; 所以可通过i=1;i+=2的方式来查看每个汉字
二:-74,-2;
三:-56,-3;
四:-53,-60;
五:-50,-27;
六:-63,-7;
七:-58,-33;
八:-80,-53;
九:-66,-59;
}
以下是将汉字转化为数字的函数:
char s1[21]="零一二三四五六七八九";
//将单个中文转化为数字
int shu_to_num(char c)
{
for(j=1;s1[j-1]!=0&&c!=s1[j];j+=2){}
return j==21?-1:(j-1)/2;
}
//将一亿以内的中文转化为数字
int hz_to_num(char s[])
{
int num=0;
for(i=1;s[i-1]!=0;i+=2)
switch(s[i])
{
case -82:num+=i>1?shu_to_num(s[i-2])*10:10;break;
case -39:num+=shu_to_num(s[i-2])*100;break;
case -89:num+=shu_to_num(s[i-2])*1000;break;
case -14:num+=shu_to_num(s[i-2])==-1?0:shu_to_num(s[i-2]);num*=10000;break;
}
return shu_to_num(s[i-2])==-1?num:num+shu_to_num(s[i-2]);
}
注:主体是 hz_to_num函数;shu_to_num函数本身无意义;
以下是函数的测试用例:
/******************************************************************************************************/
/******************************************************************************************************/
零 一 二 三 四 五 六 七 八 九 十
十一 十二 十三 十四 十五 十六 十七 十八 十九 二十
三十一 四十二 五十三 九十七 一百
一百零六 二百七十九 五百八十 九百零三
一千 一千零一 一千一百 一千零二十 一千一百零六
八千七百 九千零一十六 一万 一万零一 一万零一十
一万零八百零六 一万零九百 一万一千 一万九千零二十
九万八千六百三十四 十万零六百 十万零六百零一
十万九千八百零五 一百一十七万八千 九百万 九百零一万零一
一千万 一千零四十万零三百二十六 八千七百一十三万零五十二
九千九百九十九万九千九百九十九
/******************************************************************************************************/
/******************************************************************************************************/
以下是函数的测试结果:
4.将数字转化为汉字的具体思路
{
设置一个字符串,使整数每一位的单位与其一一对应
记录数字的总位数j;当前位数k=j,k--;当前位置的数字i;
位数为 1 时特殊:该位为0时判断总位数j,j = =1才能输出零;
位数为 6||2 时特殊:若1作为数字开头,不输出一;
位数为 1 时特殊:不输出单位 - >该位置停止即可;
出现0时,跳过直到 下一个不为0的位||位数为1,
若跳过后该位不为0,中间补上一个零
}
以下是将数字转化为汉字的函数:
char s2[19]=" 个十百千万十百千";
//将一亿以内的数字转化为中文输出
void num_to_hz(int num) { if(num==0) cout<<"零"; h=0; for(i=num;i>0;i/=10) j=i==num?1:j+1;//判断总位数j for(k=j;k>0;num%=(int)pow(10,k---1))//记录当前位置k { i=num/pow(10,k-1);//记录该位数字i if(i!=0) { if(h==1) { cout<<"零"; h=0; } if((j==2||j==6)&&k==j&&i==1);else cout<<s1[2*i]<<s1[2*i+1]; if(k!=1) cout<<s2[2*k]<<s2[2*k+1]; } else if(k!=5&&k!=1) h=1; else if(k==5) { cout<<"万"; h=0; } } cout<<endl; }
测试用例同上;(关于将数字转化为汉字,没想到很好的解法,所以函数代码没什么条理)
然后就是完整的代码了:
#include<string.h> #include<iostream> #include<math.h> using namespace std; int n,i,h,j,k; char s1[21]="零一二三四五六七八九"; char s2[19]=" 个十百千万十百千"; int shu_to_num(char c)//将单个中文转化为数字 { for(j=1;s1[j-1]!=0&&c!=s1[j];j+=2){} return j==21?-1:(j-1)/2; } int hz_to_num(char s[])//将一亿以内的中文转化为数字 { int num=0; for(i=1;s[i-1]!=0;i+=2) switch(s[i]) { case -82:num+=i>1?shu_to_num(s[i-2])*10:10;break; case -39:num+=shu_to_num(s[i-2])*100;break; case -89:num+=shu_to_num(s[i-2])*1000;break; case -14:num+=shu_to_num(s[i-2])==-1?0:shu_to_num(s[i-2]);num*=10000;break; } return shu_to_num(s[i-2])==-1?num:num+shu_to_num(s[i-2]); } void num_to_hz(int num)//将一亿以内的数字转化为中文输出 { if(num==0) cout<<"零"; h=0; for(i=num;i>0;i/=10) j=i==num?1:j+1;//判断总位数j for(k=j;k>0;num%=(int)pow(10,k---1))//记录当前位置k { i=num/pow(10,k-1);//记录该位数字i if(i!=0) { if(h==1) { cout<<"零"; h=0; } if((j==2||j==6)&&k==j&&i==1);else cout<<s1[2*i]<<s1[2*i+1]; if(k!=1) cout<<s2[2*k]<<s2[2*k+1]; } else if(k!=5&&k!=1) h=1; else if(k==5) { cout<<"万"; h=0; } } cout<<endl; } int main() { char s[20],k[20],l[20];//s记录汉字变量,k、l读取输入信息 for(;cin>>k;) { cin>>s>>k>>k; n=hz_to_num(k); for(;cin>>k;) { if(strcmp(k,s)) break; cin>>k>>l; n+=strcmp(k,"增加")==0?hz_to_num(l):-hz_to_num(l); } cin>>k; if(strcmp(k,s)) cout<<"Error"<<endl<<endl; else { cout<<"整数"<<' '<<s<<' '<<"等于"<<' '; num_to_hz(n);cout<<endl<<endl; } } }
测试用例:
/******************************************************************************************************/
/******************************************************************************************************/
整数 钱包 等于 零
钱包 增加 四
钱包 减少 三
看看 钱包
整数 健胃消食片 等于 八千七百一十三万零五十二
健胃消食片 增加 一百一十七万八千
健胃消食片 减少 三十万九千八百零五
看看 健胃消食片
整数 健胃消食片 等于 二百七十九
健胃消食片 增加 十万零六百
健胃消食片 减少 一千零一
看看 钱包
/******************************************************************************************************/
/******************************************************************************************************/
测试结果:
由于时间有限,能力不足,代码存在许多问题,主要问题有:
1.缺少错误判断,报错功能不完善;
2.代码太长,且可读性低;
3.无法解决9位及以上的汉字与整数转化;
4.没有考虑“两”,遇到2一律按“二”处理,若输入“两”程序无法判断;