亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Golang > 正文

Go語言實現的排列組合問題實例(n個數中取m個)

2020-04-01 19:06:27
字體:
來源:轉載
供稿:網友

本文實例講述了Go語言實現的排列組合問題。分享給大家供大家參考,具體如下:

(一)組合問題

組合是一個基本的數學問題,本程序的目標是輸出從n個元素中取m個的所有組合。

例如從[1,2,3]中取出2個數,一共有3中組合:[1,2],[1,3],[2,3]。(組合不考慮順序,即[1,2]和[2,1]屬同一個組合)

本程序的思路(來自網上其他大神):

(1)創建有n個元素數組,數組元素的值為1表示選中,為0則沒選中。
(2)初始化,將數組前m個元素置1,表示第一個組合為前m個數。
(3)從左到右掃描數組元素值的“10”組合,找到第一個“10”組合后將其變為“01”組合,同時將其左邊的所有“1”全部移動到數組的最左端。
(4)當某次循環沒有找到“10“組合時,說明得到了最后一個組合,循環結束。

例如求5中選3的組合:

1 1 1 0 0 //1,2,3
1 1 0 1 0 //1,2,4
1 0 1 1 0 //1,3,4
0 1 1 1 0 //2,3,4
1 1 0 0 1 //1,2,5
1 0 1 0 1 //1,3,5
0 1 1 0 1 //2,3,5
1 0 0 1 1 //1,4,5
0 1 0 1 1 //2,4,5
0 0 1 1 1 //3,4,5

效率情況:20個元素中取5個,共15504個結果,耗時約10ms.

代碼實現:

復制代碼 代碼如下:
package huawei
import (
    "fmt"
    "time"
)
/*
【排列組合問題:n個數中取m個】
*/
func Test10Base() {
    nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    m := 5
    timeStart := time.Now()
    n := len(nums)
    indexs := zuheResult(n, m)
    result := findNumsByIndexs(nums, indexs)
    timeEnd := time.Now()
    fmt.Println("count:", len(result))
    fmt.Println("result:", result)
    fmt.Println("time consume:", timeEnd.Sub(timeStart))
    //結果是否正確
    rightCount := mathZuhe(n, m)
    if rightCount == len(result) {
        fmt.Println("結果正確")
    } else {
        fmt.Println("結果錯誤,正確結果是:", rightCount)
    }
}
//組合算法(從nums中取出m個數)
func zuheResult(n int, m int) [][]int {
    if m < 1 || m > n {
        fmt.Println("Illegal argument. Param m must between 1 and len(nums).")
        return [][]int{}
    }
    //保存最終結果的數組,總數直接通過數學公式計算
    result := make([][]int, 0, mathZuhe(n, m))
    //保存每一個組合的索引的數組,1表示選中,0表示未選中
    indexs := make([]int, n)
    for i := 0; i < n; i++ {
        if i < m {
            indexs[i] = 1
        } else {
            indexs[i] = 0
        }
    }
    //第一個結果
    result = addTo(result, indexs)
    for {
        find := false
        //每次循環將第一次出現的 1 0 改為 0 1,同時將左側的1移動到最左側
        for i := 0; i < n-1; i++ {
            if indexs[i] == 1 && indexs[i+1] == 0 {
                find = true
                indexs[i], indexs[i+1] = 0, 1
                if i > 1 {
                    moveOneToLeft(indexs[:i])
                }
                result = addTo(result, indexs)
                break
            }
        }
        //本次循環沒有找到 1 0 ,說明已經取到了最后一種情況
        if !find {
            break
        }
    }
    return result
}
//將ele復制后添加到arr中,返回新的數組
func addTo(arr [][]int, ele []int) [][]int {
    newEle := make([]int, len(ele))
    copy(newEle, ele)
    arr = append(arr, newEle)
    return arr
}
func moveOneToLeft(leftNums []int) {
    //計算有幾個1
    sum := 0
    for i := 0; i < len(leftNums); i++ {
        if leftNums[i] == 1 {
            sum++
        }
    }
    //將前sum個改為1,之后的改為0
    for i := 0; i < len(leftNums); i++ {
        if i < sum {
            leftNums[i] = 1
        } else {
            leftNums[i] = 0
        }
    }
}
//根據索引號數組得到元素數組
func findNumsByIndexs(nums []int, indexs [][]int) [][]int {
    if len(indexs) == 0 {
        return [][]int{}
    }
    result := make([][]int, len(indexs))
    for i, v := range indexs {
        line := make([]int, 0)
        for j, v2 := range v {
            if v2 == 1 {
                line = append(line, nums[j])
            }
        }
        result[i] = line
    }
    return result
}

 

