递归函数将包含数学的字符串转换为整数 [英] Recursive function to convert a string containing math to integer

查看:123
本文介绍了递归函数将包含数学的字符串转换为整数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个字符串 4 + 6 * 7/2 ,我想要一个计算值的函数,在这种情况下为25。
为此,我

If I have a string 4+6*7/2 I want a function which calculates the value, in this case 25. To achieve this I have written a recursive function which analyses the string character by character.

基本算法采用(或应该采用)这样的方式:
如果我们现在分析字符是普通密码,我们还没有遇到过运算符(+,-,*,/),但是我们将其存储在名为 first_nr 的字符串中,该字符串最终将成为数字在操作员的左侧。直到遇到操作员之前,我们都会这样做。如果遇到运算符,则会存储它是哪个运算符,以便我们以后知道要做什么。因为遇到了一个运算符,所以我们现在必须将以下数字添加到另一个名为 second_nr 的字符串中,该字符串最终将成为该运算符右侧的数字。 [直到这里我都实现了]当然,我们还需要考虑计算的顺序,因此我将首先忽略所有的优缺点,直到分析所有的时间和除数。

The basic algorithm goes (or should go) like this: If the character we analyse now is a normal cipher and we haven't encountered an operator (+, -, *, /) yet we store it in a string called first_nr, which will eventually become the number on the left side of the operator. This we do until we encounter an operator. If we encounter an operator we store which operator it was so we know what to do later. Because we have encountered an operator, we now have to add the following numbers to another string called second_nr which will eventually become the number on the right-side of the operator. [I have implemented until here] Of course we also need to take the order of calculations in consideration, so I'd first ignore all the plusses and mins until all the times and divides are analyzed.

通过这种方式,例如,如果我有以下操作字符串:
123 + 789 + 4 。我的函数首先将 123 放入 first_nr ,然后查看运算符并存储 + 操作符中。由于 operator!= NULL 现在会添加以下数字,即 789 second_str 。结合这三个参数,我们可以形成 first_nr +运算符+ second_str 在这种情况下为 123 + 789 。我的程序需要在遇到下一个运算符之前执行该操作,因此在这种情况下它将形成 912 + 4 并重复执行递归。

This way if I have for example the following action string: 123+789+4. My function would first put 123 in first_nr, then see an operator and store the + in operator. Because operator != NULL now it adds the following numbers, being 789 to second_str. Combining those three parameters we could form first_nr + operator + second_str in this case 123+789. My program needs to execute that before it encounters the next operator so it will form in this case 912+4 and the recursion repeats.

我做了一些努力,但是仍然有很多漏洞。现在,我很高兴能运行字符串 12 + 5 。因此,除了加号之外,请忽略所有运算符,忽略计算顺序(第一次加和除,再加上加号和最小值),并忽略一个字符串中的多个运算符。

I did an effort but it still has a lot of holes in it. For now I would be happy if I could get the string 12+5 running. So ignore all operators besides plus, ignore the order of calculations (first times and divide, than plus and min), and ignore multiple operators in one string.

如果可以的话使最基本的字符串运行,我将改进算法以也可以使用更复杂的字符串。

If I can get the most basic string running I'll improve my algorithm to also work with more complex strings.

我的努力:

#include <iostream>
#include <string>
#include <algorithm>

//Enumeration of all the possible
//math operators
enum Operator {
    PLUS,
    MIN,
    TIMES,
    DIVIDE,
    UNDEFINED
};




/************************IGNORE********************/
Operator charToOperator(char c) {
    switch(c) {
        case '+':
            return Operator::PLUS;
            break;
        case '-':
            return Operator::MIN;
            break;
        case '*':
            return Operator::TIMES;
            break;
        case '/':
            return Operator::DIVIDE;
            break;
        default:
            return Operator::UNDEFINED;
            break;
    }
}
/***************************************************/

