string Expression::addevaluate(string x){
stringrep = x; //Stringrep is the string that user typed in,
//it might be 5+6+7-8-9*3/(2+5)
int totalnum = stringrep.length();
for(int i=0;i < totalnum;i++){ //This for loop will seperate the
//string by "+" and output a vector
//with seperate string
int addop = stringrep.find("+");
addvector.push_back(stringrep.substr(0,addop));
string a =stringrep.substr(0,addop);
totalnum=totalnum-(a.length());
stringrep = stringrep.substr(addop+1,totalnum);
}
int vectorlength = addvector.size();
for(int i = 0;i<vectorlength;i++){
cout << i+1<<":"<<addvector[i]<<",";
}
subevaluate(addvector);
return stringrep;
}
string Expression::subevaluate(vector<string> &v){
int totalnum = v.size();
//This is the question, I have no idea how can i set the value totalnum
//If it's the size of vector,it's too small. If it's the last totalnum
//from last function. Then there is a error. In addition,I do not know
//what the error is.
for(int i=0;i < totalnum;i++){
int addop = v[i].find("-");
if(addop > 0){
subtvector.push_back(v[i].substr(0,addop));
string a =v[i].substr(0,addop);
totalnum=totalnum-a.length();
v[i] = v[i].substr(addop+1,totalnum);
}
}
int vectorlength = subtvector.size();
for(int i = 0;i<vectorlength;i++){
cout << i+1<<":"<<subtvector[i]<<",";
}
return stringrep;
}
我不知道为什么我为第二个for循环做错了。请帮我解决for循环。另外,我怎样才能将所有字符串分开。&#34; +&#34;,&#34; - &#34;,&#34; *&#34;,&#34; /&#34 ;。然后像计算器一样计算答案。感谢。
答案 0 :(得分:1)
此实现不起作用......假设您有
"1+2*(3+4)"
第一次拆分(即使写得正确)也会得到
"1"
"2*(3"
"4)"
你打算用"2*(3"
做什么?
使用这种方法编写计算器至少需要:
"("
前面并在末尾添加")"
(即更改为"(1+2*(3+4))"
"3+4"
)并将原始字符串中的整个带括号的表达式替换为结果(即从"1+2*(3+4)"
获取到"(1+2*7)"
)要在给定字符上拆分字符串,您应该编写专用函数,例如:
std::vector<std::string> split(const std::string& text, char sep) {
std::vector<std::string> result;
size_t pos = text.find(sep);
while(pos != std::string::npos) {
result.push_back(text.substr(0, pos));
text = text.substr(pos + 1);
}
result.push_back(text);
return result;
}
然后你可以写
std::vector<std::string> res = split(text, '+');
从"1+2*3+4"
转到包含"1"
,"2*3"
,"4"
的向量。
PS:请注意,这种计算表达式的方式并不是通常所做的,但是它可以工作,所以在我看来你应该继续努力直到它完成。
答案 1 :(得分:0)
我认为在将字符串拆分为向量时,很难使代码生效。我认为运营商优先权太难以处理。
递归过程怎么样?
通过这种方式,您可以逐步简化原始字符串。您只需继续使用子字符串调用evaluate函数,直到将它们转换为简单表达式。
示例:
exp = 12 /(5 + 1)
呼叫1:呼叫f(“12 /(5 + 1)”)
调用1:f标识子串“5 + 1”并调用自身(递归)
致电2:致电f(“5 + 1”)
调用2:简单表达式计算为“6”,返回
调用1:子串“(5 + 1)”被返回的“6”
替换呼叫1:exp现在看起来是“12/6”
调用1:简单表达式计算为“2”,返回
更复杂的表达式如“48 /(5 +(2 * 3 /(3-1))”只会导致更多的调用,以便逐步简化字符串。
代码看起来像下面的代码。只包含结构 - 用于填写实际代码。
bool isSimpleExpression(string& s)
{
// Return true if s is simple, i.e. X+Y, X-Y, X*Y, X/Y
// Otherwise false
}
string evaluateString(string& exp)
{
while(!isSimpleExpression(exp))
{
// exp must be broken into smaller part as it isn't simple yet
if (ExpContainsParanthesis() )
{
// Example: exp is "12/(5+1)"
string s1 = FindSubstringInMostInnerMatchingParanthesis(exp);
// Example: s1 is "5+1"
// Example: call evaluateString("5+1")
strint s2 = evaluateString(s1); // Recursive call
// Example: s2 is 6
ReplaceS1WithS2(exp, s1, s2);
// Example: exp is "12/6"
}
else if (ExpContainsMultiplication())
{
// Find the substring with multiplication
// Call this function with the substring
// Replace the substring with the returned result
}
else if ....
{
// division
}
// ... and so on
}
// Calculate the simple expression
string result;
// ..
// ..
return result;
}