hdu2328 后缀树

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <deque>
#include <iostream>
using namespace std;
typedef long long LL;
const int MOD = 1000000007;
const int maxn = 40009 + 5;

int tree[maxn][30];
int sum[maxn];
int tot;
char ss[maxn], mid[maxn], ans[maxn];

void insert(char *str)
{
	int len = strlen(str);
	int root = 0;
	for (int i = 0; i < len; i++)
	{
		int id = str[i] - 'a';
		if (!tree[root][id])
			tree[root][id] = ++tot;

		if (sum[tree[root][id]] + 1 >= 1)
		{
			sum[tree[root][id]] = 1;
		}
		else
		{
			break;
		}
	
		root = tree[root][id];
	
	}
}

int find(char *str, int x)
{
	int len = strlen(str);
	int root = 0, deep = 0;
	for (int i = 0; i < len; i++)
	{
		int id = str[i] - 'a';
		if (tree[root][id])
		{
			if (sum[tree[root][id]] + 1 >= x)
			{
				sum[tree[root][id]] = x;
				deep++;
			}
			else
			{
				break;
			}
			root = tree[root][id];
		}
		else
		{
			break;
		}
	}

	return deep;
}

int main()
{

	int n, i, j, k, head;

	while (scanf("%d", &n) != EOF)
	{
		if(n == 0)
			break;

		memset(tree, 0, sizeof(tree));
		memset(sum, 0, sizeof(sum));
		memset(ans, 0, sizeof(ans));
		tot = 1;

		for (i = 1; i < n; i++)
		{
			scanf(" %s", ss);
			k = strlen(ss);
			//cout << "input: " << ss << endl;
			if (i == 1)
			{
				for (j = 0; j < k; j++)
				{
					//	printf("%s\n", &ss[j]);
					insert(&ss[j]);
				}
			}
			else
			{
				for (j = 0; j < k; j++)
				{
					find(&ss[j], i);
				}
			}
		}

		head = 0;
		scanf(" %s", ss);
		//cout << "Nth: " << ss << endl;
		k = strlen(ss);
		//		cout << "follows " << endl;
		for (j = 0; j < k; j++)
		{
			//	cout << &ss[j] << endl;
			int len = find(&ss[j], n);
			
			mid[0] = 0;
			strncpy(mid, ss + j, len);
mid[len] = 0;
			//	printf("mid:  %s\n", mid);

			if (len > head || (len == head && strcmp(mid, ans) < 0))
			{
				head = len;
				ans[0] = 0;
				strcpy(ans, mid);
				//	printf("ans:  %s\n", ans);
			}
		}

		if (head == 0)
		{
			printf("IDENTITY LOST\n");
		}
		else
		{
			printf("%s\n", ans);
		}
		//	cout << " n:  " << n << endl;
	}

	return 0;
}

 

后缀树的思想和字典树一样,不过是依次把字符串的所有后缀加入到树中。

 

需要整理的知识:后缀树的O(n)优化、后缀自动机、后缀数组

 

posted @ 2019-10-20 16:13  Daybreaking  阅读(171)  评论(0编辑  收藏  举报