借用栈实现表达式的转换与计算

1. 栈类的声明与定义

实现表达式的转换,转换后可以实现计算,此处为实现计算.
如:
1+2, will be changed to 12+, 3*5-1 will be 35*1-, 1+2-3*2-1 will be 12+32*-1-

具体的入栈和出栈过程以及操作符判断参考上一篇”中缀表达式转换为后缀表达式”

即只要有 “数字-数字-操作符”的形式就进行计算,同时将新的数入栈,最终即可得到结果

struct Node {
  char entry;
  Node *next;
  Node() {
    next = NULL;
  }
  Node(char data, Node *add_on = NULL) {
    entry = data;
    next = add_on;
  }
};
class Stack {
  public:
    Stack();
    bool empty() const;
    void push(const char item);
    void pop();
    char top() const;
    int size() const;
  protected:
    Node *top_node;
    int count;
};
在这里栈主要用来存储表达式中的操作符

下面是栈的定义

Stack::Stack() {
  count = 0;
  top_node = NULL;
}
bool Stack::empty() const {
  return count == 0;
}
void Stack::push(const char item) {
  Node* temp = new Node(item, top_node);
  top_node = temp;
  count++;
}
void Stack::pop() {
  Node* temp =  top_node;
  top_node = top_node->next;
  delete temp;
  count--;
}
char Stack::top() const {
  return top_node->entry;
}
int Stack::size() const {
  return count;
}

2. 表达式的转换, 中缀形式转换为后缀形式

重点和难点在与()处理

下面是实现的代码:

bool isOperator(char ch) {
  if (ch == '+'||ch == '-'||ch == '('||ch == ')'||ch == '*'||ch == '/')
  return true;
  else
  return false;
}
//  cur大于pre为true, cur小于或者是等pre为false
//  bool isHigherPriority(char cur, char pre) {
  if (cur == '(' || pre == '(') return true;
  else if ((cur == '*' || cur == '/')
          &&(pre == '+'||pre == '-'))
    return true;
  else
    return false;
}
bool isNum(char ch) {
  if (ch >= '0' && ch <= '9') return true;
  else return false;
}
//  重点是括号的处理,左括号直接入栈,知道遇到有括号在出栈
string transfer(string str) {
  if (str == "") return "";
  int l = str.size();
  char* result = new char[l + 1];
  Stack stack;  //  存放操作符
  int j = 0;
  for (int i = 0; i < l; ++i) {
    if (isNum(str[i])) {
      result[j++] = str[i];
    }
    if (isOperator(str[i])) {
      //  最开始为空的情况
      if (stack.empty()) {
        if (str[i] == ')')
          return "";
        else
          stack.push(str[i]);
      //  栈不为空时首先考虑是否遇到括号的情况,遇到有括号首先要判断栈中是否有左括号
      } else if (str[i] == ')') {
        bool leftBrace = false;
        while (!stack.empty()) {
          if (stack.top() == '(') {
            stack.pop();
            leftBrace = true;
            break;
          }
          result[j++] = stack.top();
          stack.pop();
        }
        if (!leftBrace) return "";
      } else {
        if (isHigherPriority(str[i], stack.top())) {
          stack.push(str[i]);
        } else {
          while (!stack.empty()) {
            if (isHigherPriority(str[i], stack.top())) {
              break;
            }
            result[j++] = stack.top();
            stack.pop();
          }
          stack.push(str[i]);
        }
      }
    }
  }
  while (!stack.empty()) {
    result[j++] = stack.top();
    stack.pop();
  }
  //   字符串以'\0'结束
  result[j] = '\0';
  string conversion(result);
  delete []result;
  return conversion;
}

(1)注意:char *result = new char[len + 1]而不是new char[len], 因为最后字符串应该以’\0’结束, 若只new了len的内存,则会因为越界而出现内存泄漏

(2)判断操作符的时候简单说有三种情况,首先判断括号的情况,然后是一种情况是优先级比原本的要高(不包括相等的情况),此种情况直接将新的操作符进栈; 另外一种情况是新的操作符与原来相等或者是小的情况,进行同一处理,即原来的操作符出栈,并且输出,同时将新的操作符与此时的stack.top()的优先级进行比较,知道新的优先级比较高或者是栈为空的时候,将新的操作符入栈

(3)测试样例:
input:
This line is pointless, please ignore 9413
(2+1)/(2-1)*(2+2)
output:
i s l i n e i s p o i n t l e s s , p l e a s e i g n o r e 9 4 1 3
0
21+21-/22+*
以下是main函数部分:

int main() {
  string str;
  string d;
  Stack s;
  getline(cin, d);
  int len = d.length();
  for (int i = len - 1; i > 1; i--) {
    s.push(d[i]);
  }
  while (!s.empty()) {
    cout << s.top() << " ";
    s.pop();
  }
  cout << endl;
  cout << s.size() << endl;
  getline(cin, str);
  MidToLast mtl;
  string strtemp = mtl.transfer(str);
  cout << strtemp << endl;
  return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值