首頁  >  文章  >  後端開發  >  詳解用go語言實作找出兩個陣列的異同

詳解用go語言實作找出兩個陣列的異同

藏色散人
藏色散人轉載
2021-06-02 17:07:352884瀏覽

下面由golang教學專欄跟大家介紹用go語言實作找出兩個陣列的異同,希望對需要的朋友有幫助!

最近專案上碰到個小需求,輸入是兩個數組,一個舊數組一個新數組,要求取得新數組相對舊數組所有新增和刪除的元素,例如:

输入:
arr_old: {"1", "2", "4", "5", "7", "9"}
arr_new: {"2", "3", "4", "6", "7"}
返回:
arr_added: {"3", "6"}
arr_deleted: {"1", "5", "9"}

go的標準庫中沒有類似的直接比較的方法,需要自己具體實現,最簡單的方法當然是舊數組的每個元素去新數組,找不到的就是刪除的,然後新數組的元素再挨個去舊數組找一遍,找不到就是新增的,但這個方法效率實在太低了。

這裡我使用了一種基於集合運算的思想,即分別求兩個數組的交集和並集,並集減去交集就是所有發生變化的元素(要么是新增的,要嘛是刪除的),遍歷這個集合中的元素去舊數組中查找,如果在舊數組中找到,那麼就是刪除掉的元素;反之,如果找不到,則一定能在新數組中找到(用不著真的再去遍歷一次),那麼就是新增的元素。

上程式碼,這裡有個技巧,就是利用go中map鍵唯一性的特性,用陣列的元素作為map的key,透過map實現快速查找。

package main

import (
	"fmt"
)

func main() {
	//fmt.Println("Hello World!")
	src := []string{"1", "2", "4", "5", "7", "9"}
	dest := []string{"2", "3", "4", "6", "7"}

	added, removed := Arrcmp(src, dest)
	fmt.Printf("add: %v\nrem: %v\n", added, removed)
}

func Arrcmp(src []string, dest []string) ([]string, []string) {
	msrc := make(map[string]byte) //按源数组建索引
	mall := make(map[string]byte) //源+目所有元素建索引

	var set []string //交集

	//1.源数组建立map
	for _, v := range src {
		msrc[v] = 0
		mall[v] = 0
	}
	//2.目数组中,存不进去,即重复元素,所有存不进去的集合就是并集
	for _, v := range dest {
		l := len(mall)
		mall[v] = 1
		if l != len(mall) { //长度变化,即可以存
			l = len(mall)
		} else { //存不了,进并集
			set = append(set, v)
		}
	}
	//3.遍历交集,在并集中找,找到就从并集中删,删完后就是补集(即并-交=所有变化的元素)
	for _, v := range set {
		delete(mall, v)
	}
	//4.此时,mall是补集,所有元素去源中找,找到就是删除的,找不到的必定能在目数组中找到,即新加的
	var added, deleted []string
	for v, _ := range mall {
		_, exist := msrc[v]
		if exist {
			deleted = append(deleted, v)
		} else {
			added = append(added, v)
		}
	}

	return added, deleted
}

運行結果:

add: [6 3]
rem: [1 5 9]

歡迎大家交流效率更高的方法。

#

以上是詳解用go語言實作找出兩個陣列的異同的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除