swift-排列组合全排列算法矩阵应用

场景描述:

我所遇到的问题是 类似于我要抽取矩阵 并标记
大概看到的效果就是这样的函数

func findchildmatrixposition(_ childrow:Int , _ childline: Int ,_ parentmatrix:[[T]])

当然二维数组的矩阵 每个维度的个数是固定的

//从一个MN的矩阵寻找ab的抽取矩阵,其中a<M,b<N, 返回矩阵的匹配的位置和个数。
//举例推导 貌似公式是巴拉巴拉 一大堆(偷偷去搜索了下貌似靠数学手算是能搞出来的,但是程序这个 怎么会这么难呢。。。。) 我们先解决一个简单的问题 按照排列组合 我们是知道 个数的
//以 33举证
// M
N 最多包含 ab 子矩阵个数 3 * 3 22 c 32 * c 32 9种
// 生成 需要标记的模板数组
[ [ _ , _ ,_ ],
[_ , _ , _ ],
[_ , _ , _]] 类似这样的模板矩阵 用于标记

// 思路 先算出 有多少种 无序排列组合 如 2*2的矩阵 对吧 先考虑一维的行无序筛选 很容易 [0,1] [0,2] [1,2] 好的 3种 列同理 [0,1] [0,2] [1,2]

//如何实现 组合 如 给一个 5 要选择 2 返回所有的组合无序列表 看现成的方案多为全排列 即 类似这样的 [[1,2],[3,4]] 12 21 是同一种组合

func getcombies(_ n:Int,_ k:Int) -> [[Int]]

// 抽取矩阵 我们将 行筛选和列筛选 继续组合 [[0,1],[0,1]] 这个看起来像什么 不就是我们要的子矩阵么[[0,1],[0,2]] [[0,1],[1,2]] 这样的组合我们可以得到 九组
// 如何标记 这里行列都列举出来了 根本不怕找不到标记对吧 类似的我们就需要写出这样的函数实现这样的效果 如 [[0,1],[0,1]]
[ [ * , * ,_ ],
[*, * , _ ],
[_ , _ , _]]

func chooseMatrix<T>(_ rowarea:[Int] , _ linearea:[Int] ,_ parentmatrix:[[T]] , _ marktemmarix:inout [[String]])

完整的实现方案

import UIKit

import Foundation

//列  1*4 位的  1 * 3  c 4  选3  4 种





//从一个M*N的矩阵中查找是否有a*b的子矩阵,其中a<M,b<N, 返回矩阵的匹配的位置和个数。

//举例推导  貌似公式是

// M*N 最多包含 a*b 子矩阵个数 3 * 3 2*2  c 32 * c  32  9种

// 思路 先算出 有多少种 无序排列组合

//  抽取矩阵

let   c_placeholder = "*"

struct  MatrixElem{

    var  ele:Int!

    var  pos:IndexPath!

    

    func judgeelmentinline(_ nextelment:MatrixElem) -> Bool {

        

        return  nextelment.pos.section == self.pos.section

        

        

        

    }

    

}

var   testparentmatrix = [[1,3,4],[2,4,6],[3,5,6],[2,5,7]]





func   judgeleaglematrix<T>(_ matrix:[[T]]) -> Bool {

    

    if matrix.count  == 0 {

        

        return  false

        

    }

    var  linecount = matrix[0].count

    if linecount == 0  {

        return false

    }

    

    var curlinecount = linecount

    for i in 1 ..< matrix.count{

        

        curlinecount = matrix[i].count

        if curlinecount != linecount {

            return false

        }

        linecount = curlinecount

    }

    return  curlinecount == linecount

}

func  displaymatrix<T>(_ matrix:[[T]] ){

    

    if !judgeleaglematrix(matrix){

        print("构造M*N矩阵不合法")

        return

    }

    for  i in 0 ..< matrix.count {

        for j in 0 ..< matrix[i].count{

            

            print("\(matrix[i][j])", terminator: "")

            if  i <= matrix.count - 1 && j != matrix[i].count - 1 {

                

                print(",", terminator: "")

                

            }

            else {

                print()

            }

        }

    }

    

}

extension Array where Element: Equatable {

    func contains(array: [Element]) -> Bool {

        for item in array {

            if !self.contains(item) { return false }

        }

        return true

    }

    

    

    

}

//displaymatrix(testparentmatrix)



//2*2

