场景描述:
我所遇到的问题是 类似于我要抽取矩阵 并标记
大概看到的效果就是这样的函数
func findchildmatrixposition(_ childrow:Int , _ childline: Int ,_ parentmatrix:[[T]])
当然二维数组的矩阵 每个维度的个数是固定的
//从一个MN的矩阵寻找ab的抽取矩阵,其中a<M,b<N, 返回矩阵的匹配的位置和个数。
//举例推导 貌似公式是巴拉巴拉 一大堆(偷偷去搜索了下貌似靠数学手算是能搞出来的,但是程序这个 怎么会这么难呢。。。。) 我们先解决一个简单的问题 按照排列组合 我们是知道 个数的
//以 33举证
// MN 最多包含 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)