2015-12-02 42 views
1

我已經爲自己設定了RPN計算器的挑戰。我有一個列表,其中包含所使用的數字(按順序)以及另一個使用了操作符的列表(按照字符順序)。我怎樣才能創建一個函數,將從列表1中取[0],從列表2中取[0],然後從列表1中取得[1],然後從列表2取得[1] ...但是當從列表2中取值爲char時,將其轉換爲可用於計算的實際運算符? - 謝謝將char(又名:'+')轉換爲運算符

static int cal() 
{ 
    string[] store = input.Split(' '); 
    List<int> num = new List<int>(); 
    List<char> op = new List<char>(); 

    foreach (string i in store) 
    { 
     if (Convert.ToInt32(i)/Convert.ToInt32(i) == 1) 
     { 
      num.Add(Convert.ToInt32(i)); 
     } 
     else 
     { 
      op.Add(Convert.ToChar(i)); 
     } 
    }    
} 
+2

你一定要明白,一個RPN處理器需要一個堆棧嗎?你的整個方法對於2個單獨的列表是無效的,並且將永遠不會在比2個操作數複雜的RPN表達式中成功。 –

回答

1

首先,這種計算器大概適合Stack作爲數據存儲。

var theStack = new Stack<decimal>(); 

然後,如果你想從簡單開始,創建委託代表(頂部2號在堆棧中如操作)

delegate decimal BinaryOperation(decimal a, decimal b); 

您可以創建方法來實現這個二進制運算;

public decimal AddFn(decimal a, decimal b) 
{ 
    return a+b; 
} 

然後創建一個字典來映射運算符名稱和運算符函數;

var map = new Dictionary<string, BinaryOperation>(); 
map.Add("+", AddFn); 

最後,在運行程序時使用地圖;

foreach(var i in store) 
{ 
    decimal number; 
    BinaryOperation op; 

    if (decimal.TryParse(i, out number)) 
    { 
     // we've found a number 
     theStack.Push(number); 
    } 
    else if (map.TryGetValue(i, out op)) 
    { 
     // we've found a known operator; 
     var a = theStack.Pop(); 
     var b = theStack.Pop(); 
     var result = op(a,b); 
     theStack.Push(result); 
    } 
    else 
    { 
     throw new Exception("syntax error"); 
    } 
} 

因此可以不必改變推動,彈出,並與在堆棧上的值操作的核心邏輯寄存器更多的運營商與所述map變量。

+0

我會使用lambda而不是'AddFn'。 'map.Add(「+」,(a,b)=> a + b);' – CodesInChaos

+0

絕對可以使用lambda,是的!所以這會讀'map.Add(「+」,(a,b)=> a + b);' –

0

您的方法無法工作,因爲RPN計算器取決於具有基於堆棧的處理。如果您正確執行該部分,其餘部分將自行解決。一個簡單的RPN計算器中的僞碼是:

foreach(item in expression) 
{ 
    if(isNumber(item)) 
    stack.push(item.toNumber()); 
    else if(item == '+') 
    stack.push(stack.pop() + stack.pop()); 
    else if(item == '-') 
    stack.push(stack.pop() - stack.pop()); 
    else 
    throw Exception("Unknown operator: " + item); 
} 
if(stack.size != 1) 
    throw Exception("Expression was invalid"); 
print("Result is " + stack.pop()); 

如果要實現像這樣,而不是2名獨立的名單,其餘將遵循。

0

我猜,你的方法冷冷的看着這樣的:

static int cal() 

    { 
     string[] store = input.Split(' '); 
     var res = 0; 
     int value; 

     var mapOp = new Dictionary<string, Func<List<int>, int>>(); 
     mapOp.Add("+", l => l.Aggregate(0, (x, y) => x + y)); 
     mapOp.Add("-", l => l.Skip(1).Aggregate(l[0], (x, y) => x - y)); 
     var process = new Action<string,List<int>>((o, l) => 
     { 
      var operation = mapOp[o]; 
      var result = operation(l); 
      l.Clear(); 
      l.Add(result); 
     }); 
     var numbers = new List<int>(); 
     foreach (var i in store) 
     { 
      if (int.TryParse(i, out value)) 
       numbers.Add(value); 
      else 
       process(i, numbers); 
     } 
     return numbers.First(); 
    }