在 Golang 中如何快速判断字符串是否在一个数组中

开发 后端
在使用 Python 的时候,如果要判断一个字符串是否在另一个包含字符串的列表中,可以使用in 关键词。

[[346073]]

在使用 Python 的时候,如果要判断一个字符串是否在另一个包含字符串的列表中,可以使用in 关键词,例如:

  1. name_list = ['pm', 'kingname', '青南'] 
  2. if 'kingname' in name_list: 
  3.     print('kingname 在列表里面') 

但是,Golang 是没有in这个关键词的,所以如果要判断一个字符串数组中是否包含一个特定的字符串,就需要一个一个对比:

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5.  
  6. func in(target string, str_array []string) bool { 
  7.      for _, element :range str_array{ 
  8.         if target == element{ 
  9.             return true 
  10.         } 
  11.     } 
  12.     return false 
  13.  
  14. func main(){ 
  15.     name_list := []string{"pm", "kingname", "青南"} 
  16.     target1 :"kingname" 
  17.     target2 :"产品经理" 
  18.     result :in(target1, name_list) 
  19.     fmt.Println("kingname 是否在 name_list 中:", result) 
  20.     result = in(target2, name_list) 
  21.     fmt.Println("产品经理是否在 name_list 中:", result) 

运行效果如下图所示:

但这种方式有一个弊端,就是要遍历整个字符串数组。如果数组里面有100万条数据,那么平均要遍历50万次才能找到。这是一个非常费时间的操作。

有没有什么办法可以优化这个操作呢?

如果是有序的整型数组,那么我们可以使用二分查找,把时间复杂度O(n)降到对数时间复杂度。字符串能不能也这样操作呢?实际上是可以的。

在 Golang 中,有一个排序模块sort,它里面有一个sort.Strings()函数,可以对字符串数组进行排序。同时,还有一个sort.SearchStrings()[1]函数,会用二分法在一个有序字符串数组中寻找特定字符串的索引。

结合两个函数,我们可以实现一个更高效的算法:

  1. package main 
  2.  
  3. import ( 
  4.         "fmt" 
  5.         "sort" 
  6.     ) 
  7.  
  8.  
  9. func in(target string, str_array []string) bool { 
  10.     sort.Strings(str_array) 
  11.     index :sort.SearchStrings(str_array, target) 
  12.     if index < len(str_array) && str_array[index] == target { 
  13.         return true 
  14.     } 
  15.     return false 
  16.  
  17. func main(){ 
  18.     name_list := []string{"pm", "kingname", "青南"} 
  19.     target1 :"kingname" 
  20.     target2 :"产品经理" 
  21.     result :in(target1, name_list) 
  22.     fmt.Println("kingname 是否在 name_list 中:", result) 
  23.     result = in(target2, name_list) 
  24.     fmt.Println("产品经理是否在 name_list 中:", result) 

运行效果如下图所示:

其中,sort.Strings是一个 in-place 的修改方式,是直接修改的 str_array。修改以后str_array变成有序的字符串数组。接下来通过二分查找快速定位。如果找到了,那么返回目标字符串在排序后的列表中第一次出现的索引。如果没有找到,那么返回数组中最后一个元素的索引。所以只要 index 小于最后一个元素的索引,那么目标字符串肯定存在;如果等于最后一个元素的索引,但是值不等于最后一个元素,那么目标字符串就不存在于字符串数组中。

通过先排序再查询的方式,对于100万个元素的字符串数组,只需要查询20次左右就能确认字符串是否存在。速度大大提升。

最后考大家一个思考题。name_list一开始是乱序的字符串数组,在上图第23行,如果打印一下 name_list,打印出来的是经过排序的,还是没有经过排序的字符串数字?

 

责任编辑:赵宁宁 来源: 未闻Code
相关推荐

2022-11-24 08:01:57

bash脚本字符串

2021-01-04 09:12:31

集合变量

2018-12-14 09:32:06

亿级数据存在

2020-09-29 07:24:14

Python字典数据

2016-08-03 17:23:47

javascripthtml前端

2017-10-10 14:41:38

Linux

2023-03-31 07:31:28

SliceGolang

2018-12-14 09:16:31

装载数据数组

2023-04-25 15:46:51

Python字符串

2021-12-29 16:40:54

Python语言字符串

2022-12-08 15:55:52

JavaScript字符串

2024-01-09 16:43:49

Shell脚本开发

2020-08-24 08:07:32

Node.js文件函数

2009-12-01 10:00:51

PHP判断字符串是否为

2010-03-11 19:34:57

Python字符串

2011-03-22 10:44:20

SQL Server数拆分字符串函数

2009-02-27 16:57:51

AJAX判断请求

2020-08-01 16:19:13

JavaScript字符串开发

2011-08-04 17:13:48

Objective-C 字符串

2019-01-08 09:23:16

Java字符串编码
点赞
收藏

51CTO技术栈公众号