阿里巴巴的手机代理商(简单)

                                                    阿里巴巴的手机代理商(简单)

阿里巴巴的手机代理商正在研究 infra 输入法的新功能。他们需要分析单词频率以改进用户输入法的体验。于是需要你在系统内核里面写一个 API。 API 有如下功能:

  1. 添加操作

    添加操作格式为insert barty 8,意思为插入barty这个单词,这个单词词频为 88 次。注意如果再次添加insert barty 8操作时,就会将词频增加为 1616 次。(不会出现词频\le 00 的情况)。

  2. 删除操作

    删除操作格式为delete barty,意思为删除所有barty这个单词。

    如果当前没有删除的词汇,输出Empty

  3. 查询操作

    查询操作格式为query ty,意思为查询当前版本以ty结尾的单词词频总和。

输入格式

第一行读入一个整数 T,代表数据组数。

每组数据的第一行读入一个整数 N代表操作数。

接下来 NN 行,每行形容一个操作。

保证数据满足 1 \le T \le 101T101 \le N \le 10001N1000insert操作的字符串总长度之和 \le 30003000,所有字符串长度 \le 1000010000,输入只有小写字母。

输出格式

输出题目中要求的结果。

样例输入
1
6
insert barty 8
query ty
insert party 9
query ty
delete barty
query ty
样例输出
8
17
9

思路:逆序字段树,对于插入操作就是以最后一个字母向前建树,并且在每个字符对应的频率进行操作。删除操作就用map几率这个单词的频率,然后对应每个位置减掉这个单词所有的频率.查询操作就是不断的从后循环查找这个单词的第一个字母对应的频率,然后返回回来。

坑点:查询操作遇到没有的后缀直接返回0,不然会一直wa!!!。反正这里我错了不下10次!!!

#include <cstring>
#include <cstdio>
#include<map>
#include<string>
const int maxn=1e5+10;
using namespace std;
struct Tree
{
    int data[30];
    int num;
    void init()
    {
        for(int i=0; i<=26; i++)
            data[i]=-1;
            num=0;
    }
} T[maxn];
int cur;//每个新建的节点的下标
void Insert(char *str,int value)
{
    int cnt=0;
    int len=strlen(str);
    for(int i=len-1; i>=0; i--)
    {
        int x=str[i]-'a';
        if(T[cnt].data[x]==-1)//如果这个节点不存在就新建
        {
            T[cur].init();
            T[cnt].data[x]=cur++;//data[x]保存的是这个字母后一个字母的下标
        }
        cnt=T[cnt].data[x];//下标移向后一个字母
        T[cnt].num+=value;
    }
}
void Delete(char *str,int value)
{
    int x,cnt=0;
    int len=strlen(str);
    for(int i=len-1; i>=0; i--)
    {
        x=str[i]-'a';
        cnt=T[cnt].data[x];
        T[cnt].num-=value;
    }
}
int Query(char *str)
{
    int x,cnt=0;
    int len=strlen(str);
    for(int i=len-1; i>=0; i--)
    {
        x=str[i]-'a';
        if(T[cnt].data[x]==-1)//没有这个一直wa
            return 0;
        cnt=T[cnt].data[x];
    }
    return T[cnt].num;
}
char op[maxn],s[maxn];
int main()
{
    int  t,n;
    scanf("%d",&t);
    while(t--)
    {
        cur=1;
        T[0].init();
        scanf("%d",&n);
        map<string,int>mp;
        while(n--)
        {
            int data,cnt;
            scanf(" %s",op);
            if(op[0]=='i')
            {
                scanf(" %s %d",s,&data);
                mp[s]=mp[s]+data;
                Insert(s,data);
            }
            else  if(op[0]=='q')
            {
                scanf(" %s",s);
                int ans = Query(s);
                printf("%d\n",ans);
            }
            else
            {
                scanf(" %s",s);
                if(mp[s]==0)
                     printf("Empty\n");
                else
                {
                    Delete(s,mp[s]);
                    mp[s]=0;
                }
            }
        }
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值