2010-01-24 38 views
5

我的最终目标是将下面的代码转换为C#,但我想通过学习python语法来完成自己的工作。我明白代码是递归的。Python to C#代码说明

该代码产生具有k个变量的n次多项式。更具体地说是每个变量的指数列表。

def multichoose(n,k): 
    if k < 0 or n < 0: return "Error" 
    if not k: return [[0]*n] 
    if not n: return [] 
    if n == 1: return [[k]] 
    return [[0]+val for val in multichoose(n-1,k)] + \ 
     [[val[0]+1]+val[1:] for val in multichoose(n,k-1)] 

这里是我到目前为止的转换:

public double[] MultiChoose(int n, int k) 
{ 
    if (k < 0 || n < 0) 
    { 
     throw new Exception(); 
    } 

    if (k == 0) 
    { 
     return [[0]*n]; // I have no idea what the [[0]*n] syntax means 
    } 

    if (n == 0) 
    { 
     return new double[0]; // I think this is just an empty array 
    } 

    if (n == 1) 
    { 
     return new double[1] {k}; // I think this is just an empty array 
    } 

    //Part I don't understand 
    return [[0]+val for val in MultiChoose(n-1,k)] + \ 
     [[val[0]+1]+val[1:] for val in MultiChoose(n,k-1)] 
} 

我的问题是:如何转换的Python代码?

+0

那么什么是你的问题? – 2010-01-24 20:58:23

回答

3

我会用LINQ在C#转换代码:

  • []是空列表。

    Enumerable.Empty<T>() 
    
  • [x]是包含单一项目的列表中,x。

    Enumerable.Repeat(x, 1) 
    
  • [[0]*n]是包含含有0

    Enumerable.Repeat(Enumerable.Repeat(0, n), 1) 
    
  • [X for Y in Z] n个拷贝的列表的列表理解列表。

    from Y in Z select X 
        - or - 
    Z.Select(Y => X); 
    
  • X + Y(其中X和Y是列表)是连接列表。

    Enumerable.Concat(X, Y) 
    

MultiChoose的签名是:

public IEnumerable<IEnumerable<double>> MultiChoose(int n, int k); 
+0

Nice =)是否可以用泛型来做到这一点,即使用'Enumerable '(或'IEnumerable ')而不是'Enumerable'? – 2010-01-24 21:07:05

+0

Enumerable是一个静态类。它有通用的方法,产生IEnumerable 的(我省略了泛型类型参数,可以推断它们),所以是的。 – dtb 2010-01-24 21:08:00

+0

我认为你得到了[[0] * n]错误,它应该Enumerable.Repeat(Enumerable.Repeat(0,n),1),外部重复可能根本就没有必要。 – 2010-01-24 21:22:27

1

[0] * n返回一个列表,带有n 0 s。 []是一个空列表。 [[k]]是一个列表,其中包含一个包含k的列表。

最后一部分使用列表解析。列表理解的基本形式如下:

[<new value> for <name> in <sequence>] 
[<new value> for <name> in <sequence> if <condition>] 

它每创建一个包含新值的新列表,可选条件为true。

1

一些评论:

蟒蛇return "Error"不抛出异常。它返回字符串值“Error”。

蟒蛇if not k:不等于if (k == 0)有更多的事情是“不”,如空列表,None值等(这可能在这种情况下没有什么不同)。

pythons foo = [for x in bar]是一个列表理解。它相当于:

foo = [] 
for x in bar: 
    foo.append(x) 
1

我发现这一个有趣的和经过一些帮助了解Python代码后,我采取了刺戳它。需要C#3.0和.NET Framework 3.5。

public static IEnumerable<IEnumerable<int>> MultiChoose(int n, int k) 
{ 
    if (k < 0 || n < 0) throw new Exception(); 
    if (k == 0) return Enumerable.Repeat(Enumerable.Repeat(0, n), 1); 
    if (n == 0) return Enumerable.Repeat(Enumerable.Empty<int>(), 0); 
    if (n == 1) return Enumerable.Repeat(Enumerable.Repeat(k, 1), 1); 

    return (from val in MultiChoose(n - 1, k) select new [] { 0 }.Concat(val)) 
     .Concat(from val in MultiChoose(n, k - 1) select new [] { val.First() + 1 }.Concat(val.Skip(1))); 
} 

下面是红宝石

def multichoose(n,k) 
    if k<0 || n<0: raise "Error" end 
    if k==0: return [[0]*n] end 
    if n==0: return [] end 
    if n==1: return [[k]] end 
    multichoose(n-1,k).map{|val| [0]+val} + \ 
    multichoose(n,k-1).map{|val| [val.first+1]+val[1..-1]} 
end 

和一些输出的例子一个版本:

>> multichoose(2,2) 
=> [[0, 2], [1, 1], [2, 0]] 
>> multichoose(3,2) 
=> [[0, 0, 2], [0, 1, 1], [0, 2, 0], [1, 0, 1], [1, 1, 0], [2, 0, 0]] 
>> multichoose(3,3) 
=> [[0, 0, 3], [0, 1, 2], [0, 2, 1], [0, 3, 0], [1, 0, 2], [1, 1, 1], [1, 2, 0], [2, 0, 1], [2, 1, 0], [3, 0, 0]] 
+0

+1 - 非常好。 – dtb 2010-01-25 01:29:01