题目大意:
给出一个数字的英文单词,输出对应的数字。如“two hundred twenty two”表示222。
分析:
首先将读入的字符串转换为数字数组,例如,以上字符串就存为2,100,20,2。
想了很久不知如何用一个简练的方式来处理。后来用了一个递归的方法。
函数int work(int L,int R)用来求解数组a[]L到R的区间表示的数字。
按次序依次在这个区间查找1000000,1000,100这三个数字。
若在k位置找到其中一个数字num,则这个区间表示的数字为work(L,k-1)×num+work(k+1,R)
若没有找到这三个数字,那么这个区间表示的数字为区间内所有数字之和。
--------------------------------------
/*
ZJU2311 Inglish-Number Translator
*/
#include <stdio.h>
#include <string.h>
#define clr(a) memset(a,0,sizeof(a))
#define N 205
#define M 32
char num[][20]={"negative",
"zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen",
"fourteen", "fifteen", "sixteen",
"seventeen", "eighteen", "nineteen",
"twenty", "thirty", "forty", "fifty", "sixty",
"seventy", "eighty", "ninety",
"hundred", "thousand", "million" };
int e[]={-1,
0,1,2,3,4,5,6,7,8,9,
10,11,12,13,14,15,16,17,18,19,
20,30,40,50,60,70,80,90,
100,1000,1000000 };
int ord[]={100, 1000, 1000000};
int getNum(char s[]){
int i=0;
while(strcmp(s,num[i])) i++;
return e[i];
}
int local(int a[],int l,int r,int x){
int i;
for(i=l;i<=r;i++) if(a[i]==x) return i;
return -1;
}
int work(int a[],int l,int r){
int i,j,k,m,t;
for(k=2;k>=0;k--){
if((t=local(a,l,r,ord[k]))>=0){
return work(a,l,t-1)*ord[k]+work(a,t+1,r);
}
}
m=0;
for(i=l;i<=r;i++) m+=a[i];
return m;
}
int main()
{
int i,j,k,m,n;
int sum,x,neg;
int a[N];
char str[N],s[N];
clr(str);
while(gets(str),strcmp(str,"")){
//input
n=0;k=0;
while(sscanf(str+k,"%s",s)!=EOF){
k+=strlen(s)+1;
a[n++]=getNum(s);
if(k>=strlen(str)) break;
}
//work
if(a[0]==-1) sum=-work(a,1,n-1);
else sum=work(a,0,n-1);
printf("%d/n",sum);
clr(str);
}
return 0;
}