GO數組切片

1. 數組

數組是一個由固定長度的特定類型元素組成的序列,一個數組可以由零個或多個元素組成。

因為數組的長度是固定的,所以在Go語言中很少直接使用數組。

Go語言數組的聲明:

var 數組變量名 [元素數量]Type

1

  • 數組變量名:數組聲明及使用時的變量名。
  • 元素數量:數組的元素數量,可以是一個表達式,但最終通過編譯期計算的結果必須是整型數值,元素數量不能含有到運行時才能確認大小的數值。
  • Type:可以是任意基本類型,包括數組本身,類型為數組本身時,可以實現多維數組。

例子:

//默認數組中的值是類型的默認值
var arr [3]int

從數組中取值:

  1. 通過索引下標取值,索引從0開始
fmt.Println(arr[0])fmt.Println(arr[1])fmt.Println(arr[2])

  1. for range獲取
for index,value := range arr{fmt.Printf("索引:%d,值:%d \n",index,value)
}

給數組賦值:

  1. 初始化的時候賦值
		var arr [3]int = [3]int{1, 2, 4}//如果第三個不使用,默認為0var arr1 [3]int = [3]int{1, 2}//可以使用簡短聲明arr2 := [3]int{1, 2, 3}//如果不寫數據數量,而使用...,表示數組的長度是根據初始化值的個數來計算arr3 := [...]int{1, 2, 4, 1, 2}

通過索引下標賦值

	var arr [3]intarr[0]=1arr[1]=2arr[2]=4

一定要注意,數組是定長的,不可更改,在編譯階段就決定了

小技巧: 如果覺的每次寫 [3]int 有點麻煩,你可以為 [3]int 定義一個新的類型。

	type arr3 [3]intvar arr arr3arr[2] = 9for _, v := range arr {fmt.Println(v)}

如果想要只初始化第三個值怎么寫?

數組比較

如果兩個數組類型相同(包括數組的長度,數組中元素的類型)的情況下,我們可以直接通過較運算符(==和!=)來判斷兩個數組是否相等,只有當兩個數組的所有元素都是相等的時候數組才是相等的,不能比較兩個類型不同的數組,否則程序將無法完成編譯。

	a := [2]int{2, 1}b := [2]int{2, 1}fmt.Println(a == b) //true


2. 多維數組

Go語言中允許使用多維數組,因為數組屬于值類型,所以多維數組的所有維度都會在創建時自動初始化零值,多維數組尤其適合管理具有父子關系或者與坐標系相關聯的數據。

聲明多維數組的語法如下所示:

//array_name 為數組的名字,array_type 為數組的類型,size1、size2 等等為數組每一維度的長度。
var array_name [size1][size2]...[sizen] array_type

二維數組是最簡單的多維數組,二維數組本質上是由多個一維數組組成的。

	var arr, arr2 [2][2]int//直接初始化arr = [2][2]int{{1, 2}, {2, 1}}//初始化索引為1的的元素arr2 = [2][2]int{1: {2, 3}}

循環取值

	var arr [2][2]int//直接初始化arr = [2][2]int{{1, 2}, {2, 1}}for _, v := range arr {fmt.Println(v) //[1 2] [2 1]}

只要類型一致,就可以將多維數組互相賦值,如下所示,多維數組的類型包括每一維度的長度以及存儲在元素中數據的類型:

// 聲明兩個二維整型數組 [2]int [2]int
var array1 [2][2]int  
var array2 [2][2]int
// 為array2的每個元素賦值
array2[0][0] = 10
array2[0][1] = 20
array2[1][0] = 30
array2[1][1] = 40
// 將 array2 的值復制給 array1
array1 = array2

因為數組中每個元素都是一個值,所以可以獨立復制某個維度,如下所示:

	var arr [2][2]intarr = [2][2]int{{1, 2}, {3, 4}}var arr2 [2]intarr2 = arr[1]fmt.Println(arr2) //[3 4]

3. 切片

切片(Slice)與數組一樣,也是可以容納若干類型相同的元素的容器。

與數組不同的是,無法通過切片類型來確定其值的長度。

每個切片值都會將數組作為其底層數據結構。

我們也把這樣的數組稱為切片的底層數組。

切片(slice)是對數組的一個連續片段的引用,所以切片是一個引用類型。

這個片段可以是整個數組,也可以是由起始和終止索引標識的一些項的子集,需要注意的是,終止索引標識的項不包括在切片內(左閉右開的區間)。

