【练习04】 字典树 1001 Hat’s Words

算法思路:考察数据结构Trie。

在31ms的时候WA了几次,后来发现是search函数的条件判断出了问题,加了一个flag标记之后AC了。

很神奇的是最后也是31msAC的,难道上面的错误只有最后一个测试数据才能发现?还是judge是在所有打印完之后再检查正确性的?疑问

代码如下:

//模板开始
#include <string>   
#include <vector>   
#include <algorithm>   
#include <iostream>   
#include <sstream>   
#include <fstream>   
#include <map>   
#include <set>   
#include <cstdio>   
#include <cmath>   
#include <cstdlib>   
#include <ctime>
#include <iomanip>
#include <string.h>
#include <queue>
#define SZ(x) (int(x.size()))
using namespace std;

int toInt(string s){
	istringstream sin(s); 
	int t; 
	sin>>t; 
	return t;
}
template<class T> string toString(T x){
	ostringstream sout; 
	sout<<x; 
	return sout.str();
}
typedef long long int64;
int64 toInt64(string s){
	istringstream sin(s); 
	int64 t; 
	sin>>t;
	return t;
}
template<class T> T gcd(T a, T b){ 
	if(a<0) 
		return gcd(-a, b);
	if(b<0) 
		return gcd(a, -b);
	return (b == 0)? a : gcd(b, a % b);
}
//模板结束(通用部分)

#define ifs cin

#define maxnode 5000000
#define maxword 50005
#define wordlen 100
#define sigma_size 26
int count[maxnode];
char words[maxword][wordlen];

struct Trie
{
	int ch[maxnode][sigma_size];
	int val[maxnode];
	int sz;
	Trie()
	{
		sz = 1;
		memset(ch[0], 0, sizeof(ch[0]));
	}
	int idx(char c)
	{
		return c - 'a';
	}

	void insert(char* s, int v)
	{
		int u = 0, n = strlen(s);
		for(int i = 0; i < n; i++)
		{
			int c = idx(s[i]);
			if(!ch[u][c])
			{
				memset(ch[sz], 0, sizeof(ch[sz]));
				val[sz] = 0;
				ch[u][c] = sz++;
			}
			u = ch[u][c];
		}
		val[u] = v;
	}

	int search(char* s, int n)
	{
		int u = 0;
		int flag = 1;
		for(int i = 0; i < n; i++)
		{
			int c = idx(s[i]);
			if(ch[u][c] == 0)
			{
				flag = 0;
				break;
			}
			u = ch[u][c];
		}	
		if(flag && val[u])
		{
			return 1;
		}
		else
		{
			return 0;
		}
	}
};

Trie t;

//【练习04】 字典树 1001 Hat’s Words

int main()
{
	//ifstream ifs("shuju.txt", ios::in);
	int wordsize = 0;
	while(ifs>>words[wordsize])
	{
		t.insert(words[wordsize], 1);
		wordsize++;
	}
	for(int i = 0; i < wordsize; i++)
	{
		//cout<<sizeof(words[i])<<endl;
		int len = strlen(words[i]);
		//cout<<len<<endl;
		for(int j = 1; j < len; j++)
		{
			//cout<<j<<endl;
			if(t.search(&words[i][0], j) && t.search(&words[i][j], len - j))
			{
				cout<<words[i]<<endl;
				break;
			}
		}

	}
	return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值