此題用 Python 的 eval 函數會比較好解。
用C++的話可以先將中序運算式(Infix expression)轉成後序運算式(Postfix expression)在做求值,為Stack的應用,不過此處所提供的程式碼是直接對中序運算式做求值的。用Stack的細節可參考 四則運算 VS Stack 一文。
C++ 程式碼:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
using namespace std; | |
void eatspaces(string &str); // Function to eliminate blanks | |
int expr(string &str); // Function evaluating an expression | |
int term(string &str, int& index); // Function analyzing a term | |
int number(string &str, int& index); // Function to recognize a number | |
string extract(string &str, int& index); //Function to extract a substring | |
int main(void) | |
{ | |
string buffer; // Input area for expression to be evaluated | |
while( getline(cin, buffer) ) | |
{ | |
eatspaces(buffer); // Remove blanks from input | |
cout << expr(buffer) // Output value of expression | |
<< endl; | |
//cout << buffer << endl; | |
} | |
} | |
// Function to eliminate blanks from a string | |
void eatspaces(string &str) | |
{ | |
for(unsigned i = 0; i < str.length(); i++) | |
{ | |
if(str[i] == ' ') | |
str.erase(i, 1); | |
} | |
} | |
// Function to evaluate an arithmetic expression | |
int expr(string &str) | |
{ | |
int value = 0; // Store result here | |
int index = 0; // Keeps track of current character position | |
value = term(str, index); // Get first term | |
for(;;) // Infinite loop, all exits inside | |
{ | |
switch(str[index++]) // Choose action based on current character | |
{ | |
case '\0': // We're at the end of the string | |
return value; // so return what we have got | |
case '+': // + found so add in the | |
value += term(str, index); // next term | |
break; | |
case '-': // - found so subtract | |
value -= term(str, index); // the next term | |
break; | |
default: // If we reach here the string | |
cout << endl // is junk | |
<< "Arrrgh!*#!! There's an error" | |
<< endl; | |
exit(1); | |
} | |
} | |
} | |
// Function to get the value of a term | |
int term(string &str, int& index) | |
{ | |
int value = 0; // Somewhere to accumulate the result | |
value = number(str, index); // Get the first number in the term | |
// Loop as long as we have a good operator | |
while( (str[index]=='*') || (str[index]=='/') || (str[index]=='%') ) | |
{ | |
if(str[index]=='*') // If it's multiply, | |
value *= number(str, ++index); // multiply by next number | |
if(str[index]=='/') // If it's divide, | |
value /= number(str, ++index); // divide by next number | |
if(str[index]=='%') | |
value = value % number(str, ++index); | |
} | |
return value; // We've finished, so return what we've got | |
} | |
// Function to recognize an expression in parentheses | |
// or a number in a string | |
int number(string &str, int& index) | |
{ | |
int value = 0; // Store the resulting value | |
if(str[index] == '(') // Start of parentheses | |
{ | |
string psubstr; // Pointer for substring | |
psubstr = extract(str, ++index); // Extract substring in brackets | |
//cout << "psubstr: " << psubstr << endl; | |
value = expr(psubstr); // Get the value of the substring | |
return value; // Return substring value | |
} | |
//cout << "number value: " << value << endl; | |
while(isdigit(str[index])) // Loop accumulating leading digits | |
value=10*value + ((str[index++]) - 48); | |
// Not a digit when we get to here | |
return value; // On loop exit we are done | |
} | |
// Function to extract a substring between parentheses | |
// (requires string) | |
string extract(string &str, int& index) | |
{ | |
string pstr; // Pointer to new string for return | |
int numL = 0; // Count of left parentheses found | |
int bufindex = index; // Save starting value for index | |
do | |
{ | |
switch(str[index]) | |
{ | |
case ')': | |
if(numL==0) | |
{ | |
++index; | |
pstr = str.substr(bufindex, index - bufindex-1); | |
//str.erase(bufindex - 1, index - bufindex + 1); | |
//cout << "extract pstr: " << pstr << endl; | |
//cout << "str: " << str << endl; | |
return pstr; // Return substring in new memory | |
} | |
else | |
numL--; // Reduce count of '(' to be matched | |
break; | |
case '(': | |
numL++; // Increase count of '(' to be matched | |
break; | |
} | |
} while(index++ < str.length());// Loop - don't overrun end of string | |
cout << "Ran off the end of the expression, must be bad input." | |
<< endl; | |
exit(1); | |
return pstr; | |
} |
import sys
for s in sys.stdin:
print(eval(s.replace("/", "//")))
沒有留言:
張貼留言