POJ 1002 487-3279 Trie解读

这个问题的解决方法是多种多样的。如本文所用,Trie为了解决这个问题。

它也可用于hash表。map等解决方案,由于输入是特定7数字,因此,你应该能够解决。

如本文所用,Trie不是非常快。最后,我主要是由于直接输出导线,遍历整个Trie速度相当慢。

思路:

1 使用insert函数建立Trie。主要添加一个叶子节点的信息。记录当前有多少个反复的字符串

2 遍历就是依据叶子节点的信息决定是否须要输出。


#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;

const int ARR_SIZE = 10;

struct Node
{
	int n;
	Node **alpha;
	Node() : n(0)
	{
		alpha = new Node*[ARR_SIZE];
		for (int i = 0; i < ARR_SIZE; i++) alpha[i] = NULL;
	}
	~Node()
	{
		for (int i = 0; i < ARR_SIZE; i++)
		{
			if (alpha[i]) delete alpha[i];
			alpha[i] = NULL;
		}
		delete alpha;
		alpha = NULL;
		n = 0;
	}
};

Node *Trie;

void insertTrie(string &s)
{
	Node *pCrawl = Trie;
	for (unsigned i = 0; i < s.size(); i++)
	{
		int id = s[i] - '0';
		if (pCrawl->alpha[id] == NULL)
		{
			pCrawl->alpha[id] = new Node;
		}
		pCrawl = pCrawl->alpha[id];
	}
	pCrawl->n++;	//添加一个字符串数量
}

inline char charToNum(char a)
{
	switch (a)
	{
	case 'A': case 'B': case 'C':
		return '2';
	case 'D': case 'E': case 'F':
		return '3';
	case 'G': case 'H': case 'I':
		return '4';
	case 'J': case 'K': case 'L':
		return '5';
	case 'M': case 'N': case 'O':
		return '6';
	case 'P': case 'R': case 'S':
		return '7';
	case 'T': case 'U': case 'V':
		return '8';
	case 'W': case 'X': case 'Y':
		return '9';
	}
	return char('9'+1);	//There is no mapping for Q or Z.uppercase letters (excluding Q and Z)
}

char lookUpTable[26];

void initLookUpTable()
{
	for (int i = 0; i < 26; i++)
	{
		lookUpTable[i] = charToNum(char(i+'A'));
	}
}

void strToNum(string &s)
{
	int j = -1;
	for (unsigned i = 0; i < s.size(); i++)
	{
		if (s[i] != '-')
		{
			s[++j] = s[i];//错误:s[j++] = s[i];j已经变化,以下还是用j
			if ('A' <= s[j] && s[j] <= 'Z')
			{
				s[j] = lookUpTable[s[j]-'A'];
			}
		}
	}
	s.resize(j+1);
}

bool flag;
void printRepeat(Node *r, string &path)
{
	if (r->n >= 1)
	{
		if (r->n == 1) return ;
		flag = true;
		unsigned i = 0;
		for ( ; i < 3; i++) putchar(path[i]);
		putchar('-');
		for ( ; i < 7; i++) putchar(path[i]);
		putchar(' ');
		printf("%d\n", r->n);
		return ;
	}
	for (int i = 0; i < ARR_SIZE; i++)//in ascending lexicographical order
	{
		path += char(i+'0');
		if (r->alpha[i]) printRepeat(r->alpha[i], path);
		path.erase(path.size()-1);
	}
}

int main()
{
	initLookUpTable();

	int N;
	scanf("%d", &N);
	getchar();
	string s;
	char chs[100];
	Trie = new Node;
	while (N--)
	{
		gets(chs);
		s = chs;
		strToNum(s);
		insertTrie(s);
	}
	flag = false;
	string path;
	printRepeat(Trie, path);
	if (!flag) puts("No duplicates.");
	delete Trie;
	return 0;
}



版权声明:笔者心脏靖。景空间地址:http://blog.csdn.net/kenden23/,可能不会在未经作者同意转载。

你可能感兴趣的:(trie)