func  findchildmatrixposition(_ childrow:Int , _ childline: Int ,_ parentmatrix:[[Int]])  {

    if   childrow  <= 0 || childrow > parentmatrix.count  || childline <= 0 || childline > parentmatrix[0].count  {

        print("参数不合法,或者不存在 该子矩阵")

        return

    }

    displaymatrix(parentmatrix)

    let   parentrow = parentmatrix.count

    let parentline = parentmatrix[0].count

    let   subcount =  (fac(parentline)/(fac(parentline-childline)*fac(childline))) * (fac(parentrow)/(fac(parentrow-childrow)*fac(childrow)))

    print("M*N \(parentrow):\(parentline)包含子矩阵a*b \(childrow):\(childline)的个数是 :\(subcount)个")

    //子模板标记 数组

    

    let  rowchoose = getcombies(parentrow, childrow)

    

    let  linechoose = getcombies(parentline, childline)

    

    

    var  allmatrix  = [[[String]]]()

    for _ in 0..<subcount{

        var  displayposition = [[String]]()

        for  _ in 0 ..< parentrow {

            

            var  itempic =  [String]()

            for _ in 0 ..< parentline{

                

                itempic.append(c_placeholder)

                

            }

            displayposition.append(itempic)

            

        }

        allmatrix.append(displayposition)

        

        

    }

    print(subcount)

    //下面可以不写了 只要返回 行列的筛选 就可以标记了

    print("子矩阵如下:")

    print("行筛选:\(rowchoose)","列筛选\(linechoose)")

    

    var  allposition = [[[Int]]]()

    for  rowitem in rowchoose {

          var  curposiotion = [[Int]]()

          curposiotion.append(rowitem)

            for  lineitem in linechoose {

                curposiotion.append(lineitem)

                

            }

        

        allposition.append(curposiotion)

    }

    

    var   combiesPositionValue = [[[Int]]]()

    

    print("行列抽取位置索引如下------------")

    for i  in  0 ..< allposition.count {

        //表示行列的组合

            let  indexmatrix = allposition[i]

        

            let  rowindex = indexmatrix.first!

       

        

            for j in 1..<indexmatrix.count {

                var  positoncobies = [[Int]]()

                positoncobies.append(rowindex)

                positoncobies.append(indexmatrix[j])

                print(positoncobies)

                

                chooseMatrix(rowindex, indexmatrix[j], parentmatrix,&allmatrix[i],c_placeholder)

                

                

                displaymatrix(allmatrix[i])

                combiesPositionValue.append(positoncobies)



            }

        

            print()

    }

    

    

    

    

}



func    comparewithstr<T>(_ matrix:[[T]] ) -> String {

    var  res = ""

    for i  in 0..<matrix.count {

        for j  in 0..<matrix[i].count {

            

           let   t  = "\(matrix[i][j])"

            if t != c_placeholder {

            res.append("\(matrix[i][j])")

            }

            

        }

    }

    

    return res

    

}





func   slicematrix(_ abmatrix:[[Int]] , _ markmatrix:[[String]] ) -> Bool{

    let   tempslice1 = comparewithstr(abmatrix)

    let   tempslice2 = comparewithstr(markmatrix)

    

    return  tempslice1 == tempslice2

    

    

    

}



//  传的  选取的行 数组  列数组

func    chooseMatrix<T>(_ rowarea:[Int] , _ linearea:[Int] ,_ parentmatrix:[[T]] , _ marktemmarix:inout [[String]] ,_ placeholder: String) {

    



    

    var  res:Bool = false

    

    for i  in 0..<parentmatrix.count {

        

        

        for  j in 0..<parentmatrix[i].count {

       

            

            res = rowarea.contains(i) && linearea.contains(j)

            if res {

                let indexrow = rowarea.firstIndex(of: i)

                let indexline = linearea.firstIndex(of: j)

                

                marktemmarix[i][j] =  "\( parentmatrix[rowarea[indexrow!]][linearea[indexline!]])"

            }

            else{

                

                

                

                marktemmarix[i][j] = placeholder

                

                

            }

            

        }

        

        

        

        

    }

    

    

    

}



func   fac(_ value:Int) -> Int{

    

    if value == 0 {return 1}

    return  value * fac(value-1)

}

func  combine(_  lists:inout [[Int]], _ list:inout [Int] ,_ start:Int,_ n:Int,_ k: Int) {

    

    if k == 0 {

        

        lists.append(list)

        return

    }

    for  i in start ..< n {

        list.append(i)

        combine(&lists, &list, i+1, n, k-1)

        list.remove(at: list.count - 1)

    }

    

    

}

func   getcombies(_ n:Int,_ k:Int) ->  [[Int]]{

    

    var result  =   [[Int]]()

    var newvalue = [Int]()

    combine(&result, &newvalue, 0, n, k)

    return  result

}







