2015-11-07 20 views
4

我目前正在學習數據結構,我試圖用C++編寫一個程序,它使用一個數組作爲模擬堆棧。代碼應該像這樣工作:C++中的後綴計算結果只在一些時間正確的答案

用戶輸入一個Postfix表達式。表達式從左到右讀取。每次讀取數字時,它都會「彈出」到模擬堆棧上。當讀取操作數時,模擬堆棧中的前兩個數字將被「彈出」,操作數將使用這些數字執行計算,並將得到的答案「推回」到模擬堆棧上。該過程繼續,直到模擬堆棧中只剩下一個數字。這個數字是Postfix表達式的答案,它在屏幕上向用戶讀出。

我的代碼大部分工作在下面。但是,如果我模擬堆棧中的其中一個值大於或等於128,那麼該數字似乎存儲不正確(例如,+128將變成-128)。

我在做什麼錯?它與calc函數中的答案有什麼關係?具體來說,這行代碼:return answer;

任何幫助或提示將不勝感激。

#include <string> 
    #include <iostream> 
    using namespace std; 

    // Define the size of the stack: 
    #define SIZE 50 

    // Global variable declarations: 
    char stack[SIZE]; 
    int top = -1; // The top of the array 

    // Function for PUSHING operands onto the stack: 
    void push(char elem) 
    { 
     top++; 
     stack[top] = elem; 
    // cout << elem << " TESTING PUSH OUTPUT\n"; // TESTING 
    } 

    // Function for POPPING operands from the stack: 
    char pop() 
    { 
     char answer; 
     answer = stack[top]; 
     top--; 
    // cout << top << " TESTING WHAT'S POPPED\n"; // TESTING 
     return (answer); 
    } 

    // Function for CALCULATING two popped numbers: 
    double calc(char op) 
    { 
     int num1, num2, answer; 

     // Pop two numbers from the stack: 
     num1 = pop(); 

     num2 = pop(); // put the second popped number into 'num2' 

     // Calculate the two popped numbers: 
     switch (op) 
     { 
     case '*': 
      answer = num2 * num1; 
      break; 
     case '/': 
      answer = num2/num1; 
      break; 
     case '+': 
      answer = num2 + num1; 
      break; 
     case '-': 
      answer = num2 - num1; 
      break; 
     default: 
      cout << "Invalid expression!"; 
     } 

     // Push the result of the calculation back onto the stack: 
     push(answer); 

     return answer; 

    } 

    // The main program, which takes in the expression: 
    int main() 
    { 
     string postfix; 

     int solution; 

     cout << "Please enter a Postfix expression, with operators and operands separated by spaces and/or commas (e.g: 3 7 5 + 2 - * 16 4 + 10//): \n"; 
     getline(cin,postfix); 

     // If the User's Postfix expression begins with an operator, then throw up an error message: 
     if (postfix.find('/') == 0 || postfix.find('*') == 0 || postfix.find('+') == 0 || postfix.find('-') == 0) 
     { 
      cout << "Sorry, that's an invalid Postfix expression, and it can't be evaluated."; 

      return 0; 

     } 

     // FOR loop to read the Postfix expression: 
     for(unsigned int i = 0; i < postfix.length(); i++) 
     { 

      // If the value is a space or a comma, move on to the next value: 
      if(postfix[i] == ' ' || postfix[i] == ',') 
      { 
       continue; 
      } // End IF 

      // If the value is a number, extract it, and continue reading and extracting the next value until it is NOT a number: 
      else if(isalnum(postfix[i])) 
      { 

       int operand = 0; 

       while(i < postfix.length() && isalnum(postfix[i])) 
       { 
        // For multi-digit numbers, multiply the initial extracted number by 10 to move it into the 'tens' column, then add the next number to the initial number. 
        // Continue doing this until the next value is NOT a number 
        operand = (operand * 10) + (postfix[i] - '0'); 
        i++; 
       } // End WHILE 

       // When WHILE exits, 'i' will be non-numeric, of the 'end of the string'. Decrement 'i', because it will be incremented in the FOR loop as longs as the FOR condition is true 
       // (Stops 'i' from being incremented twice) 
       i--; 

       // Push the operand onto the stack: 
       push(operand); 
      } // End ELSE IF 

      // If the value is an operator, run the calculation function: 
      else 
      { 
       calc(postfix[i]); 
      } // End ELSE 

     } // End FOR 

     solution = pop(); // put the solution of the equation into 'answer' 

     cout << "The solution to the Postfix expression is: " << solution; 

    } 
+3

你的堆棧元素是'char',因爲你的默認'char'類型必須是'signed'。因此無法存儲除-128..127之外的任何內容。 – usr2564301

回答

2

operand類型爲intpush預計爲char

因爲在大多數機器sizeof(int) > sizeof(char)上,如果operand的值試圖存儲在像char這樣的較小數據類型中,它的值可能會被截斷。

例如,我們假設sizeof(int) == 4sizeof(char) == 1,一個字節是8位。現在,如果只設置了位(從0開始),則char將不能保存該信息,並且值0x100被截斷爲0x00

爲了解決這個問題,可以使堆棧處理ints或將operand定義爲char

+0

@ tobi303噢,是的。謝謝你。 – Downvoter

+0

......我不敢相信我沒有抓住這個。感謝百萬@cad,這是完全意義上的。在讓我的堆棧處理int後,將'int'傳遞給'push'函數,並將'pop'函數改爲使用'int',一切都按預期工作。 – Dizzzeh

1

所有你需要做的是讓你的模擬int類型,而不是char(和其他相關的變化)的stack

+0

計算例程使用'double',所以最終的結果仍然會被強制轉換爲'int' ... – usr2564301

1

你的棧是char類型,通常被限制在-128到127之間。嘗試unsigned char,它可能是0到255.如果你的棧上需要更大的值,那麼你將使它成爲一個整數或更大的東西。