2013-06-07 2 views
3

산술 식을 중위에서 후위 폼으로 변환하는 프로그램을 만들려고합니다. "infixToPostFix"함수를 호출하지 않는 한 프로그램이 제대로 실행됩니다. 그러나 다음 코드를 실행하려고하면 크래시가 발생하고 "deque iterator dereferenceable"오류가 발생합니다. 나는 어떤 역 참조 연산자를 찾을 수 없습니다, 그래서 무엇이 잘못되었는지 모르겠어요 :오류 : dequeueable deque iterator

// infixToPostfixTest.cpp 

#include "Token.h" 
#include <iostream> 
#include <vector> 
#include <stack> 
using namespace std; 

// infix to postfix function prototype 

void infixToPostfix(vector<Token> &infix, vector<Token> &postfix); 

// priority function prototype 
int priority(Token & t); 

// printing a Token vector 
void printTokenVector(vector<Token> & tvec); 

int main() { 

    // Experiment 
    //-------------------------------------------------- 
    vector<Token> infix; 

    // a + b * c - d/e % f 
    // 
    infix.push_back(Token(VALUE,5.0)); // a 
    infix.push_back(Token(OPERATOR,'+')); 
    infix.push_back(Token(VALUE,6.0)); // b 
    infix.push_back(Token(OPERATOR,'*')); 
    infix.push_back(Token(VALUE,7.0)); // c 

    cout << "Infix expression: "; 
    printTokenVector(infix); 


    vector<Token> postfix; // create empty postfix vector 
    infixToPostfix(infix, postfix); // call inToPost to fill up postfix vector from infix vector 

    cout << "Postfix expression: "; 
    printTokenVector(postfix); 
    cout << endl << endl; 

    return 0; 
} 

// printing a Token vector 
void printTokenVector(vector<Token> & tvec) 
{ 
    int size = tvec.size(); 
    for (int i = 0; i < size; i++) { 
     cout << tvec[i] << " "; 
    } 
    cout << endl; 
} 




int priority(Token & t) // assumes t.ttype is OPERATOR, OPEN, CLOSE, or END 
{ 
    char c = t.getChar(); 
    char tt = t.getType(); 

    if (c == '*' || c == '/') 
     return 2; 
    else if (c == '+' || c == '-') 
     return 1; 
    else if (tt == OPEN) 
     return 0; 
    else if (tt == END) 
     return -1; 
    else 
     return -2; 
} 

void infixToPostfix(vector<Token> &infix, vector<Token> &postfix) 
{ 
    stack<Token> stack; 

    postfix.push_back(END); 

    int looper = 0; 
    int size = infix.size(); 
    while(looper < size) { 
     Token token = infix[looper]; 

     if (token.getType() == OPEN) 
     { 
      stack.push(token); 
     } 

     else if (token.getType() == CLOSE) 
     { 
      token = stack.top(); 
      stack.pop(); 

      while (token.getType() != OPEN) 
      { 
       postfix.push_back(token); 

       token = stack.top(); 
       stack.pop(); 

      } 
     } 

     else if (token.getType() == OPERATOR) 
     { 
      Token topToken = stack.top(); 

      while ((!stack.empty()) && (priority(token) <= priority(topToken))) 
      { 
       Token tokenOut = stack.top(); 
       stack.pop(); 

       postfix.push_back(tokenOut); 
       topToken = stack.top(); 
      } 

      stack.push(token); 
     } 

     else if (token.getType() == VALUE) 
     { 
      postfix.push_back(token); 
     } 

     else 
     { 
      cout << "Error! Invalid token type."; 
     } 

     looper = looper + 1; 
    } 

    while (!stack.empty()) 
    { 
     Token token = stack.top(); 
     stack.pop(); 

     postfix.push_back(token); 
    } 
} 


//Token.h 

#ifndef TOKEN_H 
#define TOKEN_H 

#include <iostream> 
using namespace std; 

enum TokenType { OPEN, CLOSE, OPERATOR, VARIABLE, VALUE, END }; 

class Token { 

public: 
    Token (TokenType t, char c) : ttype(t), ch(c) { } 
    Token (TokenType t, double d) : ttype(t), number(d) { } 
    Token (TokenType t) : ttype(t) { } 
    Token() : ttype (END), ch('?'), number(-99999999) { } 

    TokenType getType() {return ttype;} 
    char getChar() {return ch;} 
    double getNumber() {return number;} 

private: 
    TokenType ttype; 
    char ch; 
    double number; 
}; 

ostream & operator << (ostream & os, Token & t) { 

    switch (t.getType()) { 
     case OPEN: 
      os << "("; break; 
     case CLOSE: 
      os << ")"; break; 
     case OPERATOR: 
      os << t.getChar(); break; 
     case VARIABLE: 
      os << t.getChar(); break; 
     case VALUE: 
      os << t.getNumber(); break; 
     case END: 
      os << "END" ; break; 
     default: os << "UNKNOWN"; 
    } 


    return os; 
}  

답변

5

stackcontainer를 사용하여 구현, stack 사용하는 기본 deque으로, container adaptor 때문이다. 코드의 한 줄에서 pop/top을 비어있는 stack으로 호출하면 허용되지 않습니다.

trace 표시 오류는 Token + 이후입니다. 문제는 여기에 있습니다 : 당신은 NUMBER 토큰 토큰 OPERATOR 전에 빈입니다 경우에 stack 때문에, 빈 stack에서 top하려고

else if (token.getType() == OPERATOR) 
    { 
     Token topToken = stack.top(); 

.

+0

흠, 나는 "이 경우 각 팝/상단 호출하기 전에,하지만 난 여전히 오류가있어 추가 – user1824518

+0

user1824518 당신입니다 @. 그게 유일한 이유 야 왜 그 오류가있을 수 있니? – ForEveR

+0

아하 거기있다! 나는 "팝"키워드에 대한 검색을 했으므로 놓쳤다. 고마워. – user1824518

2

빈 스택에 top을 불러오고 테스트 코드를 따르십시오.

  1. 당신이, 당신이 스택 당신이 운영자가 발생
  2. 을 변경하고 stack.top에 액세스하지 마십시오
  3. 당신이 VALUE가 발생 빈 스택으로 시작()
0

나는 달렸다 이 문제에 너무. 문제는 다음과 같은 종류의 코드에 있다고 생각합니다.

문제는 '토큰'이 복사본이 아니라 맨 위로 이동한다는 것입니다. 따라서 토큰 작업을 마칠 때까지 스택을 팝 할 수 없습니다. 내 경우에는 정보가 여전히 존재하기 때문에 여전히 일하는 경우가 많았지 만 이상한 시간에는 정보가 손상 될 수있었습니다. '토큰'으로 작업 한 후에 만 ​​다른 방법으로이 코드를 구성해야합니다.

은 아마 무언가 같이 (! stack.empty())

else if (token.getType() == CLOSE) 
{ 
    token = stack.top(); 
    Token saveToken = new Token(token); // Or something like this... 
    stack.pop(); 

    while (saveToken.getType() != OPEN) 
    { 
     postfix.push_back(saveToken); 

     token = stack.top(); 
     delete saveToken;  // ugh 
     Token saveToken = new Token(token); 
     stack.pop(); 

    } 
    delete saveToken; //ugh 
}