如何从队列中的运算符和操作数创建数学表达式
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)
但是我的代码return这个序列:
sin(pi**avg(yyx)yyxyyx
你能帮我解决这个问题吗?
非常感谢。
**
来自字符串中的 m
和您在代码中显式编写的 sin(pi*
。
此外,对 avg 的递归(在创建 s1
时似乎索引了整个表达式,因此您得到 yyx
)。您必须确保它只从堆栈中读取 1 个完整的表达式,而不是其余部分。这很棘手,因为您需要区分 avg(x,y)
和 avg(x+y,y*x)
之间的区别。
这部分处理 avg(-,-)
严重损坏:
s1 = createExp(q);
q.pop();
s2 = createExp(q);
q.pop();
您正在按值传递队列,这会创建它的副本。然后你无法找出递归弹出队列的次数。但是你神奇地假设你应该只删除一个元素。如果其中一个参数中有函数调用或运算符怎么办。
更糟糕的是,递归处理整个队列的其余部分,而不仅仅是一个表达式。
我对你的代码做了一些小的修改,它运行得很好:
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;
}
感谢大家:)
我正在尝试使用队列中包含的运算符和操作数构建数学表达式(包括括号)。
这是我的代码:
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)
但是我的代码return这个序列:
sin(pi**avg(yyx)yyxyyx
你能帮我解决这个问题吗?
非常感谢。
**
来自字符串中的 m
和您在代码中显式编写的 sin(pi*
。
此外,对 avg 的递归(在创建 s1
时似乎索引了整个表达式,因此您得到 yyx
)。您必须确保它只从堆栈中读取 1 个完整的表达式,而不是其余部分。这很棘手,因为您需要区分 avg(x,y)
和 avg(x+y,y*x)
之间的区别。
这部分处理 avg(-,-)
严重损坏:
s1 = createExp(q);
q.pop();
s2 = createExp(q);
q.pop();
您正在按值传递队列,这会创建它的副本。然后你无法找出递归弹出队列的次数。但是你神奇地假设你应该只删除一个元素。如果其中一个参数中有函数调用或运算符怎么办。
更糟糕的是,递归处理整个队列的其余部分,而不仅仅是一个表达式。
我对你的代码做了一些小的修改,它运行得很好:
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;
}
感谢大家:)