Tries: Contacts
这题让我门建立一个树来存电话簿的名字,并能够返回以某一字符串开头的名字有多少个。
难点在与自己建立一个数据结构。我的方法是建立一个字符树,每个节点存下有几个children,以及一个hash表,用于索引之后的字符。如下:
struct wordTree{
int cnt;
unordered_map<char, wordTree*> mp;
wordTree(int n){
cnt = n;
}
};
add操作索引这个树,并在经过的节点cnt加1,表示它的children增加一个。碰到没有的字符,则新建新的节点。
void addContact(string str){
auto cur = contactBook;
for(auto c : str){
if(!cur->mp[c]){
cur->mp[c] = new wordTree(1);
cur = cur->mp[c];
}else{
cur = cur->mp[c];
cur->cnt++;
}
}
}
find操作则顺着树中的hash表找节点,找到后返回children的个数,找不到返回0。
int findContact(string str){
auto cur = contactBook;
for(auto c : str){
if (!cur->mp[c])return 0;
else cur = cur->mp[c];
}
return cur->cnt;
}
完整代码如下:
#include <vector>
#include <string>
#include <unordered_map>
#include <iostream>
#include <algorithm>
using namespace std;
vector<string> split_string(string);
struct wordTree {
int cnt;
unordered_map<char, wordTree*> mp;
wordTree(int n) {
cnt = n;
}
};
wordTree* contactBook = new wordTree(0);
void addContact(string str) {
auto cur = contactBook;
for (auto c : str) {
if (!cur->mp[c]) {
cur->mp[c] = new wordTree(1);
cur = cur->mp[c];
}
else {
cur = cur->mp[c];
cur->cnt++;
}
}
}
int findContact(string str) {
auto cur = contactBook;
for (auto c : str) {
if (!cur->mp[c])return 0;
else cur = cur->mp[c];
}
return cur->cnt;
}
int main()
{
int n;
cin >> n;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
for (int n_itr = 0; n_itr < n; n_itr++) {
string opContact_temp;
getline(cin, opContact_temp);
vector<string> opContact = split_string(opContact_temp);
string op = opContact[0];
string contact = opContact[1];
if (op == "add") {
addContact(contact);
}
else if (op == "find") {
int res = findContact(contact);
cout << res << endl;
}
}
return 0;
}
vector<string> split_string(string input_string) {
string::iterator new_end = unique(input_string.begin(), input_string.end(), [](const char &x, const char &y) {
return x == y && x == ' ';
});
input_string.erase(new_end, input_string.end());
while (input_string[input_string.length() - 1] == ' ') {
input_string.pop_back();
}
vector<string> splits;
char delimiter = ' ';
size_t i = 0;
size_t pos = input_string.find(delimiter);
while (pos != string::npos) {
splits.push_back(input_string.substr(i, pos - i));
i = pos + 1;
pos = input_string.find(delimiter, i);
}
splits.push_back(input_string.substr(i, min(pos, input_string.length()) - i + 1));
return splits;
}