递归函数将包含数学的字符串转换为整数 [英] Recursive function to convert a string containing math to integer
问题描述
如果我有一个字符串 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!
推荐答案
逐步执行该程序(使用调试器,至少在精神上$
Step through the program (with a debugger, printf
s here and there, or mentally at least). Several interesting points, in order:
- oper是未定义的(不能为NULL,因为它不是指针;编译器可能会警告您),first_nr是,second_nr是,动作是 5 + 7。
-
first_nr + = c;
- oper是未定义的,first_nr是 5,second_nr是,操作是 +7。
-
oper = charToOperator(c);
被执行。 - oper是PLUS,first_nr是 5,second_nr是,操作是 7 。
- 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".
first_nr += c;
is executed.- oper is UNDEFINED, first_nr is "5", second_nr is "", action is "+7".
oper = charToOperator(c);
is executed.- 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屋!