POJ 3573 I18n (字符串乱搞)Northeastern Europe 2007

本文深入探讨了一个涉及字符串处理的编程挑战,重点在于如何正确处理包含数字的单词,确保它们能够被准确地转换为全小写形式。通过分析样例输入输出,我们发现该问题的关键在于理解不同字符对最终结果的影响,并巧妙地利用字符操作和映射数据结构来解决。文章详细阐述了解决策略和实现细节,旨在提供一种有效且通用的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:点击打开链接

这个题的trick还是有点的,看点样例吧

/*input

output*/

ace aee a1e                               //就是出现了歧义就不修改了

ace aee a1e

Apple apple a3e A3E              //判断一个字符串是否都是大小写

Apple apple apple APPLE

ABCDEABCDEABCDE a13e A13e   //大写的单词能还原小写,而且数字是十位的,不要只当个位处理

ABCDEABCDEABCDE abcdeabcdeabcde Abcdeabcdeabcde

刚开始直接按行读入的,处理起来很麻烦的说,然后再同学那学到了新方法,处理每一个字符,遇到除字符外的题目中提到的符号就进行每个单词的处理

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cctype>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
#define debug "output for debug\n"
#define pi (acos(-1.0))
#define eps (1e-8)
#define inf 0x3f3f3f3f
#define ll long long int
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
using namespace std;
const int mod = 1000000007;
const int Max = 100005;
char c;
map<string,string>mp;      ///存储 带数字的单词,和此单词的原型
map<string,int>vis;     ///存储这个单词的原型有几种情况(如果超过一种情况就不对带数字的单词进行还原)
int fir=1;           ///记录是否有第一个单词输入,不然第一次输出会有问题
void skip()///判断特殊符号,遇到的时候直接进行处理,然后跳过
{
    while(c=='"'||c=='-'||c==' '||c==','||c=='.'||c=='('||c==')'||c==';'||c==':'||c=='!'||c=='?'||c=='\n')
    {
        if(!fir)
            printf("%c",c);
        fir=0;
        c=getchar();
    }
}
char ans[Max];
int cnt=0;
void get()///存储每一个特殊符号前的单词
{
    cnt=0;
    while(isalpha(c)||isdigit(c))
    {
        ans[cnt++]=c;
        c=getchar();
    }
    ans[cnt]='\0';///记得结尾要维护,不然字符串会乱的
}
int main()
{
    mp.clear();
    vis.clear();
    c=' ';
    while(c!=EOF)
    {
        skip();
        get();
        string tmp,ss;
        int sum=0;
        if(isdigit(ans[1]))///如果有数字,那么它的第二个字符一定是数字,可以靠这个来判断带数字的单词
        {
            int len=strlen(ans);
            ss=ans;
            for(int i=0;i<cnt;i++) ///都将其转化为小写的处理,如果输入中有大写,那么单词还原后之后再考虑大写的还原
            {
                if(isalpha(ans[i]))
                    ans[i]=tolower(ans[i]);
            }
            if(mp.find(ans)!=mp.end()&&vis[ans]==1)///查找前面是否存储过这个单词,vis的意思是没有出现歧义
            {
                tmp=mp[ans];
                int l=tmp.size();
                tmp[0]=ss[0];                    ///单词的首字母和末尾字母是不用还原的,如果首字母大写,还原后也大写
                if(ss[len-1]>='A'&&ss[len-1]<='Z')///如果单词的末字母是大写,那么肯定整个单词都是大写
                    for(int i=0;i<l;i++)
                        tmp[i]=toupper(tmp[i]);
                cout<<tmp;
            }
            else
                cout<<ss;       ///如果不符合情况,直接输出带数字的单词
        }
        else                      ///不带数字单词的处理方法
        {
            printf("%s",ans);
            for(int i=0;i<cnt;i++)
                if(isalpha(ans[i]))
                    ans[i]=tolower(ans[i]);   ///转化成小写处理并存储
            sum=cnt-2;                       ///将其转化成带数字的格式,判断有没有歧义
            ss=ans;
            tmp+=ans[0];
            string t="";
            while(sum)
            {
                t+=('0'+sum%10);
                sum/=10;
            }
            for(int i=t.size()-1;i>=0;i--)
                tmp+=t[i];
            tmp+=ans[cnt-1];
            if(vis[tmp]==0)                    ///这是没有存储过的情况,标记为1
                vis[tmp]++;
            else                             ///存储过,vis其实存储的是这个带数字单词的还原情况,大于1说明有多种,也就是有歧义
            {
                if(mp[tmp]!=ss)
                    vis[tmp]++;
            }
            mp[tmp]=ss;                     ///存一下这个单词原型
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值