如何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
。我在纸上多次浏览了代码,试图查看在每次使用索引变量 i
和 distance_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++输入整数n,计算下列表达式的值:s= 1 +1/2!+1/3!+.....+1/n!要求输出s的值,小数点保留6位