0

好的,所以我正在尝试制作一个表达式为字符串的求解器,以便用户可以输入一个字符串,例如 2+4*5/10,它会打印出答案,4。我有编写了一些代码,但它不应用操作顺序;它只是按运算符的顺序求解方程 - 例如 2+4*5/10 会产生 3,这是不正确的。我如何使它先执行乘法和除法,然后执行加法和减法?这是我现在拥有的代码:

class Expressions
{
String E;
void SetE(String e)
{
    E = e;
}

int EvalE()
{
    int res = 0;
    int temp = 0;
    char op = '+';

    for(int i=0;i<E.length();i++)
    {
        if(E.charAt(i)=='*'||E.charAt(i)=='/'||E.charAt(i)=='+'||E.charAt(i)=='-')
        {
            if(op=='*')res*=temp;
            else if(op=='/')res/=temp;
            else if(op=='+')res+=temp;
            else res-=temp;

            temp=0;
            op=E.charAt(i);
        }
        else
        {
            temp = temp*10+E.charAt(i)-'0';
        }
    }

    if(op=='*')res*=temp;
    else if(op=='/')res/=temp;
    else if(op=='+')res+=temp;
    else res-=temp;

    return res;
}
}
4

3 回答 3

2

将表达式拆分为两个更简单的表达式,然后使用递归。

您必须按此顺序执行以下步骤,否则您会弄乱操作顺序。

  1. 寻找最右边的 + 号。如果有这样的+,则使用递归计算它左边的子表达式,然后计算它右边的子表达式,然后将它们相加并返回结果。
  2. 如果没有 + 号,则查找最右边的 - 号前面有一个数字(即,它是减法,而不是否定)。如果有这样的-,则使用递归计算它左边的子表达式,然后计算它右边的子表达式,然后将它们相减并返回结果。
  3. 如果没有 + 或 - 号,则查找最右边的 * 号。如果有这样的*,则使用递归计算它左边的子表达式,然后计算它右边的子表达式,然后将它们相乘并返回结果。
  4. 如果没有 +、- 或 * 符号,则查找最右边的 * 符号。如果有这样一个*,则使用递归计算它左边的子表达式,然后计算它右边的子表达式,然后将它们相除并返回结果。如果您使用整数,则必须考虑是要整数除法还是浮点数。您可能还想对除以零进行某种检查。
  5. 如果没有 +、-、* 或 /,那么您所拥有的只是数字和空格。也许是一个负面的信号。去掉空格,解析它并返回它。

示例:“6 - 5 - 4 + 3 * -2”

  • 首先,在 + 处拆分,并使用递归计算“6 - 5 - 4”和“3 * -2”。
  • 对于“6 - 5 - 4”,在第二个 - 处拆分,并使用递归计算“6 - 5”和“4”。
  • 对于“6 - 5”,在 - 处拆分,并使用递归计算“6”和“5”。
  • 对于“ 3 * -2”,在 * 处拆分,因为 - 前面没有数字。使用递归计算“3”和“-2”。
  • 对于“6”、“5”、“4”、“3”和“-2”中的每一个,都没有运算符,所以我们只是去掉空格并解析。
  • 我们的计算结果将是“((6-5)-4)+(3*-2)”,所以运算的顺序是正确的。
于 2013-11-11T01:37:05.280 回答
1

使用两个for循环。

在您的第一个循环中,搜索*/运算符。评估该部分并将字符串的该部分替换为评估结果。

在你的第二个循环中,按照你已经在做的那样做所有的+和。-

因此,对于您使用的示例2+4*5/10,您的第一个循环将查找*or /。在找到 后*,它会评估4*5。也就是说20,字符串被修改为2+20/10. 再次检查,找到/, 并将字符串修改为2+2.

现在你通过你的第二个循环,得到4.

于 2013-11-08T03:26:54.457 回答
1

你需要做两步而不是一步。在第一步中,您将方程解析为反向波兰符号,然后在第二步中您运行并计算结果。不错的奖励是您(几乎)免费获得括号支持:-)

于 2013-11-08T03:26:59.463 回答