func   findJudgematrix(_ abmatrix:[[Int]] , _  parentmatrix:[[Int]]) {

     if !judgeleaglematrix(abmatrix) {

         print("子矩阵 不合法 ")

        return

        

    }



     displaymatrix(parentmatrix)

     print()

    

     print("查找矩阵")

     displaymatrix(abmatrix)

    

     let  firstindex = abmatrix[0][0]

     let  positionindex =  markpostionElment(firstindex, parentmatrix)

    

    if positionindex.count == 0 {

        print("无此子矩阵")

        

        return

    }

 

    let   parentrow = parentmatrix.count

    let parentline = parentmatrix[0].count

    let  childrow = abmatrix.count

    let  childline = abmatrix[0].count

    let   subcount =  (fac(parentline)/(fac(parentline-childline)*fac(childline))) * (fac(parentrow)/(fac(parentrow-childrow)*fac(childrow)))

//    print("M*N \(parentrow):\(parentline)包含子矩阵a*b \(childrow):\(childline)的个数是 :\(subcount)个")

    //子模板标记 数组

    

 

    

    let  rowchoose = getcombies(parentrow, childrow)

    

    let  linechoose = getcombies(parentline, childline)

    

    

    var  allmatrix  = [[[String]]]()

    for _ in 0..<subcount{

        var  displayposition = [[String]]()

        for  _ in 0 ..< parentrow {

            

            var  itempic =  [String]()

            for _ in 0 ..< parentline{

                

                itempic.append(c_placeholder)

                

            }

            displayposition.append(itempic)

            

        }

        allmatrix.append(displayposition)

        

        

    }

//    print(subcount)

//    //下面可以不写了 只要返回 行列的筛选 就可以标记了

//    print("子矩阵如下:")

//    print("行筛选:\(rowchoose)","列筛选\(linechoose)")

    

    var  allposition = [[[Int]]]()

    for  rowitem in rowchoose {

        var  curposiotion = [[Int]]()

        curposiotion.append(rowitem)

        for  lineitem in linechoose {

            curposiotion.append(lineitem)

            

        }

        

        allposition.append(curposiotion)

    }

    

    

    var   combiesPositionValue = [[[Int]]]()

    var    result = 0

//    print("行列抽取位置索引如下------------")

    for i  in  0 ..< allposition.count {

        //表示行列的组合

        let  indexmatrix = allposition[i]

        

        let  rowindex = indexmatrix.first!

        

        

        for j in 1..<indexmatrix.count {

            var  positoncobies = [[Int]]()

            positoncobies.append(rowindex)

            positoncobies.append(indexmatrix[j])

//            print(positoncobies)

            

            chooseMatrix(rowindex, indexmatrix[j], parentmatrix,&allmatrix[i],c_placeholder)

            if slicematrix(abmatrix, allmatrix[i]) {

                result = result + 1

                combiesPositionValue.append(positoncobies)

                print("在原矩阵的位置标记如下:")

                displaymatrix(allmatrix[i])

                print("行筛选:\(positoncobies.first!)")

                print("列筛选:\(positoncobies.last!)")

            }

            

            

            

        

            

            

        }

        

     

    }

    

    if result == 0  {

        

        

        print("没有相关子矩阵")

    }else{

        

        

        print("这样的矩阵存在 \(result)个")

    }

    

    

}





func    flatmap(_ abmatrix:[[Int]] ,_ parentmarkmatrix:[[Int]]) -> Bool {

    

    

     return parentmarkmatrix.contains(array: abmatrix)



    

}





//先查找行

func  findnextvaluesbyrow(_ index:IndexPath , _ subrows:[Int] ,_ subline:Int,_ parentmatrix:[[Int]] ) ->Bool{

    

    var  rowcount = [Int]()

    //每一行的查找个数

    for ele in subrows {

        

   

    

        var  elementexusit = 0

        

        for   j in 0..<parentmatrix[index.row].count{

            

            if  ele == parentmatrix[index.row][j] {

                

                

                elementexusit = elementexusit + 1

               

            }

            

        }

        rowcount.append(elementexusit)

        

        

    

    }

    

    

    

    return    rowcount.count == subrows.count

    

}









func   markpostionElment(_ elment:Int,_ parentmatrix:[[Int]]) -> [IndexPath]{

    var    indexpathvalue = [IndexPath]()

    for  i in 0..<parentmatrix.count{

        

        for   j in 0..<parentmatrix[i].count{

            

            if  elment == parentmatrix[i][j]{

                

                let   index = IndexPath.init(row: j, section: i)

                indexpathvalue.append(index)

                

                

                

            }

            

        }

        

        

    }

    return indexpathvalue

    

}











//findchildmatrixposition(4, 3, testparentmatrix)







var  matrixtest1 = [[2],[3],[5],[2],[6]]

var  matrixtest2 = [[2,3,5,2,6]]

var  matrixtest3 = [[2,3,1],[5,7,3],[9,6,1]]

var  matrixtest4 = [[2,3,5,8],[5,2,4,7],[6,1,3,9],[3,5,8,7],[11,9,8,4],[4,9,8,6]]





//findchildmatrixposition(2, 3, matrixtest3)

findJudgematrix([[3,5],[2,4]], matrixtest4)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342