2011-10-04 52 views
1

好吧,今天是我的思想無法正常工作的那些日子之一。
我不能讓這個工作(:C#遞歸得到正確的計數

class Program 
{ 
    static private List<KeyValuePair<int, double>> _list; 
    static protected List<KeyValuePair<int, double>> list 
    { 
     get 
     { 
      if (_list == null) 
      { 
       _list = new List<KeyValuePair<int, double>>(); 

       _list.Add(new KeyValuePair<int, double>(1, 11.60));           
       _list.Add(new KeyValuePair<int, double>(2, 11.20)); 
       _list.Add(new KeyValuePair<int, double>(3, 13.00)); 
       _list.Add(new KeyValuePair<int, double>(4, 13.60)); 
       _list.Add(new KeyValuePair<int, double>(5, 15.90)); 
       _list.Add(new KeyValuePair<int, double>(6, 16.10)); 
       _list.Add(new KeyValuePair<int, double>(7, 19.10)); 
       _list.Add(new KeyValuePair<int, double>(8, 19.10)); 
       _list.Add(new KeyValuePair<int, double>(9, 19.10)); 
       _list.Add(new KeyValuePair<int, double>(10, 21.00)); 
       _list.Add(new KeyValuePair<int, double>(11, 23.00)); 
      } 

      return _list; 
     } 
    } 

    static void Main(string[] args) 
    { 
     Program p = new Program(); 

     int value = 27; 
     double d = p.GetCost(value); 
    } 

    public double GetCost(int tot) 
    { 
     double cost = 0; 
     if (tot < 1) 
      return list[tot-1].Value; 

     cost += GetCost(tot - list.Count); 
     return cost; 
    }   
} 

所以在概念上,我需要設置遞歸GETCOST程序才能正常工作 ,這樣它會調用自身,並從得到正確的值(第二列) LIST 並將其添加到遞歸調用者。

預期成果

如果 「值」 是 總應該是$ 19.10 $從KeyParValue 19.10 (8 - 19.10)

如果 「值」 是 總應該是$ 36.60 從KeyParValue(11 - 23.00)$ 23±11.60 + KeyParValue(1 - 13.60)

如果 「值」 是 總計應該是$ 61.90
$ 23 + $ 23 + $ 15.90; 從KeyParValue(11 - 23.00)+ KeyParValue(11 - 23.00)+ KeyParValue(5 - 15.90)

由於先進, F.

+0

如果該值爲12應該是34.60(11 - 23 + 1 - 11-60 = 34.60);) – Sascha

+1

爲什麼密鑰值對的列表,作爲實際使用的字典對象相對? –

+0

你需要列表[n] .Key是要比較的點。我第二個保羅問題,字典可能會使整個事情更清楚。 – Sascha

回答

2

這是有問題入手:

if (tot < 1) 
    return list[tot-1].Value; 

如果tot小於1,則tot - 1小於零,並且list[tot - 1]會拋出異常。

實際上想:

if (tot < 1) 
    return list[tot].Value - 1; 

?這仍然只是去工作,如果tot是0,你要知道...

這不是真的我清楚你的代碼是指在首位實現 - 但我用強烈懷疑它會更清晰沒有遞歸。也許你可以描述你想要做什麼?

+0

不是真的......會發生什麼是一個數組的第一個入口不是1,但它是0.在這個例子中,數組第一列是順序的,該數組的值不是順序的,所以做「值 - 1」將給出錯誤的結果 –

+0

@Filu:你沒有解釋你想要做什麼,所以很難理解什麼是「錯誤」的結果開始 - 但你明白爲什麼第一個代碼片段不能*可能*工作? –

0

也許你想是這樣的:

public static double GetCost (int tot) { 
    double cost = 0; 
    if (tot > list.Count()) 
    cost += ((int)tot/list.Count()) * list[list.Count() - 1].Value; // add n times the max value 
    if (tot % list.Count() > 0) 
    cost += list[(tot % list.Count()) - 1].Value; // should add the remainder 
    return cost; 
} 

