问题描述
在与财务相关的应用中,经常会用到人民币金额的大写,比如发票的打印程序。本题的任务是:从键盘输入一个十亿以内的正整数(int 类型),把它转换为人民币金额大写(不考虑用户输入错误的情况)
比如,用户输入: 35201,程序输出:叁万伍仟贰佰零壹
用户输入: 30201,程序输出:叁万零贰佰零
算法设计
主要是利用栈来实现,因为栈的特点是先入后出,而我们通过计算机(整除和求余)读入是从低位到高位读入,而输出的时候是从高位往低位读。关于权和零的问题,因为比较特殊当size == 4
或size==8
,直接输出‘万’、‘亿’,多个零的情况可以通过一个while
来做,如果栈顶为零,就一直出栈,直到不为零,但只输出一个“零”。
算法实现
采用栈的数据结构(简单版本)
class numStack{
protected:
int *upper; // 存每个数字
int size; // 存有多少个数字
public:
numstack(){
upper = new int[20]; // 题目说明了最大10亿
size = 0;
} // 构造函数
~numstack(){
delete []upper;
} // 析构函数
void Push(const int n){
upper[size++] = n;
return ;
} // 入栈
int Top(){
int i = size - 1;
return upper[i];
} // 取栈顶元素
void Pop(int &n){
n = upper[size-1];
size--;
return ;
} // 出栈
int theSize(){
return size;
} // size 为protected类型,只能通过函数访问
主函数
int main()
{
int money;
numstack myStack;
cout<<"请输入金额:";
while(cin>>money){
string upchar[9] = {"壹","贰","叁","肆","伍","陆","柒","捌","玖"};
string unit[4] = {"十","百","千","万"};
int now = 0;
while(money != 0){
myStack.Push(money%10); // 依次入栈
money = money / 10;
}
while(myStack.theSize()!=0){
if(myStack.Top()!=0){ // 看栈顶元素是否为零
myStack.Pop(now); // 是的话出栈并在下面把权表示出来
cout<<upchar[now-1];
if(myStack.theSize() == 8){
cout<<"亿";
} else if (myStack.theSize()==0){
cout<<"";
}else{
cout<<unit[(myStack.theSize()-1)%4]; // 输出权
}
} else{
while(myStack.Top()==0){
myStack.Pop(now);
if(myStack.theSize() ==4 && now==0){ // 输出当万位为0的时候‘万’权
cout<<"万";
}
}
if(myStack.theSize()!=0){
cout<<"零"; // 中间的零只输出一个
}
}
}
cout<<endl;cout<<"请输入金额:"; // 格式控制
}
return 0;
}