码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3080 Blue Jeans Trie后缀树解法

时间:2014-08-03 10:21:21      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:使用   io   数据   for   art   ar   line   new   

题目是牛仔裤的意思,不过看不出题意和Blue Jeans有什么关系。

本题的数据是很水的,数据量小,故此可以使用非常暴力的方法过,也可以使用不那么暴力的KMP过。

这里使用更加不暴力的Trie后缀树过,这种解法就一点都不水了,呵呵。

思路:

1 建立所有字符串的后缀Trie树

2 增加额外信息,看每过路径是否是所有的字符串都经过了,如果是,那么就是合法的字符串了,查找最长的这样的字符串

3 优化一下:如果不是所有字符串的经过的路径,那么就可以直接返回,不往下搜索了

最后,我发现删除Trie都是很耗时的,不释放Trie那么速度是快很多的,需要内存自然高很多。


#include <stdio.h>
#include <string.h>

const int MAX_N = 61;
const int ALP_LEN = 4;
const int SIGNIFICANT = 3;
char DNAStr[MAX_N];

inline int charToint(char a)
{
	switch (a)
	{
	case 'A':
		return 0;
	case 'T':
		return 1;
	case 'G':
		return 2;
	case 'C':
		return 3;
	}
	return -1;//unexpected input
}

inline char intTochar(int i)
{
	switch (i)
	{
	case 0:
		return 'A';
	case 1:
		return 'T';
	case 2:
		return 'G';
	case 3:
		return 'C';
	}
	return '?';//unexpected input
}

struct Node
{
	int n, tab;
	Node *alpha[ALP_LEN];
	Node():n(0), tab(-1)
	{
		for (int i = 0; i < ALP_LEN; i++)
		{
			alpha[i] = NULL;
		}
	}
};

void delTrie(Node *rt)
{
	if (rt)
	{
		for (int i = 0; i < ALP_LEN; i++)
		{
			if (rt->alpha[i]) delTrie(rt->alpha[i]);
			rt->alpha[i] = NULL;
		}
		delete rt;
	}
}

Node *Trie;
int tab;
void insert(char *chs, int len)
{
	Node *pCrawl = Trie;
	for (int i = 0; i < len; i++)
	{
		int k = charToint(chs[i]);
		if (!pCrawl->alpha[k]) pCrawl->alpha[k] = new Node;
		pCrawl = pCrawl->alpha[k];
		if (pCrawl->tab != tab)//防止重复计算
		{
			pCrawl->tab = tab;
			pCrawl->n++;
		}
	}
	if (pCrawl->tab != tab)
	{
		pCrawl->tab = tab;
		pCrawl->n++;
	}
}

int maxLen, pid, n;
char path[MAX_N], res[MAX_N];
void search(Node *rt)
{
	for (int i = 0; i < ALP_LEN; i++)
	{
		if (rt->alpha[i] && rt->alpha[i]->n == n)
		{
			path[pid++] = intTochar(i);
			if (maxLen < pid)
			{
				maxLen = pid;
				path[pid] = '\0';
				strncpy(res, path, pid+1);
			}
			search(rt->alpha[i]);
			pid--;
		}
	}
}

int main()
{
	int T;
	scanf("%d", &T);
	while (T--)
	{
		Trie = new Node;
		scanf("%d", &n);
		getchar(); // get rid of '\n'
		tab = 0;
		for (int i = 0; i < n; i++)
		{			
			gets(DNAStr);
			int len = MAX_N-1;
			tab++;
			for (char *p = &DNAStr[0]; *p; p++)
			{
				insert(p, len);
				len--;
			}
		}
		maxLen = 0, pid = 0;
		search(Trie);

		if (maxLen < SIGNIFICANT)
		{
			puts("no significant commonalities");
		}
		else
		{
			printf("%s\n", res);
		}

		//delTrie(Trie);
	}
	return 0;
}



POJ 3080 Blue Jeans Trie后缀树解法,布布扣,bubuko.com

POJ 3080 Blue Jeans Trie后缀树解法

标签:使用   io   数据   for   art   ar   line   new   

原文地址:http://blog.csdn.net/kenden23/article/details/38355267

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!