2017《面向对象程序设计》课程作业六
Github鏈接
表達(dá)式用棧的實現(xiàn)
表達(dá)式的生成過程用流程圖來展示
我們通過生成一個個a+b型的小表達(dá)式,來獲得最終符合用戶要求的表達(dá)式。
首先由用戶決定(輸入y/n):
- 表達(dá)式中出現(xiàn)數(shù)字的絕對值范圍
- 表達(dá)式中出現(xiàn)數(shù)字的個數(shù)
- 是否允許乘除
- 是否允許分?jǐn)?shù)
- 是否允許括號
程序根據(jù)用戶的輸入來生成表達(dá)式,可以讓用戶對題目進行“私人訂制”,生成多種多樣的表達(dá)式。
然后通過對表達(dá)式的唯一性和是否除零的檢驗,如果通過就放入集合中,否則就重新生成。
至于合法性的檢驗,只要確保每一個a+b型的小表達(dá)式合法,則最終的表達(dá)式就合法。
代碼
/************************************************************* 文件名:Expression.cpp 作者:蓋嘉軒 日期:2017/05/09 描述: 定義——類:Expression 主要功能:表達(dá)式的生成、計算 作者:蓋嘉軒 日期:2017/05/10 *************************************************************/ #include"expression.h" #include<iostream> #include<sstream> #include<vector> #include<stack> using namespace std;Expression::Expression() { } /*隨機生成一個運算符*/ char Expression::RandomOperation(char ifMultiplyDivide) {int tmp;if (ifMultiplyDivide == 'y') //允許乘除{tmp = RandomNumber(1, 4);switch (tmp)//隨機生成運算符{case 1:{return '+';break;}case 2:{return '-';break;}case 3:{return '*';break;}case 4:{return '/';break;}}}else //不允許乘除{tmp = RandomNumber(1, 2);switch (tmp){case 1:{return '+';break;}case 2:{return '-';break;}}} }/*判斷表達(dá)式是否唯一,重復(fù)為false,唯一為true */ bool Expression::IsOnly(string expression) {int count = 0;for (unsigned i = 0; i < m_expressionUint.size(); i++){if (expression != m_expressionUint[i]){count++;}else{break;}}if (count == m_expressionUint.size()) //如果為唯一{return true;}else// 如果重復(fù){return false;} }/*生成一個中綴表達(dá)式*/ string Expression::GenerateInfixExpression(int low, int high, int parameterNumber, char ifMultiplyDivide, char ifFraction, char ifBracket) {string expression; for (; ;){string parameter1, parameter2; bool ifFirst = true; //是否已生成第一個小表達(dá)式,是為true,否為falsefor (int j = 0; j < parameterNumber - 1; j++){int ntmp;char sign = RandomOperation(ifMultiplyDivide); //運算符if (ifFraction == 'y') //允許分?jǐn)?shù){ntmp = RandomNumber(1, 3);switch (ntmp){case 1: //整數(shù)和整數(shù){stringstream sstmp1, sstmp2;sstmp1 << RandomNumber(low, high);sstmp1 >> parameter1;sstmp2 << RandomNumber(low, high);sstmp2 >> parameter2;sstmp1.clear();sstmp2.clear();break;}case 2: //整數(shù)和真分?jǐn)?shù){stringstream sstmp;sstmp << RandomNumber(low, high);sstmp >> parameter1;sstmp.clear();Fraction fraction2;fraction2.GetFraction(low, high);fraction2.Simplify();parameter2 = fraction2.TransferIntoStringNoInt();break;}case 3: //分?jǐn)?shù)和分?jǐn)?shù) {Fraction fraction1, fraction2;fraction1.GetFraction(low, high);fraction1.Simplify();fraction2.GetFraction(low, high);fraction2.Simplify();parameter1 = fraction1.TransferIntoStringNoInt();parameter2 = fraction2.TransferIntoStringNoInt();break;}}}else //不允許分?jǐn)?shù){stringstream sstmp1, sstmp2;sstmp1 << RandomNumber(low, high);sstmp1 >> parameter1;sstmp2 << RandomNumber(low, high);sstmp2 >> parameter2;sstmp1.clear();sstmp2.clear();}if (ifBracket == 'y') //允許括號{ntmp = RandomNumber(1, 4);switch (ntmp){case 1: //無括號{if (ifFirst){expression = parameter1 + sign + parameter2;ifFirst = false;}else{expression = expression + sign + parameter1;}break;}case 2: //無括號{if (ifFirst){expression = parameter2 + sign + parameter1;ifFirst = false;}else{expression = parameter1 + sign + expression;}break;}case 3: //有括號{if (ifFirst){expression = "[" + parameter1 + sign + parameter2 + "]";ifFirst = false;}else{expression = "[" + expression + sign + parameter1 + "]";}break;}case 4: //有括號{if (ifFirst){expression = "[" + parameter2 + sign + parameter1 + "]";ifFirst = false;}else{expression = "[" + expression + sign + parameter1 + "]";}break;}}}else //不允許括號{ntmp = RandomNumber(1, 2);switch (ntmp){case 1:{if (ifFirst){expression = parameter1 + sign + parameter2;ifFirst = false;}else{expression = expression + sign + parameter1;}break;}case 2:{if (ifFirst){expression = parameter2 + sign + parameter1;ifFirst = false;}else{expression = parameter1 + sign + expression;}}}}}m_infix = expression;if ((IsOnly(expression)) && (CalculateResult() != "non_comformance")) //判斷新生成的表達(dá)式是否重復(fù)以及是否出現(xiàn)除0的情況{m_expressionUint.push_back(expression);break;}}return expression; }/*將中綴表達(dá)式轉(zhuǎn)化為后綴表達(dá)式 */ void Expression::TransferInfixIntoPostfix() {unsigned i = 0;int j = 0;stack<char> signStack;//符號棧 while (i < m_infix.size()){if ((m_infix[i] >= '0') && (m_infix[i] <= '9'))//判斷數(shù)字 {while ((m_infix[i] >= '0') && (m_infix[i] <= '9')){m_postfix[j] = m_infix[i];i++;j++;}m_postfix[j] = '!'; //標(biāo)識單個整數(shù)j++;}if (m_infix[i] == '(') //判斷分?jǐn)?shù) {while (m_infix[i] != ')') //將分?jǐn)?shù)作為整體 {m_postfix[j] = m_infix[i];i++;j++;}m_postfix[j] = m_infix[i];i++;j++;}if ((m_infix[i] == '+') || (m_infix[i] == '-')) //判斷加減{while ((!signStack.empty()) && (signStack.top() != '[')){m_postfix[j] = signStack.top();j++;signStack.pop();}signStack.push(m_infix[i]);}if ((m_infix[i] == '*') || (m_infix[i] == '/'))//判斷乘除 {while ((!signStack.empty()) && (signStack.top() != '[') && ((signStack.top() == '*') || (signStack.top() == '/'))){m_postfix[j] = signStack.top();j++;signStack.pop();}signStack.push(m_infix[i]);}if (m_infix[i] == '[') //判斷'['{signStack.push(m_infix[i]);}if (m_infix[i] == ']') //判斷']' {while (signStack.top() != '['){m_postfix[j] = signStack.top();j++;signStack.pop();}signStack.pop();}i++;}while (!signStack.empty())//當(dāng)有殘余運算符時 {m_postfix[j] = signStack.top();j++;signStack.pop();}m_postfix[j] = '\0'; //設(shè)置終止符 }/*計算后綴表達(dá)式的值*/ string Expression::CalculateResult() {int i = 0;int point = -1; bool ifDivideZero = false; //是否除零,是為true,否為falseFraction numberStack[kMax]; //數(shù)棧TransferInfixIntoPostfix();while ((m_postfix[i] != '\0') && (i<1000)){if ((m_postfix[i] >= '0') && (m_postfix[i] <= '9'))//整數(shù)入棧 {double k = 0; //int會計算出錯while ((m_postfix[i] >= '0') && (m_postfix[i] <= '9')){k = 10 * k + m_postfix[i] - '0';i++;}point++;numberStack[point].TransferIntIntoFraction(k, 1);}elseif (m_postfix[i] == '(') //分?jǐn)?shù)入棧{double up = 0, down = 0;//int會計算出錯 i++;while (m_postfix[i] != '\\'){up = 10 * up + m_postfix[i] - '0';i++;}i++;while (m_postfix[i] != ')'){down = 10 * down + m_postfix[i] - '0';i++;}point++;numberStack[point].TransferIntIntoFraction(up, down);}else //進行計算{point--;switch (m_postfix[i]){case '+':{numberStack[point] = numberStack[point] + numberStack[point + 1];break;}case '-':{numberStack[point] = numberStack[point] - numberStack[point + 1];break;}case '*':{numberStack[point] = numberStack[point] * numberStack[point + 1];break;}case '/':{if (numberStack[point + 1].isDivisorZero()) //如果除數(shù)為零{ifDivideZero = true;}numberStack[point] = numberStack[point] / numberStack[point + 1];}}}i++;}if ((!ifDivideZero) && (numberStack[point].IsInt())) //如果沒有除零以及得數(shù)為整數(shù){return numberStack[point].TransferIntoString();}else{return "non_comformance";} }學(xué)習(xí)MFC
MFC(Microsoft Foundation
Classes),全稱微軟基礎(chǔ)類庫,是一個微軟公司提供的類庫(class libraries),MFC以C++類的形式封裝了Windows的API,并且包含一個應(yīng)用程序框架,以減少應(yīng)用程序開發(fā)人員的工作量。可以用于C++界面編程
優(yōu)點:
MFC的主要優(yōu)點是可以用面向?qū)ο蟮姆椒▉碚{(diào)用Windows API,以及應(yīng)用程序開發(fā)的便捷。MFC將很多應(yīng)用程序開發(fā)中常用的功能自動化,并且提供了文檔框架視圖結(jié)構(gòu)和活動文檔這樣的便于自定義的應(yīng)用程序框架。同時,在Visual C++內(nèi)部也內(nèi)建了很多對MFC的例如類向?qū)н@樣的支持以減少軟件開發(fā)的時間,使用類向?qū)Э梢陨蓮膆ello world這樣的簡單程序到活動文檔服務(wù)器這樣的復(fù)雜程序。MFC的消息映射機制也避免了使用性能較低的龐大虛函數(shù)表。
缺點:
雖然MFC的源代碼對用戶是完全開放的,但是MFC的一些封裝過程過于復(fù)雜,以致于新用戶很難迅速掌握MFC的應(yīng)用程序框架,以及在調(diào)試中定位問題的位置。同時,很多MFC對象不是線程安全的,致使在跨線程訪問MFC對象時需要編寫額外的代碼。另外,MFC的很多類依賴于應(yīng)用程序向?qū)傻拇a,使得在使用Visual C++中其他類型的應(yīng)用程序向?qū)傻墓こ讨刑砑覯FC支持的難度大大增加。
心得
雖然已經(jīng)做了那么多次的作業(yè)了,但是每一次自學(xué)新知識還是有一些“混亂”!在網(wǎng)上找一篇合適的博客都要找好久,一旦遇到問題就急得不行,可能我還是需要在歷練一下。
轉(zhuǎn)載于:https://www.cnblogs.com/gjx031602211/p/6925988.html
總結(jié)
以上是生活随笔為你收集整理的2017《面向对象程序设计》课程作业六的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tensorflow中的Session方
- 下一篇: 51. N皇后/52. N皇后 II