計算機
1.程式流程
1.1 實作一個計算機。
1.2 總共有六種運算符號(+ - * / ^ $)(全部為半形)。
1.3 運算優先順序:^ > * / > + - > $。
1.4 符號 + - * / 的定義如同一般加減乘除。
1.5 定義 $ 符號是將(符號以前的所有運算結果翻轉後加上後面的數)。
舉例:125 $ 33 * 2 = 521 + 33 * 2 |43 + 52 $ 88 = 59 + 88。
1.6 定義 ^ 符號是將(前一個數開幾次方)。
舉例:125 + 52 * 3 ^ 2 = 125 + 52 * 9。
1.7 輸入格式為(數字+符號+數字+符號……+=)。
1.8 要能無限輸入,直到助教打了(數字+未定義的符號)而跳出。
1.9 注意:數字不會全部都是整數,助教有可能會輸入小數。
1.10 注意:每次運算結果中間要放空一行。
1.11 評分方式:
1.11.1 10分:全部作完且沒有輸出錯誤。
1.11.2 9分:全部做完但有錯誤或輸出格式上有瑕疵。
1.11.3 8分:實作五個符號且正確無誤。
1.11.4 7分:實作五個符號且有錯誤。
1.11.5 6分:實作四個符號且正確無誤。
1.11.6 5分:實作四個符號且有錯誤。
1.11.7 4分:實作兩個符號且正確無誤。
1.11.8 3分:實作兩個符號且有錯誤。
1.11.9 2分:無法編譯、執行錯誤。
1.11.10 0分:抄襲,沒交作業,空白檔案。
2.助教之輸入/輸出範例 (A5-105XXXXX.cpp)
/*----- ----- ----- -----*/ //Assignment 5 //Name: //Student Number: 105502555 //Course: 2016-CE1001B /*----- ----- ----- -----*/ #include <iostream> #include <cstdlib> #include <sstream> #include <cctype> #include <cmath> #include <algorithm> using namespace std; bool error=false; //<stack template> template <typename T> struct Node { T d; Node *prev; }; template <class T> class STACK // linked list implements stack { public: STACK() { idx=NULL; SIZE=0; } T top() { T cpy=idx->d; return cpy; } void pop() { Node<T> *tmp; tmp=idx; idx=idx->prev; delete tmp; SIZE--; } void push(T item) { Node<T> *nd=new Node<T>; nd->d=item; nd->prev=idx; idx=nd; SIZE++; } bool empty() { return idx==NULL; } int size() { return SIZE; } private: Node<T> *idx; int SIZE; }; //</stack template> //<parse infix> int priority(char C) { switch(C) { case '=': return -1; case '(': return 0; case '$': return 1; case '+': return 2; case '-': return 2; case '*': return 3; case '/': return 3; case '^': return 4; default: return -2; } return -2; } string infix2pofix(string Infix) { string postfix=""; int len=Infix.length(); STACK<char> opStk; //save operator for(int i=0;i<len;i++) { if(Infix[i]==' ') { continue; } if(isdigit(Infix[i])) //number { while(i<len && isdigit(Infix[i])) { postfix+=Infix[i]; i++; } i--; postfix+=' '; } else if(Infix[i]=='.') { postfix[postfix.length()-1]=Infix[i]; } else //operator { if(Infix[i]==')') { while(opStk.top()!='(') { postfix+=opStk.top(); postfix+=' '; opStk.pop(); } opStk.pop(); //pop '(' } else { while(!opStk.empty() && Infix[i]!='(') { if(opStk.top()!='(') { if(priority(opStk.top())>=priority(Infix[i])) { postfix+=opStk.top(); postfix+=' '; opStk.pop(); } else { break; } } else { break; } } opStk.push(Infix[i]); } } } while(!opStk.empty()) { postfix+=opStk.top(); postfix+=' '; opStk.pop(); } //cout << "postfix: " << postfix << endl; return postfix; } //</parse infix> //<calc postfix> double compPofix(string Postfix) { STACK<double> stk; stringstream sin(Postfix),str2num; string token; double a,b; bool neg; while(sin>>token) { //cout << "token[0]: " << token[0] << endl; switch(token[0]) { case '$': case '+': case '-': case '*': case '/': case '^': neg=true; b=stk.top(),stk.pop(); a=stk.top(),stk.pop(); if(token=="$") { //cout << "a: " << a << endl; ostringstream ostr_a; ostr_a<<a; string str_a=ostr_a.str(); reverse(str_a.begin(),str_a.end()); a=atof(str_a.c_str()); //cout << "a': " << a << endl; stk.push(a+b),neg=false; } if(token=="+") { //cout << "a,b: " << a << ", " << b << endl; //cout << "a+b: " << a+b << endl; stk.push(a+b),neg=false; } if(token=="-") { stk.push(a-b),neg=false; } if(token=="*") { stk.push(a*b),neg=false; } if(token=="/") { stk.push(a/b),neg=false; } if(token=="^") { stk.push(pow(a,b)),neg=false; } if(neg==false) { break; } case '=': break; case '.': //number case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': str2num.clear(); str2num << token; str2num >> a; stk.push(a); //cout << "str2num: " << str2num.str() << endl; //cout << "a: " << a << endl; break; default: //invalid input cout << "Invalid Input" << endl; exit(0); } } if(stk.size()!=1) { error=true; } return stk.top(); } //</calc postfix> int main(void) { string infix,postfix; while(getline(cin,infix)) { postfix=infix2pofix(infix); if(error==false) //correct input { cout << "Sum= " << compPofix(postfix) << endl << endl; } else //invalid input { cout << "Invalid Input" << endl; return 0; } } return 0; } |