2010-01-24 37 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