/*
 * Recursive function performing all the calculations from an action string.
 * For example, if the string actions has value "5+7" in the first recursive run
 * result should contain 12 after the last recursion.
 *
 * :param result: Double containing the calculated result after the last recursion
 * :param actions: Action string (what you type in your calculator; e.g: 5+5). We analyze the first character of this string each time and add it to first_nr, second_nr, or make it the operator. First character gets deleted after each recursion
 * :param first_nr: Empty at first recursion, number of left side of the operator. So in 55+77 this paramater will be "55". Gets resetted at the next operator
 * :param second_nr: Idem as first_nr but for the right side of the operator.
 * :param oper: Operation to calculate the first_nr and second_nr
 */
int calculate(double& result, std::string& actions, std::string& first_nr, std::string& second_nr, Operator& oper) {
    //Base-condition:
    //If action string is empty return 
    if (actions == "") {
       return result;
    }

    //Get first character from action string
    char c = actions[0];

    //If first character is an operator
    char operatorInChar[] = {'+', '-', '*', '/'};
    if (std::find(std::begin(operatorInChar), std::end(operatorInChar), c) != std::end(operatorInChar)) {
        //If operator is not yet set in a previous recursion
        if (oper == NULL || oper == Operator::UNDEFINED) {
            oper = charToOperator(c);

            //If second_nr is not empty, we need to calculate the two numbers together
            if (second_nr != "") {
                //Update result
                result = std::stod(first_nr) + std::stod(second_nr); //For now we only implement plus

                //Calculation is done, so reset first_nr, second_nr and operator
                //for the next 'first_nr [operator] second_nr' block in the action string
                first_nr = "";
                second_nr = "";
                oper = Operator::UNDEFINED;
            }
        }
    } else {
        //If the character is not a operator but a number we append it to the correct nr
        //we add to first_nr if the operator is not yet set, if we already encountered an operator
        //we add to second_nr.
        //e.g: actions = "123+789"

        if (oper == NULL || oper == Operator::UNDEFINED) {
            first_nr += c;
        } else {
            second_nr += c;
        }

    }

    //Remove first character from action string because it's analysed in this recursion
    actions = actions.erase(0, 1);

    //Make recursive call
    return calculate(result, actions, first_nr, second_nr, oper);
}

int main() {
    //String we want to calculate
    std::string str = "5+7";
    std::string str_copy_for_output = str;

    //Variables
    double result = 0;
    std::string first_nr = "";
    std::string second_nr = "";
    Operator oper = Operator::UNDEFINED;

    //Call function
    int calculation = calculate(result, str, first_nr, second_nr, oper);

    //Output
    std::cout << str_copy_for_output << " = " << calculation << std::endl;

    return 0;
}


问题在于结果始终为0。任何帮助将不胜感激!

The problem is that the result is always 0. Any help would be appreciated!

推荐答案

逐步执行该程序(使用调试器,至少在精神上$ printf )。有趣的几点如下:

Step through the program (with a debugger, printfs here and there, or mentally at least). Several interesting points, in order:


  1. oper是未定义的(不能为NULL,因为它不是指针;编译器可能会警告您),first_nr是,second_nr是,动作是 5 + 7。

  2. first_nr + = c;

  3. oper是未定义的,first_nr是 5,second_nr是,操作是 +7。

  4. oper = charToOperator(c); 被执行。

  5. oper是PLUS,first_nr是 5,second_nr是,操作是 7 。

  1. oper is UNDEFINED (it can’t be NULL btw as it’s not a pointer; a compiler could warn you), first_nr is "", second_nr is "", actions is "5+7".
  2. first_nr += c; is executed.
  3. oper is UNDEFINED, first_nr is "5", second_nr is "", action is "+7".
  4. oper = charToOperator(c); is executed.
  5. oper is PLUS, first_nr is "5", second_nr is "", action is "7".

糟糕! +不再出现在操作中,因此 actions [0] 将永远不会出现在 operatorInChar ,该分支将不再执行。您可能还需要在字符串末尾执行它。

Whoops! "+" is not in actions anymore, so actions[0] will never be found in operatorInChar and that branch will not be executed anymore. You probably need to additionally execute it at end of string.

这篇关于递归函数将包含数学的字符串转换为整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