正如其他发帖者所说,您需要一个前缀树。这是一个让您入门的简单示例,假设唯一的字符是 0-7。请注意,我设置的安全性非常低,并且 number 假定给它的字符串都后跟空格(即使是最后一个),并且结果以相同的方式返回(更容易)。对于真实的代码,应该涉及更多的安全性。此外,代码未编译/未经测试,因此可能有错误。
class number { //create a prefix node type
number& operator=(const number& b); //UNDEFINED, NO COPY
int endgroup; //if this node is the end of a string, this says which group
number* next[8]; // pointers to nodes of the next letter
public:
number() :group(-1) { //constructor
for(int i=0; i<8; ++i)
next[i] = nullptr;
}
~number() { // destructor
for(int i=0; i<8; ++i)
delete next[i];
}
void add(char* numbers, int group) { //add a string to the tree for a group
if(next[numbers[0] == '\0') //if the string is completely used, this is an end
endgroup = group;
else {
int index = numbers[0]-'0'; //otherwise, get next letter's node
if (next[index] == nullptr)
next[index] = new number; //and go there
next[index].add(numbers+2, group); //+2 for the space
}
}
void find(char* numbers,
std::vector<std::pair<int, std::string>>& out,
std::string sofar="")
{ //find all strings that match
if(numbers[0]) { //if there's more letters
sofar.append(numbers[0]).append(' '); //keep track of "result" thus far
int index = numbers[0]-'0'; //find next letter's node
if (next[index] == nullptr)
return; //no strings match
next[index].find(numbers+2, out, sofar); //go to next letter's node
} else { //if there's no more letters, return everything!
if (endgroup > -1) //if this is an endpoint, put it in results
out.push_back(std::pair<int, std::string>(endgroup, sofar));
for(int i=0; i<8; ++i) { //otherwise, try all subsequent letter combinations
if (next[i]) {
std::string try(sofar); //keep track of "result" thus far
try.append('0'+i).append(' ');
next[i].find(numbers, out, try); //try this letter
}
}
}
}
} root; //this is your handle to the tree
int main() {
//group one
root.add("2 2 6", 1);
root.add("2 2 7", 1);
//...
//group two
root.add("2 2 2", 2);
//...
std::string pattern;
char digit;
while(true) {
std::cin >> digit;
if (digit<'0' || digit > '7')
break;
pattern.append(digit).append(' ');
std::vector<std::pair<int, std::string>> results;
root.find(pattern.c_str(), results);
for(int g=1; g<4; ++g) {
std::cout << "group " << g << "\n";
for(int i=0; i<results.size(); ++i) {
if( results.first == g)
std::cout << results.second;
}
}
}
}