日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构课程设计:算术表达式的求值

發布時間:2023/12/9 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构课程设计:算术表达式的求值 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、課程設計題目及內容
[問題描述]
  一個算術表達式是由操作數(operand)、運算符(operator)和界限符(delimiter)組成的。假設操作數是正實數,運算符只含加減乘除等四種運算符,界限符有左右括號和表達式起始、結束符“#”,如:#(7+15)*(23-28/4)#。引入表達式起始、結束符是為了方便。編程利用“運算符優先法”求算術表達式的值。
[基本要求]
(1) 從鍵盤或文件讀入一個合法的算術表達式,輸出正確的結果。
(2) 顯示輸入序列和棧的變化過程。
(3) 考慮算法的健壯性,當表達式錯誤時,要給出錯誤原因的提示。

二、程序中使用的數據結構及主要符號說明
程序中使用了堆棧,其中OPTR為運算符棧(運算符包括‘+’‘-’‘*’‘/’‘(’‘)’‘[’‘]’’{’’}’’#’),OPND為操作數棧(操作數包括‘0’’1’’2’’3’’4’‘5’‘6’‘7’‘8’‘9’)
三、程序流程圖和帶有注釋的源程序

源代碼:

#include<iostream> using namespace std; typedef struct SNode1//運算符棧鏈 {char data;struct SNode1* next; }StackNode1, * Linkstack1; typedef struct SNode2//數字棧鏈 {int data;struct SNode2* next; }StackNode2, * Linkstack2; void InitStack1(Linkstack1& S)//初始化運算符棧鏈 {S = NULL; } void InitStack2(Linkstack2& S)//初始化數字棧鏈 {S = NULL; } void push1(Linkstack1& S, char ch)//運算符入棧 {Linkstack1 p;p = (Linkstack1)malloc(sizeof(Linkstack1));p->data = ch;p->next = S;S = p; } void push2(Linkstack2& S, int ch)//數字入棧 {Linkstack2 p;p = (Linkstack2)malloc(sizeof(Linkstack2));p->data = ch;p->next = S;S = p; } char GetTop1(Linkstack1& S)//獲得運算符棧棧頂元素 {if (S != NULL)return S->data; } int GetTop2(Linkstack2& S)//獲得數字符棧棧頂元素 {if (S != NULL)return S->data; } void pop1(Linkstack1& S, char& e)//用元素e存儲當前運算符棧棧頂元素 { //彈出棧頂元素,棧頂指針指向下一元素e = GetTop1(S);if (S != NULL){S = S->next;} } void pop2(Linkstack2& S, int& e)//用元素e存儲當前數字棧棧頂元素 { //彈出棧頂元素,棧頂指針指向下一元素if (S != NULL){e = GetTop2(S);S = S->next;} } int In(char ch)//In函數檢測字符ch是運算符還是數字 { //若為運算符,返回1;若為數字,返回0switch (ch){case '(':return 1;case ')':return 1;case '+':return 1;case '-':return 1;case '*':return 1;case '/':return 1;case '#':return 1;case '[':return 1;case ']':return 1;case '{':return 1;case '}':return 1;default: return 0;} } char Precede(char a, char b)//比較運算符優先級 {if (b == '+'){if (a == '(' || a == '#' || a == '[' || a == '{') return '<';return '>';}if (b == '-'){if (a == '(' || a == '#' || a == '[' || a == '{') return '<';return '>';}if (b == '*'){if (a == '*' || a == '/' || a == ')' || a == ']' || a == '}') return '>';return '<';}if (b == '/'){if (a == '*' || a == '/' || a == ')' || a == ']' || a == '}') return '>';return '<';}if (b == '(') return '<';if (b == ')'){if (a == '(') return '=';return '>';}if (b == '#'){if (a == '#') return '=';return '>';}if (b == '['){if (a == ')') return '>';return '<';}if (b == ']'){if (a == '[') return '=';return '>';}if (b == '{'){if (a == ')' || a == ']') return '>';return '<';}if (b == '}'){if (a == '{') return '=';return '>';} } int Operate(int a, char op, int b)//根據運算符,進行運算 {switch (op){case '+':return a + b; break;case '-':return a - b; break;case '*':return a * b; break;case '/':return a / b; break;} } void Cout_stack1(Linkstack1& S)//輸出運算符棧元素 {Linkstack1 T;T = new StackNode1;T = S;if (T == NULL){cout << "運算符棧為空!!";}while (T){cout << T->data << '\t';T = T->next;}cout << endl; }void Cout_stack2(Linkstack2& S)//輸出字符棧元素 {Linkstack2 T;T = new StackNode2;T = S;if (T == NULL){cout << "操作數棧為空!!";}while (T){cout << T->data << '\t';T = T->next;}cout << endl; } int EvaluateExpression() {char theta = 0, x = 0;int a = 0, b = 0;Linkstack1 OPTR;//運算符Linkstack2 OPND;//操作數Linkstack1 q;InitStack1(OPTR);InitStack2(OPND);InitStack1(q);cout << "請輸入算術表達式:";push1(OPTR, '#');char ch;cin >> ch;cout << "----------------------------------------" << endl;if (ch == ')' ||ch==']'||ch=='}'|| ch == '+' || ch == '-' || ch == '*' || ch == '/'){cout << "輸入錯誤!!!表達式第一個值不能為運算符" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}cout << "初始運算符棧:";Cout_stack1(OPTR);cout << "初始操作數棧:";Cout_stack2(OPND);cout << "----------------------------------------" << endl;while (ch != '#' || GetTop1(OPTR) != '#'){cout << "輸入序列:" << ch << endl;q = OPTR;if (ch != '#' && ch != '0' && ch != '1' && ch != '2' && ch != '3' && ch != '4' && ch != '5' && ch != '6' && ch != '7' && ch != '8' && ch != '9' && ch != '+' && ch != '-' && ch != '*' && ch != '/' && ch != '(' && ch != ')' && ch != '[' && ch != ']' && ch != '{' && ch != '}'){cout << "錯誤!!!非法輸入!!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}//檢測非法輸入if (ch == ')'){while (q->data != '(' && q->next){q = q->next;}if (q->data != '('){cout << "錯誤!!!右小括號輸入過多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}}//括號匹配if (ch == ']'){while (q->data != '[' && q->next){q = q->next;}if (q->data != '['){cout << "錯誤!!!右中括號輸入過多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}}//括號匹配if (ch == '}'){while (q->data != '{' && q->next){q = q->next;}if (q->data != '{'){cout << "錯誤!!!右大括號輸入過多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}}//括號匹配if (!In(ch))//In函數檢測字符ch是運算符還是數字{ //若為運算符,返回1;若為數字,返回0int q = 0;q = ch - 48;int temp, temp1;push2(OPND, q);cin >> ch;cout << "輸入序列:" << ch << endl;for (int i = 0; i < 99; i++){if (ch >= 48 && ch <= 57){int l = ch - 48;pop2(OPND, temp);temp1 = temp * 10 + l;push2(OPND, temp1);cin >> ch;cout << "輸入序列:" << ch << endl;}}}else{switch (Precede(GetTop1(OPTR), ch))//運算符優先級比較{case'<':push1(OPTR, ch); cin >> ch; break;case'>':pop1(OPTR, theta); pop2(OPND, b);if (OPND == NULL){cout << "錯誤!!!運算符過多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}//檢測運算符是否過多pop2(OPND, a);push2(OPND, Operate(a, theta, b)); break;case'=':pop1(OPTR, x); cin >> ch; break;}}if (ch == '#'){if (q->data == '('){q = q->next;if (q->data == '('){cout << "錯誤!!!左小括號輸入過多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}}}//括號匹配if (ch == '#'){if (q->data == '['){q = q->next;if (q->data == '['){cout << "錯誤!!!左中括號輸入過多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}}}//括號匹配if (ch == '#'){if (q->data == '{'){q = q->next;if (q->data == '{'){cout << "錯誤!!!左大括號輸入過多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}}}//括號匹配cout << "運算符棧:";Cout_stack1(OPTR);cout << "操作數棧:";Cout_stack2(OPND);cout << "----------------------------------------" << endl;}cout << "運算符棧:";Cout_stack1(OPTR);cout << "操作數棧:";Cout_stack2(OPND);cout << "----------------------------------------" << endl;return GetTop2(OPND); } int main() {for (int i = 0; i < 40; i++){cout << "歡迎使用算術表達式計算器!!" << endl;cout << "注意:輸入結束時請用#符號結束,否則將使程序崩潰!!!!" << endl;int a = EvaluateExpression();if (a != 77777){cout << "運算結果為:" << a << endl;cout << "----------------------------------------" << endl;cout << endl;}} }

四、執行程序,并打印程序運行時的初值和運算結果
輸入120/{240/[120/(1+1)]}#,程序將進行運算,打印出輸入序列,運算符棧和操作數棧里的內容,最后輸出運算結果為30


五、實驗結果分析,實驗收獲和體會
考慮到算法的健壯性,考慮各種錯誤輸入時,算法進行判斷,并給出錯誤原因
1、非法輸入時,如abcd或!&,系統會自動進行判斷

2、括號不匹配時,如左括號過多或者右括號過多,系統也會進行報錯,其中包括各種括號()[]{}






3、當輸入的運算符過多時,會導致操作數不夠用,系統會識別并且報錯


六、實驗的改進意見和建議
程序還需改進:
1、當用戶輸入算術表達式時,如果沒有輸入#,算法不會報錯,并且直接進行下去直到識別最后一個字符時才會停止,此時輸入#才能繼續進行算法.
建議:運用數組先存儲輸入進去的全部字符,掃描最后一個字符是否為#,若是#才能進行算法;若不是,系統報錯,停止算法。
2、算術表達式無法輸入負數.
建議:增加對于‘-’(ch=45)的判別函數
3、對于浮點數的運算沒有實現.
建議:增加對于‘.’(ch=46)的判別函數

總結

以上是生活随笔為你收集整理的数据结构课程设计:算术表达式的求值的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。