首页 > 试题广场 >

使用 C++ (VC6、VS2003、VS2005、GCC4

[问答题]
使用 C++ (VC6、VS2003、VS2005、GCC4.1.2、GCC3.2.2)或 java(JDK1.6.0)两种语言.编写一个可以计算四则运算 (包含括号) 程序, 比如输入字符串" 1 + 2 * 3 / ( 4 - 5)" , 输出的结果为" -5" 。
推荐
#include<stack>
#include<iostream>
#include<deque>
#include<string>
using namespace std;

//判断是否为括号
bool isPra(char c)
{
    if (c == '(' || c == ')')
        return true;
    else
        return false;
}

//获得符号的优先性
int getPri(char c)
{
    switch (c)
    {
    case '+':
    case '-':
        return 0; //如果是加减,返回0
        break;
    case '*':
    case '/':
        return 1; //如果是乘除,返回1
        break;
    case '(':
    case ')':
        return -1;  //注意,这里将括号设为最低优先级,因此括号不会被弹出,除非遇到右括号
        break;
    }
}

//判断符号的优先性
void check(char c, stack<char> &coll2, deque<char> &coll3)
{
    if (coll2.empty())
    {
        coll2.push(c);
        return;
    }

    if (isPra(c))
    {
        if (c == '(')
            coll2.push(c);
        else
        {
            //弹出所有元素直到遇到左括号
            while (coll2.top() != '(')
            {
                char ch = coll2.top();
                coll3.push_back(ch);
                coll2.pop();
            }

            //当遇到左括号时,弹出但不加入coll3(后缀表达式中)
            coll2.pop();
        }
    }
    else //如果不是括号
    {
        //取出栈顶元素,与当前符号进行优先性比较
        char sym = coll2.top();

        //比较两符号的优先性
        if (getPri(c) <= getPri(sym))
        {
            //如果c的优先性比栈顶符号小或等于,弹出栈顶元素
            coll2.pop();
            //并将其压入coll3(后缀表达式)中
            coll3.push_back(sym);
            //递归调用check,比较当前符号c与下一个栈顶符号的优先性
            check(c, coll2, coll3);
        }
        else
        {
            //如果c比栈顶符号优先级大,那将c压入coll2(操作符栈)中
            coll2.push(c);
        }
    }
}

//从coll中取出元素,分配元素到coll2和coll3中
void allocate(deque<char> &coll1, stack<char> &coll2, deque<char> &coll3)
{
    while (!coll1.empty())
    {
        char c = coll1.front();
        coll1.pop_front();

        if (c >= '0' && c <= '9')
        {
            coll3.push_back(c);
        }
        else
        {
            //调用check函数,针对不同情况作出不同操作
            check(c, coll2, coll3);
        }

    }

    //如果输入结束,将coll2的元素全部弹出,加入后缀表达式中
    while (!coll2.empty())
    {
        char c = coll2.top();
        coll3.push_back(c);
        coll2.pop();
    }
}

//计算后缀表达式
void calculate(deque<char> &coll3, stack<int> &coll4)
{
    while (!coll3.empty())
    {
        char c = coll3.front();
        coll3.pop_front();

        //如果是操作数,压入栈中
        if (c >= '0' && c <= '9')
        {
            //减去'0'得出偏移值,即为真实数值(如果直接转换成int,结果不对,因为char 转换为int是其编码值,例如'1'的编码值为49
            int op = c - '0';
            coll4.push(op);
        }
        else //如果是操作符,从栈中弹出元素进行计算
        {
            int op1 = coll4.top();
            coll4.pop();
            int op2 = coll4.top();
            coll4.pop();
            switch (c)
            {
            case '+':
                coll4.push(op2 + op1);
                break;
            case '-':
                coll4.push(op2 - op1);
                break;
            case '*':
                coll4.push(op2 * op1);
                break;
            case '/':
                coll4.push(op2 / op1); //注意是op2(op)op1而不是op1(op)op2
                break;
            }
        }
    }
}


int main()
{
    deque<char> coll1;  //盛放中缀表达式
    stack<char> coll2;  //盛放操作符
    deque<char> coll3; //盛放后缀表达式
    stack<int>coll4; //计算后缀表达式的辅助容器
    string str;
    cout << "请输入表达式,按enter结束:" << endl;
    cin >> str;
    for (int i = 0; i != str.size(); ++i)
    {
        //逐一加入每个字符,这里使用deque因为deque在两端删除添加的速度最快
        coll1.push_back(str[i]);
    }

    //从coll中取出元素,分配元素到coll2和coll3中
    allocate(coll1, coll2, coll3);

    //计算后缀表达式
    calculate(coll3, coll4);
    cout << "计算结果为:" << coll4.top() << endl;
}

编辑于 2015-02-07 16:39:49 回复(0)
// A program to implement a calculator accepting parentheses
#include                               // For stream input/output
#include                                // For the exit() function
#include                                 // For the isdigit() function
#include                                // For the strcpy() function
using std::cin;
using std::cout;
using std::cerr;
using std::endl;
void eatspaces(char* str);                       // Function to eliminate blanks
double expr(char* str);                          // Function evaluating an expression
double term(const char* str, size_t& index);        // Function analyzing a term
double number(const char* str, size_t& index);      // Function to recognize a number
char* extract(const char* str, size_t& index);      // Function to extract a substring
const size_t MAX{ 80 };                          // Maximum expression length, including '\0'
int main()
{
  char buffer[MAX] {};                           // Input area for expression to be evaluated
  cout << endl
    << "Welcome to your friendly calculator."
    << endl
    << "Enter an expression, or an empty line to quit."
    << endl;
  for (;;)
  {
    cin.getline(buffer, sizeof buffer);          // Read an input line
    eatspaces(buffer);                           // Remove blanks from input
    if (!buffer[0])                              // Empty line ends calculator
      return 0;
    try
    {
      cout << "\t= " << expr(buffer)             // Output value of expression
        << endl << endl;
    }
    catch (const char* pEx)
    {
      cerr << pEx << endl;
      cerr << "Ending program." << endl;
      return 1;
    }
  }
}
// Function to eliminate spaces from a string
void eatspaces(char* str)
{
  size_t i{};                                    // 'Copy to' index to string
  size_t j{};                                    // 'Copy from' index to string
  while ((*(str + i) = *(str + j++)) != '\0')    // Loop while character
    // copied is not \0
  if (*(str + i) != ' ')                         // Increment i as long as
    i++;                                         // character is not a space
  return;
}
// Function to evaluate an arithmetic expression
double expr(char* str)
{
  double value{};                                // Store result here
  size_t index{};                                // Keeps track of current character position
  value = term(str, index);                      // Get first term
  for (;;)                                       // Indefinite 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
      char message[38] {"Expression evaluation error. Found: "};
      strcat(message, str + index - 1);    // Append the character
      throw message;
      break;
    }
  }
}
// Function to get the value of a term
double term(const char* str, size_t& index)
{
  double value{};                                // 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 (true)
  {
    if (*(str + index) == '*')                   // If it's multiply,
      value *= number(str, ++index);             // multiply by next number
    else if (*(str + index) == '/')              // If it's divide,
      value /= number(str, ++index);             // divide by next number
    else
      break;
  }
  return value;                                  // We've finished, so return what 
  // we've got
}
// Function to recognize a number in a string
double number(const char* str, size_t& index)
{
  double value{};                                // Store the resulting value
  if (*(str + index) == '(')                     // Start of parentheses
  {
    char* psubstr{};                             // Pointer for substring
    psubstr = extract(str, ++index);             // Extract substring in brackets
    value = expr(psubstr);                       // Get the value of the substring
    delete[]psubstr;                             // Clean up the free store
    return value;                                // Return substring value
  }
  // There must be at least one digit...
  if (!isdigit(*(str + index)))
  { // There's no digits so input is junk...
    char message[31] {"Invalid character in number: "};
    strcat(message, str + index);          // Append the character
    throw message;
  }
  while (isdigit(*(str + index)))                // Loop accumulating leading digits
    value = 10 * value + (*(str + index++) - '0');
  // Not a digit when we get to here
  if (*(str + index) != '.')                     // so check for decimal point
    return value;                                // and if not, return value
  double factor{ 1.0 };                          // Factor for decimal places
  while (isdigit(*(str + (++index))))            // Loop as long as we have digits
  {
    factor *= 0.1;                               // Decrease factor by factor of 10
    value = value + (*(str + index) - '0')*factor;   // Add decimal place
  }
  return value;                                  // On loop exit we are done
}
// Function to extract a substring between parentheses 
// (requires cstring)
char* extract(const char* str, size_t& index)
{
  char* pstr{};                                  // Pointer to new string for return
  int numL{};                                    // Count of left parentheses found
  size_t bufindex{ index };                      // Save starting value for index
  do
  {
    switch (*(str + index))
    {
    case ')':
      if (0 == numL)
      {
        ++index;
        pstr = new char[index - bufindex];
        if (!pstr)
        {
          throw "Memory allocation failed.";
        }
        strcpy(pstr, str + bufindex); // Copy substring to new memory
        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 (*(str + index++) != '\0');            // Loop - don't overrun end of string
  throw "Ran off the end of the expression, must be bad input.";
}
发表于 2017-03-29 16:30:38 回复(0)