2015-12-02 135 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(); 
    }