ZOJ 3700 Ever Dream

题目链接:ZOJ 3700 Ever Dream

超级麻烦的字符串处理==。

先学一个新函数(from 百度百科)。

1、原型:
char *strtok(char s[], const char *delim);

2、功能:
分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。
例如:strtok("abc,def,ghi",","),最后可以分割成为abc def ghi.尤其在点分十进制的IP中提取应用较多。
3、说明:
strtok()用来将字符串分割成一个个片段。参数s指向欲分割的字符串,参数delim则为分割字符串中包含的所有字符。当strtok()在参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。每次调用成功则返回指向被分割出片段的指针。
4、返回值 :
从s开头开始的一个个被分割的串。当查找不到delim中的字符时,返回NULL。
所有delim中包含的字符都会被滤掉,并将被滤掉的地方设为一处分割的节点。
5 、使用
strtok函数会破坏被分解字符串的完整,调用前和调用后的s已经不一样了。如果
要保持原字符串的完整,可以使用strchr和sscanf的组合等。


然后就是map的各种应用了(看了人家代码==),用了STL调试起来也好麻烦,不过这题还是不错的,学到了很多map的知识。然后倒序输出,样例看出来的,貌似题里没说要按整体频率输出。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <vector>
#include <algorithm>
#include <iterator>
#include <stack>

using namespace std;

const int MAX_N = 100 + 10;

map <string, int> _map1;
map <int, vector<string> > _map2;

int main()
{
    //freopen("in.txt", "r", stdin);
    int T, _size, a, b, n;
    char line[MAX_N];
    scanf("%d", &T);
    string s;
    while(T--)
    {
        _map1.clear(), _map2.clear();
        scanf("%d", &n);
        getchar();
        for(int l = 0; l < n; l++)
        {
            gets(line);
            _size = strlen(line);
            for(int i = 0; i < _size; i++)
                if(!isalpha(line[i]))
                    line[i] = ' ';
            char *str = strtok(line, " ");
            while(str)
            {
                s = str;
                _size = s.length();
                for(int i = 0; i < _size; i++)
                    s[i] = tolower(s[i]);
                _map1[s]++;
				str = strtok(NULL," ");
            }
        }
        for(map<string, int> :: iterator it = _map1.begin(); it != _map1.end(); it++)
            if(it -> second >= 2)
                _map2[it -> second].push_back(it -> first);

        int black = 0, _max = 0, k, z = 0;
        vector <string> temp;
        stack <string> S;
        for(map <int, vector<string> > :: iterator it = _map2.begin(); it != _map2.end(); it++)
        {
            temp.clear();
            z = _max = 0;
            if(black > 0)
                printf(" ");
            _size = (it -> second).size();
            for(int i = 0; i < _size; i++)
            {
                if((it -> second)[i].length() == _max)
                    z++;
                else if((it -> second)[i].length() > _max)
                {
                    z = 1;
                    k = i;
                    _max = (it -> second)[i].length();
                }
            }
            if(z == 1)
            {
                S.push((it -> second)[k]);
                continue;
            }
            for(int i = 0; i < _size; i++)
                if((it -> second)[i].length() == _max)
                    temp.push_back((it -> second)[i]);
            sort(temp.begin(), temp.end());
            _size = temp.size();
            S.push(temp[_size - 2]);
        }
        while(S.size() > 1)
        {
            printf("%s ", S.top().c_str());
            S.pop();
        }
        if(!S.empty())
        {
            printf("%s\n",  S.top().c_str());
            S.pop();
        }
        else
            puts("");
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值