题目
字符串前缀统计
Description
给定N个单词,建立 Trie 树;
求所有长度为M的前缀中出现的次数最多的前缀。
Input
第一行:N,M
接下来N行每行一个单词,单词的长度不超过15
Output
长度为M的字符串,表示前缀长度为M的出现次数最多的字符串前缀
Sample Input
3 2
abc
abd
acd
Sample Output
ab
解题思路
用Trie树实现,定义树的节点为一个结构体。元素包括:一个字符型数据,27个指向该类型节点的指针,以及一个整型元素(记录经过这个点的字符串数)。
难点在于插入字符串和统计字符串前缀这两个函数的实现。
代码如下
Trie_node.h
#include<iostream>
using namespace std;
const int num_chars = 27;
struct Trie_node
{
char data;
Trie_node* branch[num_chars];
int numpass;
Trie_node() {
data = '\0';
for (int i = 0; i < num_chars; i++)
branch[i] = NULL;
numpass = 0;
}
};
Key.h
#pragma once
#include"Trie_node.h"
class Key {
public:
Key(string s);
char* the_key() ;
char key_letter(int position);
private:
char str[10];
};
Key.cpp
#include "Key.h"
Key::Key(string s)
{
int i;
for (i = 0; i <= s.size(); i++)
str[i] = s[i];
}
char* Key::the_key()
{
return (char*)str;
}
char Key::key_letter(int position)
{ //返回字符串中该位置的字符
if (position < strlen(str))
return str[position];
else
return '\0';
}
Trie.h
#pragma once
#include"Key.h"
enum Error_code { not_present, overflow, underflow, duplicate_error, success };
class Trie
{
public:
Error_code insert(Key& new_entry);
Trie();
int countPrefix(Key s,int num);
private:
Trie_node* root;
};
int alphabetic_order(char c);
Trie.cpp
#include "Trie.h"
int alphabetic_order(char c)
//返回字符c是在字典序中的第几个位置
{
if (c == ' ' || c == '\0') return 0;
if ('a' <= c && c <= 'z') return c - 'a' + 1;
if ('A' <= c && c <= 'Z') return c - 'A' + 1;
}
Trie::Trie() {
root = NULL;
}
Error_code Trie::insert(Key& new_entry)
{
Error_code result = success;
if (root == NULL) root = new Trie_node; //如果根节点不存在,生成新的根节点
int position = 0;
char next_char;
Trie_node* location = root;
while (location != NULL &&(next_char = new_entry.key_letter(position)) != '\0')
{
int next_position = alphabetic_order(next_char);
if (location->branch[next_position] == NULL)
location->branch[next_position] = new Trie_node;
location = location->branch[next_position];
location->data = 'a' + next_position - 1;
location->numpass++;
position++;
}
return result;
}
int Trie::countPrefix(Key s,int num)
{
int i;
Trie_node* location = root;
for (i = 0; i < num; i++)
{
int next_position = alphabetic_order(s.key_letter(i));
location = location->branch[next_position];
}
return location->numpass;
}
main.cpp
#include<vector>
#include"Trie.h"
using namespace std;
int main()
{
Trie t;
int N,M,i;
cin >> N>>M;
string str[10];
for (i = 0; i < N; i++)
{
cin >> str[i];
Key* k=new Key(str[i]);
t.insert(*k);
}
vector<int> v;
int m;
for (i = 0; i < N; i++)
{
Key* k = new Key(str[i]);
m=t.countPrefix(*k, M);
v.push_back(m);
}
int max = v[0];
for (i = 0; i < N; i++)
{
if (v[i] > max)
max = v[i];
}
int j;
for (j = 0; j < N; j++)
{
if (v[j] == max)
break;
}
cout << str[j].substr(0, M);
return 0;
}