Go語言中切片的內部結構包含地址、大小和容量,切片一般用于快速地操作一塊數據集合。

從連續內存區域生成切片是常見的操作,格式如下:

slice [開始位置 : 結束位置]

1

語法說明如下:

  • slice:表示目標切片對象;
  • 開始位置:對應目標切片對象的索引;
  • 結束位置:對應目標切片的結束索引。

從數組生成切片,代碼如下:

var a  = [3]int{1, 2, 3}
//a[1:2] 生成了一個新的切片
fmt.Println(a, a[1:2])

從數組或切片生成新的切片擁有如下特性:

  • 取出的元素數量為:結束位置 - 開始位置;
  • 取出元素不包含結束位置對應的索引,切片最后一個元素使用 slice[len(slice)] 獲取;
  • 當缺省開始位置時,表示從連續區域開頭到結束位置(a[:2]);
  • 當缺省結束位置時,表示從開始位置到整個連續區域末尾(a[0:]);
  • 兩者同時缺省時,與切片本身等效(a[:]);
  • 兩者同時為 0 時,等效于空切片,一般用于切片復位(a[0:0])。

注意:超界會報運行時錯誤,比如數組長度為3,則結束位置最大只能為3

切片在指針的基礎上增加了大小,約束了切片對應的內存區域,切片使用中無法對切片內部的地址和大小進行手動調整,因此切片比指針更安全、強大。

3.1 直接聲明新的切片

除了可以從原有的數組或者切片中生成切片外,也可以聲明一個新的切片,每一種類型都可以擁有其切片類型,表示多個相同類型元素的連續集合。

切片類型聲明格式如下:

//name 表示切片的變量名,Type 表示切片對應的元素類型。
var name []Type

	// 聲明字符串切片var strList []string// 聲明整型切片var numList []int// 聲明一個空切片var numListEmpty = []int{}// 輸出3個切片fmt.Println(strList, numList, numListEmpty) //[] [] []// 輸出3個切片大小fmt.Println(len(strList), len(numList), len(numListEmpty))// 切片判定空的結果fmt.Println(strList == nil)      //truefmt.Println(numList == nil)      //truefmt.Println(numListEmpty == nil) //false

切片是動態結構,只能與 nil 判定相等,不能互相判定相等。聲明新的切片后,可以使用 append() 函數向切片中添加元素。

func append(slice []Type, elems ...Type) []Type

3.2 使用 make() 函數構造切片

如果需要動態地創建一個切片,可以使用 make() 內建函數,格式如下:

make( []Type, size, cap )

Type 是指切片的元素類型,size 指的是為這個類型分配多少個元素,cap 為預分配的元素數量,這個值設定后不影響 size,只是能提前分配空間,降低多次分配空間造成的性能問題。

使用 make() 函數生成的切片一定發生了內存分配操作,但給定開始與結束位置(包括切片復位)的切片只是將新的切片結構指向已經分配好的內存區域,設定開始與結束位置,不會發生內存分配操作

思考題:

