评估公式,但忽略数学运算和括号的顺序

问题描述:

我正在尝试编写一个忽略数学运算和括号顺序的函数。该函数仅从左到右评估运算符。 (对于+-*/^评估公式,但忽略数学运算和括号的顺序

示例1:5 - 3 * 8^2返回256
示例2:4/2 - 1^2 + (5*3)返回18

这里就是我所做的:

function out = calc(num) 
    [curNum, num] = strtok(num, '+-*/^'); 
    out = str2num(curNum); 
    while ~isempty(num) 
     sign = num(1); 
     [curNum, num] = strtok(num, '+-*/^'); 
     switch sign 
     case '+'  
      out = out + str2num(curNum); 
     case'-' 
      out = out - str2num(curNum); 
     case '*' 
      out = out.*str2num(curNum); 
     case '/' 
      out = out./str2num(curNum); 
     case '^' 
      out = out.^str2num(curNum); 
     end 
    end 
end 

我的功能不会忽略左到右的规则。我该如何纠正?

+2

的就是你得到的输出?当您提出问题时,包含这些信息很重要。首先,你不要在现在的代码中用'^'运算符分割字符串。 – eigenchris 2015-02-23 18:12:38

您的第一个示例失败,因为您正在使用+-*/分隔符分割字符串,而您省略了^。您应该将其更改为第2行和第6行中的+-*/^

第二个示例失败,因为您不告诉程序如何忽略()字符。您应该在输入switch声明之前去掉它们。

curNum = strrep(curNum,'(','') 
curNum = strrep(curNum,')','') 
switch sign 
... 
+0

谢谢!我忘了去掉括号。 – timrow 2015-02-23 18:46:08

这是一种没有任何switch语句的方法。

str = '4/2 - 1^2 + (5*3)' 

%// get rid of spaces and brackets 
str(regexp(str,'[()]')) = [] 

%// get numbers 
[numbers, operators] = regexp(str, '\d+', 'match','split') 

%// get number of numbers 
n = numel(numbers); 

%// reorder string with numbers closing brackets and operators 
newStr = [numbers; repmat({')'},1,n); operators(2:end)]; 

%// add opening brackets at the beginning 
newStr = [repmat('(',1,n) newStr{:}] 

%// evaluate 
result = eval(newStr) 

str = 
4/2-1^2+5*3 

newStr =  
((((((4)/2)-1)^2)+5)*3) 

result =  
    18 
+0

不错!我想这并不重要,但在第一行你也可以使用'regexprep':'regexprep(str,'[()]','')' – 2015-02-23 18:59:52

+0

@ Benoit_11或多或少都是一样的,不是吗? – thewaywewalk 2015-02-23 19:01:15

+0

实际上,我记得我们希望保持'str'的​​长度不变,但这并不重要, – 2015-02-23 19:05:23