golang 字符串切片去重實(shí)例
實(shí)現(xiàn)目的:實(shí)現(xiàn)字符串切片去重,只是兩個(gè)字符完全相同時(shí),去除一個(gè)。
實(shí)現(xiàn)方式:考慮兩種,一種是常規(guī)的雙重循環(huán)去除,另一種是利用map的key的唯一性實(shí)現(xiàn)。
1、通過雙重循環(huán)來過濾重復(fù)元素
方法1,
思路:利用for雙重循環(huán),新建一個(gè)slice,遍歷原slice中的每一個(gè)元素,每一次判斷這個(gè)元素和后面元素是否相同,若相同則去除,若不同則存入新slice中,判斷本元素后,再繼續(xù)判斷下一個(gè)元素,直到判斷完畢。
package main import "fmt" func main() { var arr = []string{"hello", "hi", "world", "hi", "china", "hello", "hi"} fmt.Println(RemoveRepeatedElement(arr)) } //去除重復(fù)字符串 func RemoveRepeatedElement(arr []string) (newArr []string) { newArr = make([]string, 0) for i := 0; i < len(arr); i++ { repeat := false for j := i + 1; j < len(arr); j++ { if arr[i] == arr[j] { repeat = true break } } if !repeat { newArr = append(newArr, arr[i]) } } return newArr }
方法2,
思路:先對(duì)原slice使用sort進(jìn)行排序,后面思路同方法1。
package main import( "fmt" "sort" ) //去除重復(fù)字符串和空格 func RemoveDuplicatesAndEmpty(a []string) (ret []string){ a_len := len(a) for i:=0; i < a_len; i++{ if (i > 0 && a[i-1] == a[i]) || len(a[i])==0{ continue; } ret = append(ret, a[i]) } return } func main(){ a := []string{"hello", "", "world", "yes", "hello", "nihao", "shijie", "hello", "yes", "nihao","good"} sort.Strings(a) fmt.Println(a) fmt.Println(RemoveDuplicatesAndEmpty(a)) }
2、通過字典來過濾
思路:因?yàn)樽值涞闹麈I唯一,所以可以用來判斷元素是否重復(fù)。
package main import ( "fmt" ) func main() { testStr := make([]string, 0) testStr = append(testStr, "haha", "hehe", "hoho", "hehe") afterStr := removeDuplicate(testStr) fmt.Println(afterStr) } // 通過map主鍵唯一的特性過濾重復(fù)元素 func removeDuplicate(arr []string) []string { resArr := make([]string, 0) tmpMap := make(map[string]interface{}) for _, val := range arr { //判斷主鍵為val的map是否存在 if _, ok := tmpMap[val]; !ok { resArr = append(resArr, val) tmpMap[val] = nil } } return resArr }
3、效率考慮
程序算法有兩個(gè)指標(biāo):運(yùn)行時(shí)間、內(nèi)存消耗(即:時(shí)間復(fù)雜度、空間復(fù)雜度)。
以上兩個(gè)方法,當(dāng)數(shù)據(jù)量小和數(shù)據(jù)量大時(shí)分別考慮用雙重for循環(huán)方法和map主鍵唯一方法。具體需要數(shù)據(jù)驗(yàn)證。
補(bǔ)充:Golang中如何刪除切片的重復(fù)元素
思想如下:利用map中key唯一的特性將slice中的數(shù)據(jù)保存到map的key中
但是要注意key的類型,有些數(shù)值不能做為key
Map 是一種無序的鍵值對(duì)的集合。Map 最重要的一點(diǎn)是通過 key 來快速檢索數(shù)據(jù),key 類似于索引,指向數(shù)據(jù)的值。
Map 是一種集合,所以我們可以像迭代數(shù)組和切片那樣迭代它。不過,Map 是無序的,我們無法決定它的返回順序,這是因?yàn)?Map 是使用 hash 表來實(shí)現(xiàn)的
Golang中map中key的類型
golang中的map,其中的 key 可以是很多種類型,比如 bool, 數(shù)字,string, 指針, channel , 還有只包含前面幾個(gè)類型的 interface types, structs, arrays
顯然,slice, map 還有 function 是不可以了,因?yàn)檫@幾個(gè)沒法用 == 來判斷
原文如下:
As mentioned earlier, map keys may be of any type that is comparable. The language spec defines this precisely, but in short, comparable types are boolean, numeric, string, pointer, channel, and interface types, and structs or arrays that contain only those types. Notably absent from the list are slices, maps, and functions; these types cannot be compared using ==, and may not be used as map keys.
// 刪除切片中重復(fù)的數(shù)據(jù) package main import ( "fmt" "reflect" "sort" ) func main() { b := []string{"a", "b", "c", "c", "e", "f", "a", "g", "b", "b", "c"} sort.Strings(b) fmt.Println(Duplicate(b)) c := []int{1, 1, 2, 4, 6, 7, 8, 4, 3, 2, 5, 6, 6, 8} sort.Ints(c) fmt.Println(DeleteDuplicateValue(c)) } func Duplicate(a interface{}) (ret []interface{}) { fmt.Printf("a : %+v\n", a) va := reflect.ValueOf(a) fmt.Printf("va : %+v\n", va) for i := 0; i < va.Len(); i++ { if i > 0 && reflect.DeepEqual(va.Index(i-1).Interface(), va.Index(i).Interface()) { continue } ret = append(ret, va.Index(i).Interface()) } return ret } // 這種方式比較容易理解 func DeleteDuplicateValue(s []int) (ret []int) { fmt.Printf("s :%+v\n", s) tmpM := make(map[int]int) // key的類型要和切片中的數(shù)據(jù)類型一致 for _, v := range s { tmpM[v] = 1 } // 先清空s s = []int{} for i, _ := range tmpM { s = append(s, i) } return s }
輸出的結(jié)果如下:
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
詳解Golang中NewTimer計(jì)時(shí)器的底層實(shí)現(xiàn)原理
本文將主要介紹一下Go語言中的NewTimer,首先展示基于NewTimer創(chuàng)建的定時(shí)器來實(shí)現(xiàn)超時(shí)控制。接著通過一系列問題的跟進(jìn),展示了NewTimer的底層實(shí)現(xiàn)原理,需要的可以參考一下2023-05-05Go語言特點(diǎn)及基本數(shù)據(jù)類型使用詳解
這篇文章主要為大家介紹了Go語言特點(diǎn)及基本數(shù)據(jù)類型使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03Go?WaitGroup及Cond底層實(shí)現(xiàn)原理
這篇文章主要為大家介紹了Go?WaitGroup及Cond底層實(shí)現(xiàn)原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08Go Gin框架中的binding驗(yàn)證器使用小結(jié)
Gin框架中的binding驗(yàn)證器為我們提供了簡便的數(shù)據(jù)綁定和驗(yàn)證功能,通過合理使用binding和validate標(biāo)簽,我們可以確保API接口的數(shù)據(jù)合法性和完整性,這篇文章主要介紹了Go Gin框架中的binding驗(yàn)證器使用指南,需要的朋友可以參考下2024-07-07go語言中的json與map相互轉(zhuǎn)換實(shí)現(xiàn)
本文主要介紹了go語言中的json與map相互轉(zhuǎn)換實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08