所以我試圖用一個隊列來解析一些輸入,將前綴數學表達式轉化爲帶括號的中綴數學表達式。例如:+++ 12 20 3 4變成(((12 + 20)+3)+4)。大多數情況下,我的算法是有效的,除了一個特定的事情。當數字長於2位數時,輸出變得很奇怪。我會給你一些例子,而不是試圖解釋。隊列給出錯誤的數據
Examples: +++12 200 3 4 becomes (((12+3)+3)+4)
+++12 2000 3 4 becomes (((12+20004)+3)+4)
+++12 20005 3 4 becomes (((12+20004)+3)+4)
+++12 20005 3 45 becomes (((12+20004)+3)+45)
+++12 20005 3 456 becomes (((12+20004)+3)+()
希望這就是足夠的例子,如果你需要更多,請問。
我在Mac OSX 10.6.2上的XCode中使用GCC 4.2。
這裏是做這個奇妙的東西代碼:
#include "EParse.h"
#include <iostream>
#include <iomanip>
EParse::EParse(char* s)
{
this->s = s;
len = strlen(s);
}
void EParse::showParsed()
{
parse(s, 0, len, new std::queue< char* >(), new std::queue<char>());
}
void EParse::parse(char* str, int beg, int len, std::queue< char* > *n, std::queue<char> *ex)
{
//ex is for mathematical expressions (+, -, etc.), n is for numbers
if(beg == len)
{
if(ex->size() > n->size())
{
std::cout << "Malformed expression. Too many mathematical expressions to too few numbers." << std::endl;
std::cout << ex->size() << " mathematical expressions." << std::endl;
std::cout << n->size() << " number(s)." << std::endl;
return;
}
else
{
std::string *s = new std::string();
output(n, ex, 0, s);
std::cout << s->c_str();
return;
}
}
if(str[ beg ] == ' ' && beg != (len - 1))
beg++;
if(num(str[ beg ]))
{
std::string *s = new std::string();
getNum(s, str, beg, len);
//std::cout << s->c_str() << std::endl;
n->push(const_cast< char* >(s->c_str()));
delete s;
parse(str, beg, len, n, ex);
}
else if(mathexp(str[ beg ]))
{
ex->push(str[ beg ]);
parse(str, beg + 1, len, n, ex);
}
}
void EParse::getNum(std::string *s, char* str, int &beg, int len)
{
if(num(str[ beg ]))
{
char *t = new char[ 1 ];
t[ 0 ] = str[ beg ];
s->append(t);
beg += 1;
getNum(s, str, beg, len);
}
}
bool EParse::num(char c)
{
return c == '0' || c == '1' || c == '2' || c == '3' || c == '4' ||
c == '5' || c == '6' || c == '7' || c == '8' || c == '9';
}
bool EParse::mathexp(char c)
{
return c == '+' || c == '*' || c == '/' || c == '%' || c == '-';
}
void EParse::output(std::queue< char* > *n, std::queue<char> *ex, int beg, std::string *str)
{
if(ex->empty())
{
return;
}
char *t = new char[1];
t[ 0 ] = ex->front();
ex->pop();
if(beg == 0)
{
str->insert(0, "(");
str->append(n->front());
beg += 1 + strlen(n->front());
n->pop();
str->append(t);
str->append(n->front());
str->append(")");
beg += 2 + strlen(n->front());
n->pop();
}
else
{
str->insert(0, "(");
str->insert(beg, t);
str->insert(beg + 1, n->front());
beg += 1 + strlen(n->front());
str->insert(beg, ")");
n->pop();
beg++;
}
//ex->pop();
output(n, ex, beg + 1, str);
//std::cout << str << std::endl;
}
如果您需要任何評論或究竟某些東西呢,請讓我知道解釋,我會檢查回到這裏相當頻繁今晚。
你可以發佈一些EParse類的例子嗎?即你的main()函數,或類似的? – razlebe 2010-03-11 00:45:44
@sgreeve 檢查我放在帖子頂部的示例。這幾乎是我將如何使用這個類。 EParse e(「+++ 12 200 3 4」); e.showParsed(); 這是我的主要,作爲一個例子。所有的解析都是在課堂上完成的,然後才被輸出。 作爲一個方面說明,這個類使用純粹的遞歸方法。我通常不會這樣做,但這是作業所必需的。 – Freezerburn 2010-03-11 00:48:25
謝謝。從沒有經過每一行代碼的例子中可以看出,您只需調用showParsed()就可以了。你做得越清楚,你就可以越快得到別人的幫助! – razlebe 2010-03-11 00:49:56