Sql代码补全功能(GO)| 豆包MarsCode AI刷题

114 阅读3分钟

问题描述

在开发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'

思路解析

1. 遍历查找

遍历 data 数组,检查每个字符串是否以 input 开头。如果是,则将其添加到结果列表中。

2. 去重

使用一个 map 来记录已经添加到结果列表中的字符串,避免重复添加。

3. 排序

如果结果列表中有多个候选词,按字典序排序。

4. 返回结果

  • 如果结果列表为空,返回 "-1"
  • 如果结果列表只有一个元素,直接返回该元素。
  • 如果结果列表有多个元素,按字典序排序后,使用逗号连接并返回。

代码实现

package main

import (
	"fmt"
	"sort"
	"strings"
)

func solution(num int, data []string, input string) string {
    res := make([]string, 0)
    repeat := make(map[string]int)
    
    // 遍历 data 数组,查找以 input 开头的字符串
    for i := 0; i < num; i++ {
        if strings.HasPrefix(data[i], input) {
            if _, ok := repeat[data[i]]; !ok {
                res = append(res, data[i])
                repeat[data[i]] = 1
            }
        }
    }
    
    // 如果没有符合条件的候选词,返回 "-1"
    if len(res) == 0 {
        return "-1"
    } else if len(res) == 1 {
        // 如果只有一个候选词,直接返回该候选词
        return res[0]
    } else {
        // 如果有多个候选词,按字典序排序后,使用逗号连接并返回
        sort.Strings(res)
        return strings.Join(res, ",")
    }
}

代码解析

  1. 初始化

    • res:用于存储符合条件的候选词。
    • repeat:用于记录已经添加到 res 中的字符串,避免重复添加。
  2. 遍历查找

    • 使用 for 循环遍历 data 数组。
    • 使用 strings.HasPrefix 检查每个字符串是否以 input 开头。
    • 如果符合条件且未在 repeat 中记录过,将其添加到 res 中,并在 repeat 中记录。
  3. 返回结果

    • 如果 res 为空,返回 "-1"
    • 如果 res 只有一个元素,直接返回该元素。
    • 如果 res 有多个元素,使用 sort.Strings 按字典序排序,然后使用 strings.Join 将结果列表连接成一个字符串,使用逗号分隔。
  4. strings函数介绍

  • 字符串是否有某个前缀或后缀
// s 中是否以 prefix 开始
func HasPrefix(s, prefix string) bool {
    return len(s) >= len(prefix) && <strong><span style="color:#ff0000;">s[0:len(prefix)]</span></strong> == prefix
}
// s 中是否以 suffix 结尾
func HasSuffix(s, suffix string) bool {
    return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
}
  • Join
func Join(a []string, sep string) string

将字符串数组(或slice)连接起来可以通过 Join 实现。

标准库的实现:

func Join(a []string, sep string) string {
    if len(a) == 0 {
        return ""
    }
    if len(a) == 1 {
        return a[0]
    }
    n := len(sep) * (len(a) - 1)
    for i := 0; i < len(a); i++ {
        n += len(a[i])
    }

    b := make([]byte, n)       //借助 字节切片实现
    bp := <strong><span style="color:#ff0000;">copy</span></strong>(b, a[0])        
    for _, s := range a[1:] {
        bp += copy(b[bp:], sep)
        bp += copy(b[bp:], s)
    }
    return str

总结

通过上述方法,我们可以高效地实现SQL编辑器的自动补全功能。该方法的时间复杂度为 O(n log n),其中 n 是 data 数组的长度。这种方法在处理大规模数据时也能保持较高的效率。