你可以在C#编写一个置换函数一样优雅?你可以、函数、优雅

2023-09-11 03:52:18 作者:疼了╮自然会松手

我喜欢这6行的解决方案很多,我试图复制它在C#中。基本上,它permutes数组的元素:

 高清置换(XS,pre = []):
  如果len(XS)​​== 0:
     收益pre
  对于I,X在历数(XS):
     为的y置换(XS [我] + XS [我+ 1:],pre + [X]):
        工艺成品率Y
 

解决方案

嗯,这大概是没怎么我会一直写,但是:

 静态的IEnumerable< T []>置换< T>(这件T [] XS,则params T [] pre){
    如果(xs.Length == 0)收益回报pre;
    的for(int i = 0; I< xs.Length;我++){
        的foreach(T []的y置换(xs.Take(ⅰ).Union(xs.Skip第(i + 1))。的ToArray(),pre.Union(新[] {XS [I]})。的ToArray())){
            得到的回报ÿ;
        }
    }
}
 

回复您的评论;我不的完全的明确的问题;如果你的意思是这是为什么有用吗? - 除其他事项外,还有一系列的暴力场景在那里你会想尝试不同的排列组合 - 例如,对于喜欢旅游的销售人员小排序问题(是不是足够大,以保证一个更复杂的解决方案),你可能要检查它是否是最好去{基,A,B,C,基地},{基地,A,C,B,基地},{基地,B,A,C,基}等。

告别手敲 SQL GPT 3 自动帮你写

如果你的意思是我将如何使用这个方法? - 未经测试,但这样的:

  INT []值= {1,2,3};
的foreach(INT []烫发的values​​.Permute()){
   WriteArray(烫发);
}

无效WriteArray< T>(T []值){
    StringBuilder的SB =新的StringBuilder();
    的foreach(中值的T值){
        sb.Append(值).Append(,);
    }
    Console.WriteLine(某人);
}
 

如果你的意思是它是如何工作的? - 迭代器块(收益率回报)本身就是一个复杂的课题 - 乔恩有一个免费的章节(6)的在他的书中的,虽然。的code,其余是非常喜欢你原来的问题 - 只需使用LINQ提供 + 的道德当量(数组)

I like this 6 line solution a lot and am trying to replicate it in C#. Basically, it permutes the elements of an array:

def permute(xs, pre=[]):
  if len(xs) == 0:
     yield pre
  for i, x in enumerate(xs):
     for y in permute(xs[:i] + xs[i+1:], pre + [x]):
        yield y

解决方案

Well, it probably isn't how I'd write it, but:

static IEnumerable<T[]> Permute<T>(this T[] xs, params T[] pre) {
    if (xs.Length == 0) yield return pre;
    for (int i = 0; i < xs.Length; i++) {
        foreach (T[] y in Permute(xs.Take(i).Union(xs.Skip(i+1)).ToArray(), pre.Union(new[] { xs[i] }).ToArray())) {
            yield return y;
        }
    }
}

Re your comment; I'm not entirely clear on the question; if you mean "why is this useful?" - among other things, there are a range of brute-force scenarios where you would want to try different permutations - for example, for small ordering problems like travelling sales person (that aren't big enough to warrant a more sophisticated solution), you might want to check whether it is best to go {base,A,B,C,base}, {base,A,C,B,base},{base,B,A,C,base}, etc.

If you mean "how would I use this method?" - untested, but something like:

int[] values = {1,2,3};
foreach(int[] perm in values.Permute()) {
   WriteArray(perm);
}

void WriteArray<T>(T[] values) {
    StringBuilder sb = new StringBuilder();
    foreach(T value in values) {
        sb.Append(value).Append(", ");
    }
    Console.WriteLine(sb);
}

If you mean "how does it work?" - iterator blocks (yield return) are a complex subject in themselves - Jon has a free chapter (6) in his book, though. The rest of the code is very much like your original question - just using LINQ to provide the moral equivalent of + (for arrays).

 
精彩推荐
图片推荐