亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

改變合并排序中通道的使用會殺死我的程序;或者我在處理 goroutine 時誤解了范圍?

改變合并排序中通道的使用會殺死我的程序;或者我在處理 goroutine 時誤解了范圍?

Go
侃侃無極 2023-08-07 15:25:43
幾天前,我在 Code Review 網站上發布了這個主題。在其中,我詳細介紹了我在合并排序代碼中實現 goroutine 的第一次嘗試,雖然它運行良好,但我希望有更好的實現。當我想得更多時,我有了一個我認為可靠的想法:與其在將兩側合并在一起之前不斷等待左側和右側都完成,為什么不采用從左側,因為它正在對自己進行排序,并對從右側獲得的單個塊進行排序,然后對它們進行排序?我嘗試重組我的代碼,但遇到了一些問題:據我所知,我對基本情況的實現導致了巨大的問題,或者我誤解了 goroutine 的范圍,并告訴通道在何時關閉它們在不同的排序塊中仍在使用。我希望有人可以幫助我完善我的理解,或者,如果我的代碼以簡單的方式被破壞,幫助我理解我將在此代碼之后提出的問題:package mainimport (? ? "crypto/rand"? ? "fmt"? ? "os"? ? "strconv")var (? ? nums? ? []byte //The slice of numbers we want to sort? ? numVals int? ? = -1)//User can optionally add a parameter that determines how many random numbers will be sorted//If none are provided, 100 will be usedfunc main() {? ? if len(os.Args) >= 2 {? ? ? ? numVals, _ = strconv.Atoi(os.Args[1])? ? } else {? ? ? ? numVals = 2? ? }? ? nums = initSlice()? ? ms := make(chan byte)? ? go mergeSort(nums, ms)? ? pos := 0? ? for val := range ms {? ? ? ? nums[pos] = val? ? ? ? pos++? ? }? ? for _, value := range nums {? ? ? ? fmt.Printf("%d\n", value)? ? }}func initSlice() []byte {? ? vals := make([]byte, numVals)? ? _, err := rand.Read(vals)? ? if err != nil {? ? ? ? panic(err)? ? }? ? return vals}func mergeSort(arr []byte, ms chan byte) {? ? if len(arr) <= 1 {? ? ? ? if len(arr) == 1 { //base case? ? ? ? ? ? ms <- arr[0]? ? ? ? }? ? ? ? close(ms)? ? ? ? return? ? }? ? leftMS := make(chan byte)? ? go mergeSort(arr[:len(arr)/2], leftMS)? ? rightMS := make(chan byte)? ? go mergeSort(arr[len(arr)/2:], rightMS)? ? left, lOK := <-leftMS? ? right, rOK := <-rightMS? ? for lOK && rOK {? ? ? ? leftLeast := left <= right? ? ? ? if leftLeast {? ? ? ? ? ? ms <- left? ? ? ? ? ? left, lOK = <-leftMS? ? ? ? } else {? ? ? ? ? ? ms <- right? ? ? ? ? ? right, lOK = <-rightMS? ? ? ? }? ? }? ? if lOK {? ? ? ? ms <- left? ? ? ? for val := range leftMS {? ? ? ? ? ? ms <- val? ? ? ? }? ? }總的來說,我最大的問題是,假設我們有以下類型:如果我當前正在處理&ldquo;38&rdquo;和&ldquo;27&rdquo;配對,并且關閉該 ms 通道,我希望它與在 main 中啟動所有內容的通道不是同一個通道?如果沒有,有沒有辦法可以在保留名稱的同時遞歸創建新頻道?希望這一切都有意義并感謝您的幫助。
查看完整描述

1 回答

?
Qyouu

TA貢獻1786條經驗 獲得超11個贊

您的頻道使用不是您的問題。你的程序有兩個問題。

首先,您必須將結果收集到主 goroutine 中的單獨數組中,否則,您將在排序時修改正在排序的數組。

二、這個塊:

       } else {
            ms <- right
            right, lOK = <-rightMS

它應該是

right, rOK = <-rightMS

您正在設置lOK,rightMS而不是rOK。


查看完整回答
反對 回復 2023-08-07
  • 1 回答
  • 0 關注
  • 106 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號