oc/swift 笛卡尔积算法实现

2,077 阅读1分钟

如果不想安逸的被淘汰,那就奋不顾身的去努力


笛卡尔积

笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尔积(Cartesian product),又称直积,表示为X × Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员 [1]。有关更多的描述可参考笛卡尔积--百度百科

案例

假定给出三个域:

D1=SUPERVISOR = { 张清玫,刘逸 }

D2=SPECIALITY= {计算机专业,信息专业}

D3=POSTGRADUATE = {李勇,刘晨,王敏}

则D1,D2,D3的笛卡尔积为D:

D=D1×D2×D3 ={(张清玫, 计算机专业, 李勇), (张清玫, 计算机专业, 刘晨), (张清玫, 计算机专业, 王敏), (张清玫, 信息专业, 李勇), (张清玫, 信息专业, 刘晨), (张清玫, 信息专业, 王敏), (刘逸, 计算机专业, 李勇), (刘逸, 计算机专业, 刘晨), (刘逸, 计算机专业, 王敏), (刘逸, 信息专业, 李勇), (刘逸, 信息专业, 刘晨), (刘逸, 信息专业, 王敏)}

代码

在最近的工作过程中遇到了使用该算法的场景,并以此记录一下加深对递归的使用,

OC实现
-(void)descartes:(NSArray *)dimValue result:(NSMutableArray *)result index:(NSInteger)currentIndex culList:(NSMutableArray *)culList
{
    if (currentIndex < dimValue.count - 1) {
        if ([dimValue[currentIndex] count] == 0) {
            [self descartes:dimValue result:result index:currentIndex +1 culList:culList];
        }else{
            for (NSInteger i = 0; i < [dimValue[currentIndex] count]; i ++) {
                NSMutableArray * list = [culList mutableCopy];
                [list addObject:dimValue[currentIndex][i]];
                [self descartes:dimValue result:result index:currentIndex +1 culList:list];
            }
        }
    }else if (currentIndex == dimValue.count - 1){
        if ([dimValue[currentIndex] count] == 0) {
            [result addObject:culList];
        }else{
            for (NSInteger i = 0; i < [dimValue[currentIndex] count]; i ++) {
                NSMutableArray * list = [culList mutableCopy];
                [list addObject:dimValue[currentIndex][i]];
                [result addObject:list];
            }
        }
    }
}

其中

dimValue--原始数据数组,比如[[1,2],[a,b]]

result--结果数组,比如[[1,a],[1,b],[2,a],[2,b]]

index--下标,

culList--子数据数组,用来在递归方法中组合数据,比如[1,a]

方法调用:

[self descartes:dimValue result:_result  index:0 culList:[NSMutableArray array]];
swift实现
func descarts<T>(_ dimValue:[[T]],_ result:inout [[T]],_ index:Int, _ culList:[T]){
    if index < dimValue.count - 1 {
        if dimValue[index].count == 0{
            descarts(dimValue, &result, index + 1, culList)
        }else{
            for item in dimValue[index] {
                var list = Array.init(culList)
                list.append(item)
                descarts(dimValue, &result, index + 1, list)
            }
        }
    }else if(index == dimValue.count - 1){
        if dimValue[index].count == 0 {
            result.append(culList)
        }else{
            for item in dimValue[index] {
                var list = Array.init(culList)
                list.append(item)
                result.append(list)
            }
        }
    }
}

方法调用:

var dimValue = [[1,2],["a","b"]]

var result2: [[Any]] = [[AnyObject]]()

var index = 0

var culList = [AnyObject]()

descarts(dimValue, &result2, 0, culList)