英语数字转换器(栈)

题目

原题链接点击这里
在这里插入图片描述

样例输入

six
negative seven hundred twenty nine
one million one hundred one
eight hundred fourteen thousand twenty two

样例输出

6
-729
1000101
814022

算法思路

( I )数据的读入
因为是多行数据,每行有多个字符串,我们采用先将一行的字符串读入字符串Line中,然后将Line传入流stringstream中,再将stringstream中的一个个字符串一个个传给s进行处理。因为缓存区会读掉一个换行,所以当Line为空串的时候,即Line==“”时程序结束。
( II )数据结构设计及表示
我们输入的数,的结构可以表示为如下图(负号特殊处理,不考虑),其中十几和几十、个位数,处于同一优先级,其次依次是百、千、百万。个位、十几、几十此处用字母A表示,百、千、百万分别用H、T、M表示。

比如 twenty one hundred thousand million fifteen hundred thousand seventeen hundred nine可以表示为下图

容易发现,十位和个位处于同一优先级,百、千、百万优先级一次递增,于是我们便可以采用栈stack来进行设计算法。
( III )算法设计及思路
总体思路:借助栈stack分别计算上述的数据结构中,每个递增的序列的和,最后将所有值加起来,最后再乘以符号,即为答案。
特判第一个字符串是否是“negative”,是则为f=-1
接下来分析当前字符串和栈顶的优先级的情况
1.栈空,直接压入
2.优先级相等(十位和个位),将当前字符串的值加到栈顶上
3.当前优先级小于栈顶,直接压入栈
4.当前优先级大于栈顶,开始计算,并将最后计算的结果再压入栈中
最后处理完所有的字符串,将栈中的元素求和,再乘以符号,即为答案。

算法实现

#include<bits/stdc++.h>
using namespace std;
#define el '\n'
#define cl putchar('\n')

typedef map<string,int> msi;
typedef msi::iterator msi_it;
msi mp,level;

int x,y,now_level;

void init() {
	mp["zero"]=0,mp["one"]=1,mp["two"]=2,mp["three"]=3,mp["four"]=4,mp["five"]=5,mp["six"]=6,mp["seven"]=7,
	mp["eight"]=8,mp["nine"]=9,mp["ten"]=10,mp["eleven"]=11,mp["twelve"]=12,mp["thirteen"]=13;mp["fourteen"]=14;mp["fifteen"]=15;
	mp["sixteen"]=16;mp["seventeen"]=17;mp["eighteen"]=18;mp["nineteen"]=19;mp["twenty"]=20;mp["thirty"]=30;mp["forty"]=40;mp["fifty"]=50;
	mp["sixty"]=60;mp["seventy"]=70;mp["eighty"]=80;mp["ninety"]=90;mp["hundred"]=100;mp["thousand"]=1000;mp["million"]=1000000;

	level["hundred"]=2,level["thousand"]=3,level["million"]=4;
}
int main() {
	init();//初始化map 
	int ans,f;
	string s;
	stringstream ss;//用流进行读入
	getline(cin,s);
	while(s!="") {//缓存区会读掉一个换行
		if(s=="zero") { 
			cout<<"0"<<el;
			getline(cin,s);
			continue;
		}
		ss.clear();
		ss<<s;
		ans=0,f=1;//初值状态,f代表符号 
		stack<int> s_level,s_num;
		while(ss>>s) {
			if(s=="negative")f=-1;
			else {
				now_level=level[s];
				x=mp[s];
				if(s_level.empty()){//栈空,直接压入 
					s_level.push(now_level);
					s_num.push(x);
				}
				else if(now_level==s_level.top()){//优先级相等,仅有5这种个位数,和20这种十位数,优先级相同 
					y=s_num.top();
					s_num.pop();
					y+=x;//20+5或者50+3这种情况 
					s_num.push(y);
				}
				else if(now_level<s_level.top()){//当前优先级<栈顶优先级,直接压入栈 
					s_level.push(now_level);
					s_num.push(x);
				}
				else {//当前优先级>栈顶优先级,开始计算 
					int tmp=0;
					while(!s_level.empty()&&now_level>s_level.top()){
						s_level.pop();
						tmp+=s_num.top();
						s_num.pop();
					}
					s_num.push(tmp*x);
					s_level.push(now_level);
				}
			}
		}
		while(!s_num.empty()){//最后将栈中所有的值相加 
			ans+=s_num.top();
			s_num.pop();
		}
		cout<<f*ans<<el;
		getline(cin,s);
	}
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值