兄弟单词

好长时间没写blog了,写一篇表示我还活着,还在看代码,还在准备笔试和面试。。。

兄弟的单词就是两个或多个单词有相同的字母,只是字母顺序不同,例如:abfs 和fabs。找到所给单词的兄弟单词。

方案一:使用数据结构 map。兄弟单词共用一个签名key,key为单词内部排序后的词条,list存储同一key的单词集合;把相同key的兄弟单词组成一个链表。

代码:

#include
#include
#include
using namespace std;

struct node
{
	string word;
	node* next;
};
int cmp(const void* p, const void* q)
{
	return (*(char*)p) - (*(char*)q);
}
string ChangeWordToKey(string word)
{
	int length = word.length();
	char* pword = &word[0];
	qsort(pword, length, sizeof(char), cmp);
	return word;
}
void InsertWordToList(node* list, node* word)
{
	node* p = list;
	while(p->next != NULL)
		p = p->next;
	p->next = word;
}
void InsertWordsToMap(map &bromap, string word)
{
	string key = ChangeWordToKey(word);

	node* pword = new node();
	pword->word = word;
	pword->next = NULL;

	if(bromap[key])
		InsertWordToList(bromap[key], pword);
	else
		bromap[key] = pword;
}
void OutputList(node* list)
{
	if(list == NULL)
		return;
	else
	{
		while(list != NULL)
		{
			cout<word<<'\t';
			list = list->next;
		}
	}
}
void OutputMap(map &bromap)
{
	map::iterator it = bromap.begin();
	for(; it != bromap.end(); ++it)
	{
		cout<first<<": ";
		OutputList(it->second);
		cout< bromap;
	for(int i = 0; i < length; ++i)
		InsertWordsToMap(bromap, words[i]);
	OutputMap(bromap);
}
int main(int argc, char* argv[])
{
	string words[10] = {"abc", "bca", "cba", "fgdes", "edss",
						"ssde", "fffg", "fgff", "gfff", "sffdswe"};
	OutputBrotherWords(words,10);

	return 0;
}
方案二:使用trie树。trie树又称字典树,在面试题中关于“字符串”与“数字串”类型的问题中高频出现,非常实用。对于兄弟单词,兄弟单词公用一个key自不必说,只是trie的节点结构应该多出一个域list,用来存储key对应的兄弟单词。

具体节点结构应该为:

struct TrieNode
{
	bool isAWord;//is a word
	TrieNode* next[BRANCHNUM];
	std::vector browords;
};

代码:

/*-----BrotherTrie.h-----*/
#ifndef BROTHERTRIE_H
#define BROTHERTRIE_H

#include
#include
#define BRANCHNUM 26

/*trie node*/
struct TrieNode
{
	bool isAWord;//is a word
	TrieNode* next[BRANCHNUM];
	std::vector browords;
	TrieNode():isAWord(false)
	{
		std::memset(next,NULL,sizeof(next));
	}
};

/*trie class*/
class BroTrie
{
public:
	TrieNode* root;
	BroTrie() {root = new TrieNode();}

	/*insert a word to brother trie*/
	void insertAWord(const char* key, const char* word)
	{
		TrieNode* location = root;
		while(*key)
		{
			if(location->next[*key - 'a'] == NULL)
			{
				TrieNode* tmp = new TrieNode();
				location->next[*key - 'a'] = tmp;
			}
			location = location->next[*key - 'a'];
			++key;
		}
		location->isAWord = true;
		location->browords.push_back(word);
	}

	void outputBroWords(TrieNode* location)
	{
		if(location->isAWord)
		{
			std::vector::iterator it = location->browords.begin();
			for(; it != location->browords.end(); ++it)
				printf("%s ",*it);
			printf("\n");
		}
		for(int i = 0; i < BRANCHNUM; ++i)
			if(location->next[i] != NULL)
				outputBroWords(location->next[i]);
		delete location;
	}
};

#endif

/*-----BrotherTrie.cpp-----*/
#include
#include"BrotherTrie.h"
using namespace std;

int cmp(const void* p, const void* q)
{
	return (*(char*)p) - (*(char*)q);
}

int main()
{
	BroTrie broWords;
	string words[10] = {"abc", "bca", "cba", "fgdes", "edss",
						"ssde", "fffg", "fgff", "gfff", "sffdswe"};
	char* key; char* word;
	for(int i = 0; i < 10; ++i)
	{
		word = &words[i][0];
		int len = words[i].length();
		key = new char[len+1];
		strcpy(key, word);
		qsort(key, len, sizeof(char), cmp);
		broWords.insertAWord(key, word);
	}
    broWords.outputBroWords(broWords.root);
	return 0;
}

你可能感兴趣的:(C/C++,程序员笔试面试,算法与数据结构)