如何从队列中的运算符和操作数创建数学表达式
How to create a mathematical expression from operators and operands in a queue
我正试图用队列中包含的运算符和操作数构建一个数学表达式(包括括号)。
这是我的代码:
string createExp (queue<char> q) {
string s;
string s1, s2;
char c;
while (!q.empty()) {
c = q.front();
if (c == 'x') {
s += "x";
q.pop();
}
else if (c == 'y') {
s += "y";
q.pop();
}
else if (c == 'a') {
s += "avg(";
q.pop();
s1 = createExp(q);
q.pop();
s2 = createExp(q);
q.pop();
s += s1;
s += ',';
s += s2;
s += ')';
}
else if (c == 's') {
s += "sin(pi*";
q.pop();
op++;
}
else if (c == 'c') {
s += "cos(pi*";
q.pop();
op++;
}
else {
s += "*";
q.pop();
}
}
while (op > cp) {
s += ")";
cp++;
}
return (s);
}
正如您所看到的,在平均值(avg)的情况下,我试图递归调用该函数以获得下一个值序列。
例如,如果我的队列包含下一个值:
s m a y x y
表达式应该是这样的:
sin(pi*(avg(y,x)*y)
但是我的代码返回了这个序列:
sin(pi**平均值(yyx)yyx
你能帮我做这个吗?
非常感谢。
处理avg(-,-)
的这一部分严重损坏:
s1 = createExp(q);
q.pop();
s2 = createExp(q);
q.pop();
你按值传递队列,这会创建它的副本。然后你就找不到递归弹出队列的次数了。但是您神奇地假设您应该只删除一个元素。如果其中一个参数中有函数调用或运算符,该怎么办?
更糟糕的是,递归处理队列的整个其余部分,而不仅仅是一个表达式。
**
来自字符串中的m
和您在代码中显式写入的sin(pi*
。
此外,递归到avg(当创建s1
时,似乎对整个表达式进行了索引,因此您得到了yyx
)。您必须确保它只从堆栈中读取一个完整的表达式,而不是其他内容。这很棘手,因为您需要区分例如avg(x,y)
和avg(x+y,y*x)
之间的区别。
我对您的代码做了一个小修改,它运行得很好:
int cp = 0, op = 0;
std::string createExp(std::queue< char >& q)
{
std::string s;
std::string s1, s2;
char c;
while (!q.empty())
{
c = q.front();
if (c == 'x')
{
s += "x";
q.pop();
}
else if (c == 'y')
{
s += "y";
q.pop();
}
else if (c == 'a')
{
s += "avg(";
q.pop();
s1 = q.front(); // here
q.pop();
s2 = q.front(); // and here
q.pop();
s += s1;
s += ',';
s += s2;
s += ')*';
}
else if (c == 's')
{
s += "sin(pi*";
q.pop();
op++;
}
else if (c == 'c')
{
s += "cos(pi*";
q.pop();
op++;
}
else
{
// s += "*";
q.pop();
}
}
while (op > cp)
{
s += ")";
cp++;
}
return (s);
}
但是,只有当您的操作员始终为*
时,这才会起作用。如果你还需要其他操作符,那么你需要一个更复杂的东西。
这是我的最后一个递归解决方案:
int cp = 0, op = 0;
string recursiveExp (queue<char>& q) {
char e;
if (!q.empty()) {
e = q.front();
if (e == 'x' || e == 'y') {
q.pop();
s += e;
}
else if (e == 's') {
q.pop();
s += "sin(pi*";
op++;
recursiveExp(q);
s += ")";
cp++;
}
else if (e == 'c') {
q.pop();
s += "cos(pi*";
op++;
recursiveExp(q);
s += ")";
cp++;
}
else if (e == 'a') {
q.pop();
s += "avg(";
op++;
recursiveExp(q);
s += ",";
recursiveExp(q);
s += ")";
cp++;
}
else if (e == 'm'){
q.pop();
s += "(";
op++;
recursiveExp(q);
s += "*";
recursiveExp(q);
s += ")";
cp++;
}
}
return s;
}
感谢大家:)
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 使用std::multimap迭代器创建std::list
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 使用CMake创建QML插件
- 如何在c++中为模板函数实例创建快捷方式
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 试图在visual studio上用C++创建一个桌面应用程序
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 如何在C++20中创建模板别名的推导指南
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 如何创建一个空的全局类并在启动时实例化它
- 无法创建抽象类的实例
- 链接到自行创建的dll失败
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++类内存结构中创建"spacer"?
- 如何从队列中的运算符和操作数创建数学表达式
- LLVM:创建一个带有空指针操作数的CallInst