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