SQL代码补全
问题描述
在开发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'
分析题目
题目要求实现一个SQL编辑器的自动补全功能。具体来说,用户输入一个字符片段,系统需要从已知的SQL关键字和数据库相关名称中找到所有以该片段开头的候选词,并按字典序输出。如果没有匹配的候选词,则输出 -1。
结构选择
- 输入数据:已知的SQL关键字和数据库相关名称存储在一个字符串数组
data中。 - 用户输入:用户输入的字符片段存储在一个字符串
input中。 - 输出数据:匹配的候选词列表,按字典序排列,用逗号分隔。如果没有匹配项,输出
-1。
算法设计
- 遍历数据:遍历
data数组中的每一个字符串。 - 匹配检查:对于每一个字符串,检查它是否以
input开头。 - 去重:确保匹配的字符串不重复。
- 排序:将匹配的字符串按字典序排序。
- 输出结果:将排序后的字符串列表用逗号连接,如果没有匹配项则输出
-1。
注意事项
- 字符串匹配:使用
startsWith方法可以简化匹配检查。 - 去重:可以使用
Set来确保匹配的字符串不重复。 - 排序:使用
Collections.sort方法对列表进行排序。
代码展示
`import java.util.ArrayList; import java.util.Collections;
public class Main {
public static String solution(int num, String[] data, String input) {
int a = input.length();
ArrayList<String> arr = new ArrayList<String>();
for (int i = 0; i < num; i++) {
if (data[i].length() < a) {
continue;
}
boolean match = true;
for (int j = 0; j < a; j++) {
if (data[i].charAt(j) != input.charAt(j)) {
match = false;
break;
}
}
if (match && !arr.contains(data[i])) { // 去重检查
arr.add(data[i]);
}
}Collections.sort(arr);
StringBuilder as = new StringBuilder();
for (int i = 0; i < arr.size(); i++) {
as.append(arr.get(i));
if (i != arr.size() - 1) {
as.append(",");
}
} return as.length() == 0 ? "-1" : as.toString();
}
// You can add more test cases here
String[] testData1 = { "select", "from", "where", "limit", "origin_log_db", "event_log_table", "user_id",
"from_mobile" };
String[] testData2 = { "select", "from", "where", "limit", "group", "having", "in", "index", "inner", "insert",
"like", "log_db", "log_table", "user_id", "group_name", "group_id" };
System.out.println(solution(8, testData1, "f").equals("from,from_mobile"));
System.out.println(solution(16, testData2, "g").equals("group,group_name,group_id"));
System.out.println(solution(16, testData2, "m").equals("-1"));
}
优化方法
1. 使用 startsWith 方法简化匹配检查
当前代码中使用了嵌套的 for 循环来检查字符串是否以 input 开头。我们可以使用 String 类的 startsWith 方法来简化这一过程。
2. 使用 Set 去重
当前代码中使用了 ArrayList 并手动检查是否包含重复项。我们可以使用 Set 来自动去重,然后再将 Set 转换为 List 进行排序。
3. 减少不必要的操作
当前代码中在每次添加元素时都进行了 contains 检查,这会增加时间复杂度。我们可以先添加所有匹配的元素,然后再进行去重和排序。