如何c++ 计算字符串表达式的值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何c++ 计算字符串表达式的值相关的知识,希望对你有一定的参考价值。

参考技术A 直接贴个以前写过的给你吧。
#include <iostream>
#include <boost/algorithm/string/trim.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

typedef double value_t;

template <typename Iterator>
struct calc_parser : boost::spirit::qi::grammar<Iterator, value_t(), boost::spirit::ascii::space_type>
calc_parser() : calc_parser::base_type(expression)
using boost::spirit::qi::double_;
using boost::spirit::qi::_val;
using boost::spirit::qi::_1;

expression = term [_val=_1]
>> *( ('+' >> term [_val=_val+_1])
| ('-' >> term [_val=_val-_1])
)
;

term = factor [_val=_1]
>> *( ('*' >> factor [_val=_val*_1])
| ('/' >> factor [_val=_val/_1])
)
;

factor = double_ [_val=_1]
| '(' >> expression [_val=_1] >> ')'
| ('+' >> factor [_val=_1])
| ('-' >> factor [_val=-_1])
;本回答被提问者和网友采纳

为啥我的代码没有为表达式字符串计算正确的值?

【中文标题】为啥我的代码没有为表达式字符串计算正确的值?【英文标题】:Why is my code not calculating the correct value for the expression string?为什么我的代码没有为表达式字符串计算正确的值? 【发布时间】:2019-10-04 10:20:27 【问题描述】:

在代码中,我使用了表达式树"3 + 2.53 - 1.75",它应该返回3.78 的结果。但是,它最终会添加字符串中的所有值并输出7.28。我在纸上多次浏览了代码,试图查看在每次使用索引变量 idistance_operator 的循环中发生了什么。就我所经历的而言,我找不到程序继续添加每个浮点值的原因。到达'-' 字符时,它应该减去下一个值。

distance_operator 用于作为第一个运算符的偏移量,其中索引 i 将被旋转,以便我可以获取该字符串的一部分并使用 substr() 函数计算它。

    float total = (float)value(expression[0]);
    int distance_operator;

    for (i = 1; i < expression.size(); i++) 
        if (expression[i] == '+' || expression[i] == '-') 
            distance_operator = i + 1;
            while (expression[distance_operator] != '+' || expression[distance_operator] != '-') 
                distance_operator++;
                if (distance_operator == expression.size())
                    break;
            
            if (expression[i] == '+')
                total += std::stof(expression.substr(i, distance_operator - i));
            else if(expression[i] == '-')
                total -= std::stof(expression.substr(i, distance_operator - i));

        
    

【问题讨论】:

你试过debug your program吗? substr 函数是否返回正确的子字符串?对于某些输入,预期输出是多少?实际输出是多少? 离题,但这不是解析这样的表达式的好方法。希望您现在不会被要求在表达式和/或乘法和除法中添加括号 - 您很快就会发现这段代码现在实际上毫无价值。 @PaulMcKenzie:同意,但实际上你可以走得很远。例如,我记得我的第一个表达式计算算法(我 15 岁时用 basic 编写的),我正在寻找第一个右括号,然后回到第一个左括号并为子表达式调用一个 sub 并将其替换为原始字符串。该子正在寻找+- 并为中间的任何内容调用一个子,而第二个子正在处理*/。肯定不是最好的方式......但你可以到达那里...... :-D @6502 -- 是的,但我要让 OP 知道他很有可能需要重新从头开始,或者完全疯狂地尝试调整当前程序,即使是最简单的程序添加到表达式中的特征。有一些正式的方法可以做到这一点,而不必从头开始。这是一种为不知情的学生设置陷阱的作业。 @PaulMcKenzie:我不太确定现在教这个男孩/女孩说 ANTLR 是否会让他/她成为更好的程序员。 【参考方案1】:

还要注意这个检查

while (expression[distance_operator] != '+' || expression[distance_operator] != '-')

将永远为真,因为事物总是与 A 不同或与 B 不同。正确的逻辑运算符是 &&。

【讨论】:

【参考方案2】:

代码几乎是正确的,但有一个“off-by-one”错误。

问题在于,当找到- 时,使用的正确子字符串将是"- 1.75",在解析为数字时为负值,您将减去它,基本上否定您的值想用。累积代码应该是:

if (expression[i] == '+')
    total += std::stof(expression.substr(i+1, distance_operator-i-1));
else if(expression[i] == '-')
    total -= std::stof(expression.substr(i+1, distance_operator-i-1));

注意使用i+1,所以会跳过找到的表达式符号。

【讨论】:

以上是关于如何c++ 计算字符串表达式的值的主要内容,如果未能解决你的问题,请参考以下文章

C++逻辑表达式运算

C++ 使用栈求解中缀后缀表达式的值

C++输入整数n,计算下列表达式的值:s= 1 +1/2!+1/3!+.....+1/n!要求输出s的值,小数点保留6位

问题 C++ 逆波兰表示法计算器

在 C++ 中从字符串计算算术表达式

在 C++ 中匹配正则表达式的惯用方法