var numbers4 = [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
myslice := numbers4[4:6]
//這打印出來長度為2
fmt.Printf("myslice為 %d, 其長度為: %d\n", myslice, len(myslice))
myslice = myslice[:cap(myslice)]
//為什么 myslice 的長度為2,卻能訪問到第四個元素
fmt.Printf("myslice的第四個元素為: %d", myslice[3])

這里,cap(myslice) 返回 myslice 的容量(capacity)。由于 myslice 是從 numbers4 中提取的,它的容量實際上是從原始數組 numbers4 的起始位置到 numbers4 的結束位置的元素數量,即10。因此,myslice[:cap(myslice)] 實際上等同于 myslice[:10],它將 myslice 擴展到了其最大容量,即包含了從原始數組 numbers4 的開始到原始切片結束的所有元素。

4. 切片復制

Go語言的內置函數 copy() 可以將一個數組切片復制到另一個數組切片中,如果加入的兩個數組切片不一樣大,就會按照其中較小的那個數組切片的元素個數進行復制。

copy() 函數的使用格式如下:

copy( destSlice, srcSlice []T) int

其中 srcSlice 為數據來源切片,destSlice 為復制的目標(也就是將 srcSlice 復制到 destSlice),目標切片必須分配過空間且足夠承載復制的元素個數,并且來源和目標的類型必須一致,copy() 函數的返回值表示實際發生復制的元素個數。

下面的代碼展示了使用 copy() 函數將一個切片復制到另一個切片的過程:

	slice1 := []int{1, 2, 3, 4, 5}slice2 := []int{6, 7, 8}copy(slice1, slice2) //復制slice2 的前三個元素到slice1中fmt.Println(slice1)  //[6 7 8 4 5]copy(slice2, slice1) //復制slice1的前三個元素到slice2中fmt.Println(slice2)  //[6 7 8]

切片的引用和復制操作對切片元素的影響:

	srcArr := make([]int, 10)for i := 0; i < 10; i++ {srcArr[i] = i}refArr := srcArrcopyArr := make([]int, 10)copy(copyArr, refArr)fmt.Println(srcArr) //[0 1 2 3 4 5 6 7 8 9]srcArr[0] = 999// 打印引用切片的第一個元素 引用數據的第一個元素將會發生變化fmt.Println(refArr) //[999 1 2 3 4 5 6 7 8 9]//由于數據是復制的,因此不會發生變化。fmt.Println(copyArr) //[0 1 2 3 4 5 6 7 8 9]

5. map

map 是一種無序的鍵值對的集合。

map 最重要的一點是通過 key 來快速檢索數據,key 類似于索引,指向數據的值。

map 是一種集合,所以我們可以像迭代數組和切片那樣迭代它。不過,map 是無序的,我們無法決定它的返回順序,這是因為 map 是使用 hash 表來實現的。

map 是引用類型,可以使用如下方式聲明:

//[keytype] 和 valuetype 之間允許有空格。
var mapname map[keytype]valuetype

其中:

  • mapname 為 map 的變量名。
  • keytype 為鍵類型。
  • valuetype 是鍵對應的值類型。

在聲明的時候不需要知道 map 的長度,因為 map 是可以動態增長的,未初始化的 map 的值是 nil,使用函數 len() 可以獲取 map 中 鍵值對的數目。

	var mapLit map[string]intvar mapAssigned map[string]intmapLit = map[string]int{"one": 1, "two": 2}mapAssigned = mapLit//mapAssigned 是 mapList 的引用,對 mapAssigned 的修改也會影響到 mapList 的值。mapAssigned["two"] = 3fmt.Printf("Map literal at \"one\" is: %d\n", mapLit["one"])fmt.Printf("Map assigned at \"two\" is: %d\n", mapLit["two"])  //Map assigned at "two" is: 3fmt.Printf("Map literal at \"ten\" is: %d\n", mapLit["ten"]) //Map literal at "ten" is: 0

map的另外一種創建方式:

make(map[keytype]valuetype)

1

切記不要使用new創建map,否則會得到一個空引用的指針

map 可以根據新增的 key-value 動態的伸縮,因此它不存在固定長度或者最大限制,但是也可以選擇標明 map 的初始容量 capacity,格式如下:

make(map[keytype]valuetype, cap)

當 map 增長到容量上限的時候,如果再增加新的 key-value,map 的大小會自動加 1,所以出于性能的考慮,對于大的 map 或者會快速擴張的 map,即使只是大概知道容量,也最好先標明。

既然一個 key 只能對應一個 value,而 value 又是一個原始類型,那么如果一個 key 要對應多個值怎么辦?

答案是:使用切片

例如,當我們要處理 unix 機器上的所有進程,以父進程(pid 為整形)作為 key,所有的子進程(以所有子進程的 pid 組成的切片)作為 value。

通過將 value 定義為 []int 類型或者其他類型的切片,就可以優雅的解決這個問題,示例代碼如下所示:

mp1 := make(map[int][]int)
mp2 := make(map[int]*[]int)

5.1 遍歷map

map 的遍歷過程使用 for range 循環完成,代碼如下:

	scene := make(map[string]int)scene["cat"] = 66scene["dog"] = 4scene["pig"] = 960for k, v := range scene {fmt.Printf("key :%s,val:%d\n", k, v)}

注意:map是無序的,不要期望 map 在遍歷時返回某種期望順序的結果

5.2 刪除

使用 delete() 內建函數從 map 中刪除一組鍵值對,delete() 函數的格式如下:

delete(map, 鍵)

map 為要刪除的 map 實例,鍵為要刪除的 map 中鍵值對的鍵。

	scene := make(map[string]int)// 準備map數據scene["cat"] = 66scene["dog"] = 4scene["pig"] = 960delete(scene, "dog")for k, v := range scene {fmt.Printf("key :%s,val:%d\n", k, v)}

Go語言中并沒有為 map 提供任何清空所有元素的函數、方法,清空 map 的唯一辦法就是重新 make 一個新的 map,不用擔心垃圾回收的效率,Go語言中的并行垃圾回收效率比寫一個清空函數要高效的多。

注意map 在并發情況下,只讀是線程安全的,同時讀寫是線程不安全的。

func main() {myMap := make(map[int]int)//寫go func() {//不停的寫for {myMap[0] = 10}}()//讀go func() {//不停的讀for {_ = myMap[0]}}()// 無限循環, 讓并發程序在后臺執行for {}
}

程序報錯:fatal error: concurrent map read and map write

需要并發讀寫時,一般的做法是加鎖,但這樣性能并不高,Go語言在 1.9 版本中提供了一種效率較高的并發安全的 sync.Map,sync.Map 和 map 不同,不是以語言原生形態提供,而是在 sync 包下的特殊結構。

sync.Map 有以下特性:

  • 無須初始化,直接聲明即可。
  • sync.Map 不能使用 map 的方式進行取值和設置等操作,而是使用 sync.Map 的方法進行調用,Store 表示存儲,Load 表示獲取,Delete 表示刪除。
  • 使用 Range 配合一個回調函數進行遍歷操作,通過回調函數返回內部遍歷出來的值,Range 參數中回調函數的返回值在需要繼續迭代遍歷時,返回 true,終止迭代遍歷時,返回 false。

	var color sync.Mapcolor.Store(1, "red")color.Store(2, "blue")color.Store(3, "yellow")fmt.Println(color) //{{0 0} {[] {} 0xc00008a040} map[1:0xc0000a8018 2:0xc0000a8020 3:0xc0000a8028] 0}fmt.Println(color.Load(1)) //red truecolor.Delete(2)color.Range(func(k, v interface{}) bool {fmt.Println("iter:", k, v)return true})//iter: 1 red//iter: 3 yellow

sync.Map 為了保證并發安全有一些性能損失,因此在非并發情況下,使用 map 相比使用 sync.Map 會有更好的性能

6. nil

在Go語言中,布爾類型的零值(初始值)為 false,數值類型的零值為 0,字符串類型的零值為空字符串"",而指針、切片、映射、通道、函數和接口的零值則是 nil。

nil和其他語言的null是不同的。

nil 標識符是不能比較的

func main() {//invalid operation: nil == nil (operator == not defined on nil)fmt.Println(nil==nil)
}

nil 不是關鍵字或保留字

nil 并不是Go語言的關鍵字或者保留字,也就是說我們可以定義一個名稱為 nil 的變量,比如下面這樣:

//但不提倡這樣做
var nil = errors.New("my god")

nil 沒有默認類型

package main
import ("fmt"
)
func main() {//error :use of untyped nilfmt.Printf("%T", nil)print(nil)
}

不同類型 nil 的指針是一樣的

	var arr []intvar point *intfmt.Printf("%p\n", arr) //0x0fmt.Printf("%p", point) //0x0

nil 是 map、slice、pointer、channel、func、interface 的零值

	var m map[int]intvar p *intvar f func()var ch chan intvar s []intvar i interface{}fmt.Printf("%##v\n", m)  //map[int]int(nil)fmt.Printf("%##v\n", p)  //(*int)(nil)fmt.Printf("%##v\n", f)  //(func())(nil)fmt.Printf("%##v\n", ch) //(chan int)(nil)fmt.Printf("%##v\n", s)  //[]int(nil)fmt.Printf("%##v\n", i)  //<nil>

零值是Go語言中變量在聲明之后但是未初始化被賦予的該類型的一個默認值。

不同類型的 nil 值占用的內存大小可能是不一樣的

func main() {var p *struct{}fmt.Println( unsafe.Sizeof( p ) ) // 8var s []intfmt.Println( unsafe.Sizeof( s ) ) // 24var m map[int]boolfmt.Println( unsafe.Sizeof( m ) ) // 8var c chan stringfmt.Println( unsafe.Sizeof( c ) ) // 8var f func()fmt.Println( unsafe.Sizeof( f ) ) // 8var i interface{}fmt.Println( unsafe.Sizeof( i ) ) // 16
}

7. new和make

make 關鍵字的主要作用是創建 slice、map 和 Channel 等內置的數據結構,而 new 的主要作用是為類型申請一片內存空間,并返回指向這片內存的指針。

  1. make 分配空間后,會進行初始化,new分配的空間被清零
  2. new 分配返回的是指針,即類型 *Type。make 返回引用,即 Type;
  3. new 可以分配任意類型的數據;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/713717.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/713717.shtml
英文地址,請注明出處:http://en.pswp.cn/news/713717.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

本地快速部署谷歌開放模型Gemma教程(基于WasmEdge)

本地快速部署谷歌開放模型Gemma教程&#xff08;基于WasmEdge&#xff09; 一、介紹 Gemma二、部署 Gemma2.1 部署工具2.1 部署步驟 三、構建超輕量級 AI 代理四、總結 一、介紹 Gemma Gemma是一系列輕量級、最先進的開放式模型&#xff0c;采用與創建Gemini模型相同的研究和技…

持續集成(CICD)- Jenkins插件安裝失敗解決辦法

解決辦法&#xff1a;將插件安裝更新源需要改成國內鏡像源 具體步驟如下&#xff1a; 步驟一&#xff1a;修改Jenkins工作目錄下的 hudson.model.UpdateCenter.xml 文件&#xff0c;將url 改為http://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json 步驟二…

RuoYi-Vue-Plus功能分析-jackson配置

文章目錄 前言一、配置文件二、配置類三、注解四、json工具類1. 工具內容2. 使用工具 前言 前端在給我發送請求的時候一般包含三個部分url&#xff0c;header&#xff0c;body。那么就會涉及我們后端如何接收這些請求參數并且我們處理完畢參數后前端又如何接收參數 通過url傳…

代碼隨想錄刷題筆記 DAY 37 | 動態規劃理論基礎 | 斐波那契數 No.509 | 爬樓梯 No.70 | 使用最小花費爬樓梯 No.746

文章目錄 Day 3700. 動態規劃理論基礎01. 斐波那契數&#xff08;No. 509&#xff09;<1> 題目<2> 筆記<3> 代碼 02. 爬樓梯&#xff08;No. 70&#xff09;<1> 題目<2> 筆記<3> 代碼 03. 使用最小花費爬樓梯&#xff08;No. 746&#xff…

ECMAScript-262 @2023版本中的關鍵字和保留字

1、什么是標識符&#xff1f; 所謂標識符&#xff0c;就是javascript里的變量、函數、屬性或函數參數的名稱&#xff0c;可由一個或多個字符組成&#xff0c;當然標識符有命名規范 標識符第一個字符必須是 一個字母、下劃線&#xff08;_&#xff09;或美元符號&#xff08;$…

ONLYOFFICE文檔8.0全新發布:私有部署、卓越安全的協同辦公解決方案

ONLYOFFICE文檔8.0全新發布&#xff1a;私有部署、卓越安全的協同辦公解決方案 文章目錄 ONLYOFFICE文檔8.0全新發布&#xff1a;私有部署、卓越安全的協同辦公解決方案摘要&#x1f4d1;引言 &#x1f31f;正文&#x1f4da;一、ONLYOFFICE文檔概述 &#x1f4ca;二、ONLYOFFI…

【新書推薦】10.2 分支程序設計

稍微復雜一些的程序通常需要做某種條件判斷&#xff0c;然后再決定程序的執行流程。當然也可以無條件跳轉到程序的另一處地址開始執行。本節我們將詳細介紹分支結構的程序設計方法。 針對功能較為復雜的程序&#xff0c;程序開發有一套標準的流程&#xff0c;我們將10.1節中的五…

計算機網絡【網絡安全】

計算機網絡——網絡安全 一、網絡安全問題概述 網絡安全威脅 網絡安全面臨兩大類威脅&#xff0c;被動攻擊和主動攻擊 被動攻擊 指攻擊者從網絡上竊聽他人的通信內容&#xff0c;通常把這類攻擊稱為截獲。 主動攻擊 篡改 攻擊者故意篡改網絡上傳送的報文 惡意程序 拒絕服…

InnoDB索引與優化篇(5)-InnoDB中的查詢優化策略

InnoDB是MySQL數據庫中一種常用的存儲引擎&#xff0c;它具有高性能和可靠性。查詢優化是數據庫開發中非常重要的一環&#xff0c;它能夠幫助我們提高數據庫查詢的效率和性能。在本篇博客中&#xff0c;我們將介紹一些在使用InnoDB存儲引擎時進行查詢優化的常用策略&#xff0c…

貪心 Leetcode 455 分發餅干

分發餅干 Leetcode 455 學習記錄自代碼隨想錄 假設你是一位很棒的家長&#xff0c;想要給你的孩子們一些小餅干。但是&#xff0c;每個孩子最多只能給一塊餅干。 對每個孩子 i&#xff0c;都有一個胃口值 g[i]&#xff0c;這是能讓孩子們滿足胃口的餅干的最小尺寸&#xff1…

神經網絡算法:卷積神經網絡

神經網絡算法&#xff0c;也稱為人工神經網絡算法&#xff0c;是一種模仿人腦神經網絡結構和功能的計算模型。它由多個神經元相互連接而成的網絡組成&#xff0c;每個神經元都有輸入和輸出&#xff0c;并通過學習算法來調整連接權重&#xff0c;從而實現對輸入數據的模式識別和…

JavaScript Web Socket 詳解

Web Socket ? Web Socket&#xff08;套接字&#xff09;的目標是通過一個長時連接實現與服務器全雙工、雙向的通信。在 JavaScript 中創建 Web Socket 時&#xff0c;一個 HTTP 請求會發送到服務器以初始化連接。服務器響應后&#xff0c;連接使用 HTTP 的 Upgrade 頭部從 H…

12、窗口看門狗

目錄 1、窗口看門狗概述 2、常用寄存器和庫函數配置 3、窗口看門狗實驗 1、窗口看門狗概述 之所以稱為窗口就是因為其喂狗時間是一個有上下限的范圍內&#xff08;窗口&#xff09;&#xff0c;你可以通過設定相關寄存器&#xff0c;設定其上限時間&#xff08;下限固定&…

數據結構 棧和隊列 力扣例題AC——代碼以及思路記錄

20. 有效的括號 給定一個只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判斷字符串是否有效。 有效字符串需滿足&#xff1a; 左括號必須用相同類型的右括號閉合。左括號必須以正確的順序閉合。每個右括號都有一個對應…

mysql使用連接池

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、mysql連接池&#xff1f;二、使用步驟1.引入庫 前言 提示&#xff1a;這里可以添加本文要記錄的大概內容&#xff1a; 例如&#xff1a; 提示&#xff1a…

深入理解Flutter中的StreamSubscription和StreamController

在Flutter中&#xff0c;StreamSubscription和StreamController是處理異步數據流的重要工具。它們提供了一種方便的方式來處理來自異步事件源的數據。本文將深入探討它們的區別以及在實際應用中的使用場景。 StreamSubscription StreamSubscription代表了對數據流的訂閱&…

代碼隨想錄算法訓練營番外 刷題日記0301 || 29、兩數相除,31、下一個排列

29、兩數相除 思路&#xff1a;不斷相減就是求解的最直接方法&#xff0c;我這樣計算時間復雜度有點高 // 時間復雜度O(count*divisor) // 空間復雜度O(1)class Solution {int res 0;public int divide(int dividend, int divisor) {// dividend 是被除數if(dividend 0) …

技術棧選型的時候,ruby、go、java、vue、react應該怎么選擇?

選擇適合項目需求、團隊技術背景和偏好、開發速度、性能要求以及可擴展性的技術棧和框架是一個綜合考慮的過程&#xff0c;沒有一種通用的最佳選擇&#xff0c;取決于具體情況。 選擇Vue.js或React應該綜合考慮項目的需求、團隊的技術背景和偏好、生態系統的支持和發展趨勢等因…

隨記-點選驗證碼

文字驗證碼&#xff08;點擊文字&#xff09; 模板匹配&#xff08;從一張圖片中尋找 icon&#xff09;&#xff0c;放棄&#xff0c;目前準確率不高&#xff0c;且處理過程復雜 灰度處理將 complete_image_path 截取并另存為 target_image_path&#xff0c; verify_image_path…

WPF真入門教程30--順風物流單據管理系統

1、教程回顧 到現在為止&#xff0c;真入門系列教程已完成了29刺由淺入深地講解&#xff0c;當然不可能講到了WPF的所有技能點&#xff0c;但讀者看到了wpf的內部各種功能及之間的聯系&#xff0c;在此基礎上&#xff0c;提供一個完整有效的綜合項目&#xff0c;本項目采用的是…