【字符串处理 && 字典树】HihoCoder - 1385 A Simple Job

Problem Description

给你一个文本,文本以#结束
问你出现最多的词组是什么,词组定义:连续的两个单词中间只有空格,组合成的就叫做词组
例:above,all ,above all good at good
词组有 above all, all good, good at, at good
问你文本中出现最多的词组是那个,还有出现的次数,如果次数一样按照字典序最小的输出,没注意到这个条件,比赛没有AC,比赛后一改字典序就A了。

思路:

这道题核心点就是把所有的词组提取出来。接下来各种姿势的统计方法都有,我用的字典树,第一反应想到这个,就用了这个。

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int data;
    node *next[27];//因为有空格,所以26个字母+空格 = 27, 0-25代表'a'-'z',26代表空格
};
int top, ans;
node a[30000];//静态内存
char s[1000], phr[1000], Ans[1000];
node *creat()//初始化
{
    node *root = &a[top++];//静态申请内存
    root->data = 0;
    for(int i = 0; i < 27; i++)
        root->next[i] = NULL;
    return root;
}
node *Insert(node *root, char str[])
{
    node *p = root;
    for(int i = 0; str[i]; i++)
    {
        int t;
        if(str[i] == ' ') t = 26;//空格
        else
            t = str[i] - 'a';//字母
        if(!p->next[t]) p->next[t] = creat();
        p = p->next[t];
    }
    p->data++;
    if(ans < p->data || (ans == p->data && strcmp(Ans, str) > 0))//找出现次数最多,字典序最小的
    {
        ans = p->data;
        strcpy(Ans, str);
    }
    return root;
}
int main()
{
    top = ans = 0;//初始化
    node *root = creat();
    int fflag = 0;
    while(gets(s))
    {
        if(s[0] == '#' && !fflag)//我以为#有多行,所以WA的,改了发现还是WA,后面发现是自己没有注意到字典序的问题。
        {
            printf("%s:%d\n", Ans, ans);//输出
            top = ans = 0;//初始化
            root = creat();
            continue;
        }
        fflag = 0;
        int len = strlen(s);
        int cnt = 0, flag = 0, i, j;
        for(i = 0; i < len; i++)
        {
            if((s[i] == ' ' || s[i] == ',' || s[i] == '.') && !flag)//往前找第一个词组
            {
                int kk = 0, flag1 = 0;
                for(j = i-1; j >= 0; j--)
                {
                    if(s[j] == ',' || s[j] == '.' || (flag1 && s[j] == ' ')) break;
                    if(s[j] == ' ' && !kk)
                        phr[cnt++] = s[j];
                    else if(s[j] != ' ')
                        phr[cnt++] = s[j];
                    if(s[j] == ' ') kk++;
                    if(kk && s[j] >= 'a' && s[j] <= 'z') flag1 = 1;
                }
                if(flag1)
                {
                    phr[cnt] = '\0';
                    reverse(phr, phr+cnt);
                    root = Insert(root, phr);//将找到的词组 插入字典树
                }
                cnt = 0;
                flag = 1;
            }
            else flag = 0;
            if(i == len - 1 && !flag) {
                s[i+1] = ' ';
                len++;
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值