注:n個元素中取m個一共有多少種取法可直接通過數學公式計算得出,即:

復制代碼 代碼如下:
//數學方法計算排列數(從n中取m個數)
func mathPailie(n int, m int) int {
    return jieCheng(n) / jieCheng(n-m)
}
//數學方法計算組合數(從n中取m個數)
func mathZuhe(n int, m int) int {
    return jieCheng(n) / (jieCheng(n-m) * jieCheng(m))
}
//階乘
func jieCheng(n int) int {
    result := 1
    for i := 2; i <= n; i++ {
        result *= i
    }
    return result
}

 

通過此公式可以簡單的驗證一下上述程序的結果是否正確。

(二)排列問題

從n個數中取出m個進行排列,其實就是組合算法之后,對選中的m個數進行全排列。而全排列的問題在之前的文章中已經討論過了。

代碼實現:

復制代碼 代碼如下:
func pailieResult(nums []int, m int) [][]int {
    //組合結果
    zuhe := zuheResult(nums, m)
    //保存最終排列結果
    result := make([][]int, 0)
    //遍歷組合結果,對每一項進行全排列
    for _, v := range zuhe {
        p := quanPailie(v)
        result = append(result, p...)
    }
    return result
}
//n個數全排列
//如輸入[1 2 3],則返回[123 132 213 231 312 321]
func quanPailie(nums []int) [][]int {
    COUNT := len(nums)
    //檢查
    if COUNT == 0 || COUNT > 10 {
        panic("Illegal argument. nums size must between 1 and 9.")
    }
    //如果只有一個數,則直接返回
    if COUNT == 1 {
        return [][]int{nums}
    }
    //否則,將最后一個數插入到前面的排列數中的所有位置
    return insertItem(quanPailie(nums[:COUNT-1]), nums[COUNT-1])
}
func insertItem(res [][]int, insertNum int) [][]int {
    //保存結果的slice
    result := make([][]int, len(res)*(len(res[0])+1))
    index := 0
    for _, v := range res {
        for i := 0; i < len(v); i++ {
            //在v的每一個元素前面插入新元素
            result[index] = insertToSlice(v, i, insertNum)
            index++
        }
        //在v最后面插入新元素
        result[index] = append(v, insertNum)
        index++
    }
    return result
}
//將元素value插入到數組nums中索引為index的位置
func insertToSlice(nums []int, index int, value int) []int {
    result := make([]int, len(nums)+1)
    copy(result[:index], nums[:index])
    result[index] = value
    copy(result[index+1:], nums[index:])
    return result
}

 

