o.boj 1495 麻烦的名词复数

注:最近这一系列ACM的内容,都是2年多之前的代码,自己回顾一下。
 
 
 
 
麻烦的名词复数
 
Submit: 204    Accepted:84
Time Limit: 2000MS  Memory Limit: 65535K
Description
英语中名词的复数是非常麻烦的东西,由于规则太多,刚上初一dalong一直没有弄清楚。而这个星期的英语作业就是名词的单数变复数,dalong希望你能帮助他来完成这份作业。当然,由于考虑到你可能也忘记了这些麻烦的规则,他特意百度了相应的规则:
名词复数的构成方法
(1) 在一般情况下,加词尾 -s:book / books 书 pen / pens 钢笔 face / faces 脸
(2) 在通常情况下,以 s, x, z, sh, ch 等结尾的名词,通常加词尾 -es:bus/buses 公共汽车
(3) 复合名词的复数形式通常是将其主要名词变为复数 passer-by / passers-by 过路人
(4) 其它特殊的不规则复数名词:man/men 男人
事实上名词复数变化远不像上面描述的这样简单,只是由于dalong刚上初一,因此只学了简单的规则,dalong事先会告诉你一些他所学到的不规则名词,而你可以认为除了这些不规则名词复数外其它的都是规则的,也就是它们满足规则1,2,3中的任一个,如果是复合名词,那么它的主要名词是单词中字母数较多的一个,相同时是第一个(主要名词的判断是dalong的发明,可能与实际情况不符,你只需要按照他的判断来做即可),如果主要名词是不规则的,那么就变成不规则的复数形式。


Input
单组测试数据
输入的第一部分有若干行,是dalong给你的不规则名词表,每一行包含两个个英语单词,单词间用空格隔开,第一个单词表示名词的单数,后一个是复数。这一部分最后一行是#,表示输入结束,这个#不是单词表中的单词。
输入的第二部分也有若干行,每一行是一个英文名词的单数,如果这个单词没有出现在单词表中,那么你可以认为它是规则的。输入的最后也是用#表示结束。
注意:单词表中的单词不会超过20000个,第二部分中的询问不会超过30000个。单词长度不会超过20。复合名词只会包含两个单词。


Output
对于输入第二部分的每一个名词单数,你需要给出它相应的复数形式。如果这个单词在不规则单词表中出现过,你需要输出单词表中给出的相应复数形式,否则按1,2,3中任一规则输出复数形式。

Sample Input

woman women
man men
child children
fish fish
tooth teeth
ox oxen
#
book
bus
passer-by
fish
box
ox
woman-maker
#


Sample Output

books
buses
passers-by
fish
boxes
oxen
women-maker


Source
 
模拟题,注意超时。
 
#include <iostream>
#include <string>
#include <map>
using namespace std;

void normal_change(string str)
{
    int len = str.length();
    if (str[len-1] == 'z' || str[len-1] == 's' || str[len-1] == 'x')
        cout << str << "es";
    else if (str[len-1] == 'h' && (str[len-2] == 's' || str[len-2] == 'c'))
        cout << str << "es";
    else
        cout << str << "s";
}

int main()
{
    map<string, string> M;
    map<string, string>::iterator pos;
    string A, B;
    string temp, sub1, sub2;
    int in_len, s_len;
    
    while (1)
    {
        cin >> A;
        if (A == "#")
            break;        
        cin >> B;
        M.insert(make_pair(A, B));
    }
    
    cin >> temp;
    while (temp != "#")
    {
        sub1 = sub2 = "\0";
        in_len = temp.length();
        for (s_len = 0; s_len < in_len; s_len++)
            if (temp[s_len] == '-')
                break;
        
        if (s_len != in_len)
        {
            sub1 = temp.substr(0, s_len);
            sub2 = temp.substr(s_len+1, in_len-s_len-1);
            if (s_len >= in_len/2)
            {
                pos = M.find(sub1);
                if (pos != M.end())
                    cout << pos->second;
                else
                    normal_change(sub1);
                cout << "-" << sub2;
            }
            else
            {
                cout << sub1 << "-";
                pos = M.find(sub2);
                if (pos != M.end())
                    cout << pos->second;
                else
                    normal_change(sub2);
            }            
        }
        else
        {
            pos = M.find(temp);
            if (pos != M.end())
                cout << pos->second;
            else
                normal_change(temp);
        }        
        
        cout << endl;
        cin >> temp;        
    }    
    // system("pause");
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值