1:英语数字转换器
查看 提交 统计 提问
总时间限制: 1000ms 内存限制: 65536kB
描述
在这个问题中,将用英语给你一个或多个整数。你的任务是将这些数字转换成整型表示。数字范围从-999,999,999到999,999,999.下面是你的程序必须考虑的详尽的英语单词表:

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

输入
输入包括多个样例,注意:

1.负数前面有词negative

2.当能用thousand的时候,将不用hundred。例如1500将写为"one thousand five hundred",而不是"fifteen hundred".

输入将以一个空行结束
输出
输出将是每一个单独一行,每一个后面一个换行符
样例输入
six
negative seven hundred twenty nine
one million one hundred one
eight hundred fourteen thousand twenty two

样例输出
6
-729
1000101
814022
来源
CTU Open 2004,UVA 486

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int t = 0, cnt = 0;
enum TOKEN_TYPE
{
    TYPE_NUMBER,
    TYPE_UNIT,
    TYPE_NEGATIVE
};
struct Token
{
    string        StringValue;
    int            Value;
    TOKEN_TYPE    Type;
};
Token sTokenTable[] =
{
    { "zero",        0, TYPE_NUMBER },
    { "one",            1, TYPE_NUMBER },
    { "two",            2, TYPE_NUMBER },
    { "three",        3, TYPE_NUMBER },
    { "four",        4, TYPE_NUMBER },
    { "five",        5, TYPE_NUMBER },
    { "six",            6, TYPE_NUMBER },
    { "seven",        7, TYPE_NUMBER },
    { "eight",        8, TYPE_NUMBER },
    { "nine",        9, TYPE_NUMBER },
    { "ten",            10, TYPE_NUMBER },
    { "eleven",        11, TYPE_NUMBER },
    { "twelve",        12, TYPE_NUMBER },
    { "thirteen",    13, TYPE_NUMBER },
    { "fourteen",    14, TYPE_NUMBER },
    { "fifteen",        15, TYPE_NUMBER },
    { "sixteen",        16, TYPE_NUMBER },
    { "seventeen",    17, TYPE_NUMBER },
    { "eighteen",    18, TYPE_NUMBER },
    { "nineteen",    19, TYPE_NUMBER },
    { "twenty",        20, TYPE_NUMBER },
    { "thirty",        30, TYPE_NUMBER },
    { "forty",        40, TYPE_NUMBER },
    { "fifty",        50, TYPE_NUMBER },
    { "sixty",        60, TYPE_NUMBER },
    { "seventy",        70, TYPE_NUMBER },
    { "eighty",        80, TYPE_NUMBER },
    { "ninety",        90, TYPE_NUMBER },
    { "hundred",        100, TYPE_UNIT },
    { "thousand",    1000, TYPE_UNIT },
    { "million",        1000000, TYPE_UNIT },
    { "negative",    -1, TYPE_NEGATIVE }
};
string GetTokenStr(const string &value)
{
    cnt = 0;
    stringstream ss;
    string str[30];
    ss << value;
    while (ss)
    {
        ss >> str[cnt];
        cnt++;
    }
    if (!t)
        return str[cnt - 2];
    return str[cnt - t - 1];
}
bool GetToken(const string &value, Token &nextToken)
{
    bool bRet = false;
    string tokenStr = GetTokenStr(value);
    t++;

    for (int i = 0; i < 32; ++i)
    {
        if (tokenStr == sTokenTable[i].StringValue)
        {
            nextToken.Type = sTokenTable[i].Type;
            nextToken.Value = sTokenTable[i].Value;
            bRet = true;
            break;
        }
    }
    return bRet;
}
long Parse(const string& value)
{
    long ans = 0;
    bool neg = false;
    Token NToken;
    int CUV = 1;

    while (GetToken(value, NToken))
    {
        switch (NToken.Type)
        {
        case TYPE_NEGATIVE:
            neg = true;break;

        case TYPE_NUMBER:
            ans += NToken.Value * CUV;break;

        case TYPE_UNIT:
            if (NToken.Value >= CUV)
                CUV = NToken.Value;
            else
                CUV *= NToken.Value;
            break;
        }
        if (t == cnt)
            break;
    }
    if (neg)
        ans = -ans;
    return ans;
}
int main() 
{
    cin.tie(0);
    std::ios::sync_with_stdio(false);
    string s;
    while(getline(cin, s) && !s.empty())
    {
        t = 0;
        Token NextToken;
        GetToken(s, NextToken);
        cout << Parse(s) << endl;
    }
    return 0;
}
  • 枚举的想法借鉴了网络上博客,从而很好的避免了优先级的问题,学习一个
  • string效率低确实是不可避免的,但是方便确实方便