希望本文所述對大家Go語言程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
在线播放国产一区二区三区| 久久精品国产96久久久香蕉| 亚洲人午夜精品| 国产精品视频yy9099| 91夜夜揉人人捏人人添红杏| 欧美成人午夜剧场免费观看| 亚洲精品日韩丝袜精品| 成人网在线免费观看| 久久精品久久久久久国产 免费| 色综合久久久久久中文网| 成人久久18免费网站图片| 国产日韩中文字幕在线| 久久久久久久久爱| 久久全球大尺度高清视频| 亚洲精品日韩av| 中文字幕日韩视频| 色青青草原桃花久久综合| 久久伊人色综合| 中文字幕亚洲色图| 日韩一区在线视频| 91久久久久久久久| 国产一区二区丝袜高跟鞋图片| 国内精品视频一区| 久久久久国色av免费观看性色| 日本精品视频网站| 亚洲福利在线观看| 久久精品色欧美aⅴ一区二区| 久久综合88中文色鬼| 国产欧美在线看| 欧美成人精品不卡视频在线观看| 亚洲а∨天堂久久精品喷水| 欧美孕妇孕交黑巨大网站| 国产成人短视频| 亚洲精品欧美日韩专区| 俺也去精品视频在线观看| 国产盗摄xxxx视频xxx69| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲欧美日韩网| 亚洲香蕉伊综合在人在线视看| 亚洲欧美国产va在线影院| 国产成一区二区| 国内精品在线一区| 在线精品91av| 亚洲人成电影网| 青青久久aⅴ北条麻妃| 欧美综合在线第二页| 日韩美女免费线视频| 久久久久久69| 亚洲已满18点击进入在线看片| 亚洲一区二区三区久久| 国产精品户外野外| 91久久嫩草影院一区二区| 日韩成人激情在线| 精品中文字幕在线观看| 精品国内产的精品视频在线观看| 久久福利网址导航| 色偷偷综合社区| 91精品中文在线| 亚洲精品国偷自产在线99热| 97超级碰碰碰久久久| 国产精品一区二区三区在线播放| 欧美裸体xxxx极品少妇软件| 久久精品视频网站| 亚洲综合大片69999| 精品亚洲永久免费精品| 日韩av影片在线观看| 欧美一级淫片aaaaaaa视频| 91成人性视频| 亚洲精品国产综合区久久久久久久| 日日摸夜夜添一区| 国产欧美日韩高清| 欧美激情乱人伦一区| 国产区亚洲区欧美区| 日本高清视频精品| 91精品综合久久久久久五月天| 亚洲国产精品久久精品怡红院| 成人国产精品免费视频| 亚洲а∨天堂久久精品喷水| 日韩经典第一页| 久久久亚洲影院你懂的| 日韩视频免费在线观看| 日韩欧美999| 久久免费视频这里只有精品| 中文字幕在线看视频国产欧美在线看完整| 亚洲精品久久久久| 亚洲日本成人女熟在线观看| 欧美最猛性xxxxx亚洲精品| 国产精品日韩在线| 久久精品人人爽| 91精品视频在线看| 欧美一区亚洲一区| 青青草精品毛片| 国产成人一区二区三区| 奇米成人av国产一区二区三区| 日韩一二三在线视频播| 91在线免费视频| www.色综合| 欧美激情2020午夜免费观看| 97在线观看免费高清| 国产成人精品久久亚洲高清不卡| 亚洲图片欧美日产| 亚洲国产欧美日韩精品| 日韩免费视频在线观看| 91精品久久久久久久久| 国产精品流白浆视频| 久久精品成人一区二区三区| 国产精品小说在线| 最近的2019中文字幕免费一页| 中文字幕亚洲色图| 色综合伊人色综合网| 亚洲自拍av在线| 欧美激情精品久久久久久| 国产一区二区三区免费视频| 精品国产一区二区在线| 成人免费观看49www在线观看| 日韩视频在线免费| 久久久久久久影视| 在线性视频日韩欧美| 国产成人午夜视频网址| 欧亚精品在线观看| 国产精品综合久久久| 亚洲欧美日韩一区二区在线| 91av国产在线| 久久久久这里只有精品| 啊v视频在线一区二区三区| 久久99热这里只有精品国产| 中文日韩电影网站| 91免费的视频在线播放| 91亚洲va在线va天堂va国| 欧美自拍视频在线观看| 久久精品久久久久久| 亚洲欧美中文字幕| 一区二区三区四区视频| 国产69精品久久久久99| 人人爽久久涩噜噜噜网站| 在线免费观看羞羞视频一区二区| 精品亚洲va在线va天堂资源站| 丰满岳妇乱一区二区三区| 日韩精品中文字幕视频在线| 日韩电视剧在线观看免费网站| 97香蕉久久超级碰碰高清版| …久久精品99久久香蕉国产| 日韩黄色高清视频| 国产网站欧美日韩免费精品在线观看| 亚洲国产精彩中文乱码av| 国产一区二区三区视频在线观看| 欧美午夜激情视频| 日韩欧美国产骚| 欧洲美女7788成人免费视频| 97视频免费在线观看| 北条麻妃一区二区在线观看| 久久99精品久久久久久琪琪| 91中文字幕在线观看| 亚洲视频在线免费看| 成人中文字幕在线观看| 日韩久久精品成人| 91精品国产色综合久久不卡98| 日韩精品视频免费在线观看| 欧美激情久久久久| 国产日韩中文字幕在线| 久久久久日韩精品久久久男男| 日韩一区视频在线| 亚洲黄色www网站| 久久久国产精彩视频美女艺术照福利|