一尘不染

如何获得子集的所有可能组合?

algorithm

考虑一下 List<string>

List<string> data = new List<string>();
data.Add("Text1");
data.Add("Text2");
data.Add("Text3");
data.Add("Text4");

我遇到的问题是:如何获得列表子集的每种组合?有点像这样:

#Subset Dimension 4
Text1;Text2;Text3;Text4

#Subset Dimension 3
Text1;Text2;Text3;
Text1;Text2;Text4;
Text1;Text3;Text4;
Text2;Text3;Text4;

#Subset Dimension 2
Text1;Text2;
Text1;Text3;
Text1;Text4;
Text2;Text3;
Text2;Text4;

#Subset Dimension 1
Text1;
Text2;
Text3;
Text4;

我想出了一个体面的解决方案,值得在这里分享一下。


阅读 189

收藏
2020-07-28

共1个答案

一尘不染

我认为,这个问题的答案需要一些性能测试。我会去的。这是 社区Wiki ,请随时进行更新。

void PerfTest()
{
    var list = Enumerable.Range(0, 21).ToList();

    var t1 = GetDurationInMs(list.SubSets_LB);
    var t2 = GetDurationInMs(list.SubSets_Jodrell2);
    var t3 = GetDurationInMs(() => list.CalcCombinations(20));

    Console.WriteLine("{0}\n{1}\n{2}", t1, t2, t3);
}

long GetDurationInMs(Func<IEnumerable<IEnumerable<int>>> fxn)
{
    fxn(); //JIT???
    var count = 0;

    var sw = Stopwatch.StartNew();
    foreach (var ss in fxn())
    {
        count = ss.Sum();
    }
    return sw.ElapsedMilliseconds;
}

输出:

1281
1604 (_Jodrell not _Jodrell2)
6817

乔德雷尔的更新

我已经建立了发布模式,即优化。当我通过Visual Studio运行时,在1或2之间没有得到一致的偏差,但是在重复运行LB的答案后,我得到的答案接近,

1190
1260
more

但是如果我从命令行而不是通过Visual Studio运行测试工具,我会得到更多这样的结果

987
879
still more
2020-07-28