做法1:字典树,添加就标记个数时+1,删除就标记个数时-1,最关键的是怎么处理有前置0的情况?我认为第一种方法,可以先把字符串变成数,但是还有另一种方法,就是,假设所有数字都是19位的,数字进来,我们在前面补0,直到补到19-数字长度即可,这样一来,就把前置0的问题解决了。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N=1e5+5;
struct node{
int cou;
node *n[3];
void init()
{
for(int i=0;i<3;i++)
{
n[i]=NULL;
}
cou=0;
}
};
node *root;
void Insert(char s[])
{
int len;
node* p=root;
len=strlen(s);
for(int i=1;i<=20-len;i++)//未解决001==1的问题,将这个字符串长度设为定值20,前面不足的全部补0,这样0X191=0X191了
{
int temp=0;
if(p->n[temp]==NULL)
{
p->n[temp]=new node;
p->n[temp]->init();
}
p=p->n[temp];
}
for(int i=0;i<len;i++)
{
int temp=s[i]-'0';
temp=temp%2;
if(p->n[temp]==NULL)
{
p->n[temp]=new node;
p->n[temp]->init();
}
p=p->n[temp];
}
p->cou++;
}
void del(char s[])
{
int len;
node *p=root;
len=strlen(s);
for(int i=1;i<=20-len;i++)//未解决001==1的问题,将这个字符串长度设为定值20,前面不足的全部补0,这样0X191=0X191了
{
int temp=0;
if(p->n[temp]==NULL)
{
p->n[temp]=new node;
p->n[temp]->init();
}
p=p->n[temp];
}
for(int i=0;i<len;i++)
{
int temp=s[i]-'0';
temp=temp%2;
if(p->n[temp]==NULL)
{
p->n[temp]=new node;
p->n[temp]->init();
}
p=p->n[temp];
}
p->cou--;
}
int query(char s[])
{
node *p=root;
int len=strlen(s);
for(int i=1;i<=20-len;i++)
{
int temp=0;
if(p->n[temp]==0)
return 0;
p=p->n[temp];
}
for(int i=0;i<len;i++)
{
int temp=s[i]-'0';
temp=temp%2;
if(p->n[temp]==0)
return 0;
p=p->n[temp];
}
return p->cou;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
char str[5];
char s[20];
root=new node();
while(n--)
{
scanf("%s %s",str,s);
if(str[0]=='+')
{
Insert(s);
}
else if(str[0]=='?')
{
int ans=query(s);
printf("%d\n",ans);
}
else
{
del(s);
}
}
}
return 0;
}
第二种做法,先把字符串转变成01串之后,之后将这个01串,按照2进制转换十进制展开,这样也解决了前置0的问题,用map解决数组可能存不下2^18这么大的空间问题。map数据结构是红黑树,查找时间复杂度logn,完全可以接受。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
map<int,int>my_map;
char s[30];
int main()
{
int n;
scanf("%d",&n);
my_map.clear();
while(n--)
{
char o;
//printf("1\n");
scanf(" %c %s",&o,s);
int len=strlen(s);
int t=0,k=0;
for(int i=0;i<len;i++)
{
k=(int)(s[i]-'0');
k=k%2;
t=t*2+k;
}
// printf("%d\n",t);
if(o=='+')
{
if(my_map.find(t)==my_map.end())
my_map[t]=1;
else
my_map[t]++;
}
else if(o=='-')
{
if(my_map[t]==1)
my_map.erase(t);
else
my_map[t]--;
}
else
{
printf("%d\n",my_map[t]);
}
}
return 0;
}