问题描述
在开发SQL编辑器时,实现自动补全功能是提高用户体验的重要一环。小C需要实现一个功能,根据用户输入的字符片段,快速从已知的SQL关键字和数据库相关名称中找到所有以该片段开头的候选词,并按字典序输出。
例如,当用户输入 s 时,编辑器需要自动提示以 s 开头的所有可能选项,如 select。如果用户输入 fr,则需要提示 from 和 from_mobile。如果在提示中只有一个选项符合,如输入 from_ 时只提示 from_mobile。
测试样例
样例1:
输入:
num = 8,data = ["select", "from", "where", "limit", "origin_log_db", "event_log_table", "user_id", "from_mobile"], input = "f"
输出:'from,from_mobile'
样例2:
输入:
num = 8,data = ["select", "from", "where", "limit", "origin_log_db", "event_log_table", "user_id", "from_mobile"], input = "wh"
输出:'where'
样例3:
输入:
num = 8,data = ["select", "from", "where", "limit", "origin_log_db", "event_log_table", "user_id", "from_mobile"], input = "z"
输出:'-1'
样例4:
输入:
num = 8,data = ["select", "from", "where", "limit", "origin_log_db", "event_log_table", "user_id", "from_mobile"], input = "origin"
输出:'origin_log_db'
#include <algorithm>
#include <iostream>
#include <string>
#include <unordered_set>
#include <vector>
std::string solution(int num, std::vector<std::string> data,
std::string input) {
std::vector<std::string> res;
std::unordered_set<std::string> repeat;
// 遍历 data 数组,查找以 input 开头的字符串
for (int i = 0; i < num; ++i) {
if (data[i].find(input) == 0) { // 检查是否以 input 开头
if (repeat.find(data[i]) == repeat.end()) {
res.push_back(data[i]);
repeat.insert(data[i]);
}
}
}
// 如果没有符合条件的候选词,返回 "-1"
if (res.empty()) {
return "-1";
} else if (res.size() == 1) {
// 如果只有一个候选词,直接返回该候选词
return res[0];
} else {
// 如果有多个候选词,按字典序排序后,使用逗号连接并返回
std::sort(res.begin(), res.end());
std::string result = res[0];
for (size_t i = 1; i < res.size(); ++i) {
result += "," + res[i];
}
return result;
}
}
int main() {
// You can add more test cases here
std::vector<std::string> testData1 = {
"select", "from", "where", "limit", "origin_log_db",
"event_log_table", "user_id", "from_mobile"};
std::cout << (solution(8, testData1, "f") == "from,from_mobile") << std::endl;
std::cout << (solution(8, testData1, "wh") == "where") << std::endl;
std::cout << (solution(8, testData1, "z") == "-1") << std::endl;
return 0;
}
前缀树
#include <algorithm>
#include <iostream>
#include <numeric>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
class Trie {
private:
struct TrieNode {
bool isEnd;
std::unordered_map<char, TrieNode *> children;
TrieNode() : isEnd(false) {}
};
TrieNode *root;
public:
Trie() { root = new TrieNode(); }
void insert(const std::string &word) {
TrieNode *node = root;
for (char ch : word) {
if (!node->children.count(ch)) {
node->children[ch] = new TrieNode();
}
node = node->children[ch];
}
node->isEnd = true;
}
void findWords(TrieNode *node, const std::string &prefix,
std::vector<std::string> &results) {
if (!node)
return;
if (node->isEnd)
results.push_back(prefix);
for (auto &[ch, child] : node->children) {
findWords(child, prefix + ch, results);
}
}
std::vector<std::string> searchWithPrefix(const std::string &prefix) {
TrieNode *node = root;
for (char ch : prefix) {
if (!node->children.count(ch))
return {}; // 直接返回空
node = node->children[ch];
}
std::vector<std::string> results;
findWords(node, prefix, results);
return results;
}
};
std::string solution(int num, const std::vector<std::string> &data,
const std::string &input) {
Trie trie;
std::unordered_set<std::string> uniqueWords;
// 插入数据到 Trie,并去重
for (const auto &word : data) {
if (uniqueWords.insert(word).second) {
trie.insert(word);
}
}
// 查找匹配的前缀
std::vector<std::string> res = trie.searchWithPrefix(input);
if (res.empty())
return "-1";
// 按字典序排序并拼接结果
std::sort(res.begin(), res.end());
return std::accumulate(
res.begin() + 1, res.end(), res[0],
[](const std::string &a, const std::string &b) { return a + "," + b; });
}
int main() {
// You can add more test cases here
std::vector<std::string> testData1 = {
"select", "from", "where", "limit", "origin_log_db",
"event_log_table", "user_id", "from_mobile"};
std::cout << (solution(8, testData1, "f") == "from,from_mobile") << std::endl;
std::cout << (solution(8, testData1, "wh") == "where") << std::endl;
std::cout << (solution(8, testData1, "z") == "-1") << std::endl;
return 0;
}