首页 > 解决方案 > 使用枚举查找数组中的所有组合(Swift 5)

问题描述

我在 C# 中有一些代码正是我喜欢做的:枚举数组中给定长度的所有组合(重复)。像这样:

public static IEnumerable<IEnumerable<int>> CombinationsWithRepition(IEnumerable<int> input, int length)
{
    if (length <= 0)
        yield return new List<int>();
    else
    {
        foreach (int i in input)
            foreach (IEnumerable<int> c in CombinationsWithRepition(input, length - 1))
            {
                List<int> list = new List<int>();
                list.Add(i);
                list.AddRange(c);
                yield return list;
            }
    }
}

用法:

foreach (var c in CombinationsWithRepition(new int[] { 0, 1, 2 }, 2))
{
    foreach (var x in c)
        Console.Write(x + " : ");

    Console.WriteLine("");
}

输出:

0 : 0
0 : 1
0 : 2
1 : 0
1 : 1
1 : 2
2 : 0
2 : 1
2 : 2

现在我想将它移植到 swift 5,但我失败了。我在网上搜索,但我只能找到没有重复的解决方案或创建一个巨大数组的解决方案。枚举整个事物的能力很重要(不作为数组或包含所有结果的列表输出)。我不知道如何将“yield”移植到 swift 代码。

这是我发现的最接近的: 如何在 Swift 中返回一个序列?

先感谢您

标签: arraysswiftfindcombinationsenumeration

解决方案


在具有 的语言中yield,它是对返回结果的调用函数的回调。当前函数的状态保持不变,并在yield返回时继续。

我们可以用闭包回调在 Swift 中实现类似的东西。

这几乎是您日常工作的直接翻译:

func combinationsWithRepetition(_ input: [Int], length: Int, yield: ([Int]) -> ()) {
    if length <= 0 {
        yield([])
    }
    else {
        for i in input {
            combinationsWithRepetition(input, length: length - 1) { c in
                var list = [Int]()
                list.append(i)
                list += c
                yield(list)
            }
        }
    }
}

combinationsWithRepetition([0, 1, 2], length: 2) { c in
    print(c.map(String.init).joined(separator: " : "))
}

输出:

0 : 0
0 : 1
0 : 2
1 : 0
1 : 1
1 : 2
2 : 0
2 : 1
2 : 2

有时调用者想要控制正在让步的函数。如果您希望能够停止该函数,您可以让yield回调返回一个Bool告诉屈服函数是否应该继续。

考虑这个例子:

// Generate squares until told to stop
func squares(_ yield: (_ n: Int) -> Bool) {
    var i = 1
    var run = true
    while run {
        run = yield(i * i)
        i += 1
    }
}

// print squares until they exceed 200
squares() { n -> Bool in
    print(n)
    return n < 200
}
1
4
9
16
25
36
49
64
81
100
121
144
169
196
225

推荐阅读