字符串(1)题集

【字典树】

数组模板

#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define idx(x) x - 'a';
const int MAXN = 1e6;
struct Trie 
{
	int next[26];
	int val;
}tree[MAXN];
int nxt, T;
char str[MAXN];
int add()
{
	memset(&tree[nxt], 0, sizeof(Trie));
	return nxt++;
}
void Insert(char *s)
{
	int rt = 0, len = strlen(s);
	for(int i = 0; i < len; i++) 
	{
		int c = idx(s[i]);
		if(!tree[rt].next[c]) 
		{
			tree[rt].next[c] = add();
		}
		rt = tree[rt].next[c];
	}
	tree[rt].val++;
}
bool Find(char *s)
{
	int rt = 0, len = strlen(s);
	for(int i = 0; i < len; i++) 
	{
		int c = idx(s[i]);
		if(!tree[rt].next[c]) return false;
		rt = tree[rt].next[c];
	}
	if(tree[rt].val) return true;
	return false;
}
int main()
{
	memset(&tree[0], 0, sizeof(Trie));
	nxt = 1;
	scanf("%d", &T);
	while(T--) 
	{
		scanf("%s", str);
		Insert(str);
	}
	while(~scanf("%s", str)) 
	{
		if(Find(str)) puts("exist");
		else puts("none");
	}
	return 0;
}


POJ 2001 Shortest Prefixes(求字符串非公共的最短前缀,记录每个节点上的单词数)

HDU 1671 Phone List (也就是 POJ 3630 Phone List)

如果有前缀存在,一共就两种可能性

1、短的出现在长的前面

2、短的出现在长的后面

这一题其实也可以不用字典树的

字典树版

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring> 
#include <string>
using namespace std;
char s[100005][15],str[25];
int nxt,flag;
struct Trie
{
	int next[26];
	int val;
}tree[100005];
int add()
{
	memset(tree[nxt].next, 0, sizeof(tree[nxt].next));
	tree[nxt].val=0;
	return nxt++;
}
void insert(char *st)
{
	int rt=0,len=strlen(st);
	int ff=0;
	for(int i=0;i<len;i++)
	{
		int c=st[i]-'0';
		if(!tree[rt].next[c])
		{
			tree[rt].next[c]=add();
			if(tree[rt].val>0) flag=0;
			ff=1;
		}
		rt=tree[rt].next[c];
	}
	tree[rt].val++;
	if(ff==0) flag=0;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		nxt=1;
		int n;
		scanf("%d",&n);
		flag=1;
		memset(s,'\0',sizeof(s));
		memset(tree,0,sizeof(tree));//一定要注意,没有清零wa了好久,所以贴个代码纪念一下 
		for(int i=0;i<n;i++)
		{
			scanf("%s",s[i]);
			insert(s[i]);
		}
		if(flag==0) printf("NO\n");
		if(flag==1) printf("YES\n");
	}
	return 0;
}

非字典树版

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;

int main()
{
	string str[10010];
	int t,n;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i=0;i<n;i++)
		{
			cin>>str[i];
		}
		sort(str,str+n);//排序之后,如果存在前缀关系,那么排序后,长的必定出现在短的后一个 
		int flag=0;
		for(int i=0;i<n;i++)
		{
			int len=str[i].length();
			string tmp=str[i+1].substr(0,len);
			if(tmp==str[i])
			{
				flag=1;
				break;
			} 
		}
		if(flag==1) printf("NO\n");
		if(flag==0) printf("YES\n");
	}
	return 0;
}

这个用了c++的一些知识点

string在c++中的用法http://jingyan.baidu.com/article/20b68a8854f919796dec6265.html

HDU 1247 Hat’s Words

可以试试用string+map的方法

HDU 2846 Repository 

【KMP】

【ac自动机】



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值