同事分享了一道Go的算法面试题,下面是基于字符串分析的go代码,在写的时候特意将最后一行数据加大复杂度,给大家分享一下:
字符输入规则如下:
a. 每行表示一条记录,字段之间以逗号(,)分隔。
b. 如果字段内容包含逗号(,),则需使用双引号(")包裹。
c. 如果字段内容包含双引号("),则需使用两个双引号("")进行转义并用双引号包裹。
4. 编写解析程序,将解析后的内容按行输出,字段之间以制表符(\t)分隔。
5. 以下是一个示例:
1)输入:Linda,47,"旅游,""攀岩",New Job
2)输出:Linda 47 旅游,"攀岩 New Job
rows := `2,Tina,37,"足球,""篮球",Old Job
3,Alice Job,66,"""看电影"",旅游","上海,上海市"
4,John,44,"洗衣机101,""","LA""CITY"""
5,"Jane,li",55,Hiking,Canada` 加大难度,修改为 5,"Jane,Li""",55,Hiking,""",Canada"
本题解析思路如下:
1,按行读取数据
2,每行按字符解析
2.1 记录 " 第1次出现的索引left,计数 " 出现的 total 数量,每次分割的 逗号 索引 lastSplit
2.2 遇到 逗号,如果 之前没有 " ,则left还是默认-1,可以直接分割字段
2.3 遇到 逗号,如果 之前出现的 " 总数total为 偶数,则也可以直接分割字段,并重置left total 变量
2.4 当解析到行的最后一个字符时,分为是 " 和 非 " 两种情况
package mainimport ("fmt""strings"
)func main() {rows := `2,Tina,37,"足球,""篮球",0ld Job
3,ALice Job,66,"""看电影"",旅游","上海,上海市"
4,John,44,"洗衣机101,""","LA""CITY"""
5,"Jane,Li""",55,Hiking,""",Canada"`rowSlice := strings.Split(rows, "\n")res := make([][]string, 0)for _, v := range rowSlice {left := -1 // 第一次遇到 " 时索引total := 0 // 已经出现的 " 个数row := make([]string, 0)lastSplit := 0 // 上一次出现 分割字段的 开始索引for i := 0; i < len(v); i++ {if v[i] == ',' && left < 0 {row = append(row, string(v[lastSplit:i]))lastSplit = i + 1continue}if v[i] == '"' {total += 1if left < 0 {left = i}if i == len(v)-1 {row = append(row, string(v[left+1:i]))break}}if v[i] == ',' {if total%2 == 0 && left > 0 {row = append(row, string(v[left+1:i-1]))left = -1total = 0lastSplit = i + 1continue}}if i == len(v)-1 {row = append(row, string(v[lastSplit:]))}}res = append(res, row)}for _, v := range res {fmt.Println(strings.Join(v, "\t"))}
}
最终输出
2 Tina 37 足球,""篮球 0ld Job
3 ALice Job 66 ""看电影"",旅游 上海,上海市
4 John 44 洗衣机101,"" LA""CITY""
5 Jane,Li"" 55 Hiking "",Canada