現在經過在Visual Studio。你的第二個例子是關閉的。它應該是34.60(23.00 + 11.60 = 34.60)。正如Jon指出的那樣,0存在一個問題。可能拋出一個ArgumentException或者返回零,無論哪個符合你的需求。

編輯: 從你對Jon的回答的評論我認爲,列表不是你的樣品。這意味着,計算總數必須基於關鍵而不是索引。第一槍(給你預期的結果):

public static double GetCost (int tot) { 
    int maxKey = list.Aggregate ((current, next) => next.Key > current.Key ? next : current).Key; 
    double cost = 0; 

    if (tot > maxKey) 
    cost += ((int)tot/maxKey) * list.Where (kvp => kvp.Key == maxKey).First().Value; // add n times the max value 
    if (tot % maxKey > 0) 
    cost += list.Where (kvp => kvp.Key == tot % maxKey).First().Value; // should add the remainder 
    return cost; 
} 

看起來不一樣。該函數假定one和maxKey之間的所有鍵都存在。如果不是,那麼缺少所需密鑰的情況將會失敗。

2

這將返回您在預期結果部分中描述的內容。但感覺就像你真正想要實現的東西有些不同。

public double GetCost(int tot) 
{ 
    double cost = 0; 
    while(tot > 0) { 
     cost += tot >= 11 
       ? list[11] 
       : list[tot]; 
     tot -= tot % 11; 
    } 
    return cost; 
}  
+1

我認爲減量線應該是'tot - = tot> = 11? 11:tot'。 – Kevin

0

你不需要遞歸或循環...

public double GetCost(int tot) 
{ 
    int multipliers; 
    int count; 
    double cost; 
    var dictionary = list.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); 

    count = list.Count; 
    multipliers = tot/count; 
    cost = multipliers * dictionary[count]; 
    tot %= count; 
    if (dictionary.ContainsKey(tot)) 
    { 
     cost += dictionary[tot]; 
    } 
    return cost; 
} 

編輯:修正了 「TOT == 0問題」。

0

我會去與下面的東西,並刪除遞歸。然而,因爲問題是關於遞歸的,所以我也包含了遞歸邏輯。真的,它只是你的列表導致邏輯問題。

class Program 
{ 
    private static Dictionary<int, double> _dollarValues; 
    protected static Dictionary<int, double> DollarValues 
    { 
     get 
     { 
      if (_dollarValues == null) 
      { 
       _dollarValues = new Dictionary<int, double>(); 

       _dollarValues.Add(1, 11.60); 
       _dollarValues.Add(2, 11.20); 
       _dollarValues.Add(3, 13.00); 
       _dollarValues.Add(4, 13.60); 
       _dollarValues.Add(5, 15.90); 
       _dollarValues.Add(6, 16.10); 
       _dollarValues.Add(7, 19.10); 
       _dollarValues.Add(8, 19.10); 
       _dollarValues.Add(9, 19.10); 
       _dollarValues.Add(10, 21.00); 
       _dollarValues.Add(11, 23.00); 
      } 

      return _dollarValues; 
     } 
    } 

    private static int _maxKey = 0; 

    private static void Main(string[] args) 
    { 
     _maxKey = DollarValues.Max(key => key.Key); 
     int value = 27; 
     double cost = 0; //GetCost(value); If I wanted to use recursion instead. 
     while(value > 0) 
     { 
      int key = value >= _maxKey ? _maxKey : value; 
      cost += DollarValues[key]; 
      value -= key; 
     } 
    } 
      //Recursion if I had to 
    public static double GetCost(int value) 
    { 
     double cost = 0; 
     cost += 
         value >= _maxKey ? 
           DollarValues[_maxKey] + GetCost(value - _maxKey) 
           : DollarValues[value]; 
     return cost; 
    } 
}