将char(又名:' +')转换为运算符

时间:2015-12-02 10:50:16

标签: c# function rpn

我已经为自己设定了RPN计算器的挑战。我有一个列表,其中包含使用的数字(按顺序)和另一个使用运算符的列表(按顺序,作为字符)。如何创建一个从list1获取[0]的函数,从list2获取[0],然后从list1获取[1],然后从list2获取[1] ......但是当从list2获取值作为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));
        }
    }            
}

3 个答案:

答案 0 :(得分: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变量注册更多运算符,而无需更改推送,弹出和操作堆栈值的核心逻辑。

答案 1 :(得分: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个单独的列表,其余的将遵循。

答案 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();
    }