支持多位數,括號,四則運算,的計算器算法c++實現

#include<iostream>

#include<string>

#include<stack>

#include<stdio.h>

using namespace std;

//23+(34*45)/(5+6+7)

//2+3*5+6+7

int priority(char c)

{

if (c == ')')

{

return 4;

}

else if (c == '^')

{

return 3;

}

else if (c == '*' || c == '/' || c == '%')

{

return 2;

}

else if (c == '+' || c == '-')

{

return 1;

}

else if (c == '(')

{

return 0;

}

else

{

cout << "不符合要求的字符!" << endl;

return -1;

}

} //返回字符c的優先級

bool isNumber(char c)

{

if (c >= '0'&& c <= '9')

{

return true;

}

else

{

return false;

}

}

bool isOperator(char c)

{

if (c == '+' || c == '-' || c == '*' || c == '/' || c == '%')

{

return true;

}

else

{

return false;

}

}

bool isBracket(char c)

{

if (c == '(' || c == ')')

{

return true;

}

else

{

return false;

}

}

double charToDouble(char c)

{

return (double)(c - '0');

}

double stringToDouble(string s)

{

return atof(s.c_str());

}

int stringToInt(string s)

{

return atoi(s.c_str());

}

char doubleToChar(double d)

{

return (char)(d + 48);

}

string doubleToString(double d)

{

return to_string(d);

}

double charBasicCalculate(char left, char op, char right)

{

if (isNumber(left) && isNumber(right))

{

if (op == '+')

{

return (charToDouble(left) + charToDouble(right));

}

else if (op == '-')

{

return (charToDouble(left) - charToDouble(right));

}

else if (op == '*')

{

return (charToDouble(left) * charToDouble(right));

}

else if (op == '/')

{

return (charToDouble(left) / charToDouble(right));

}

else if (op == '%')

{

return (left - '0') % (right - '0');

}

else

{

cout << "操作符錯誤!";

return -1;

}

}

else

{

cout << "錯誤運算參數";

return -1;

}

}//返回double 的基本計算函數

double doubleBasicCalculate(double left, char op, double right)

{

if (op == '+')

{

return left + right;

}

else if (op == '-')

{

return left - right;

}

else if (op == '*')

{

return left*right;

}

else if (op == '/')

{

return left / right;

}

else if (op == '%')

{

return (int)left % (int)right;

}

else

{

cout << "操作符錯誤!";

return -1;

}

}

double stringBasicCalculate(string left, char op, string right)

{

if (op == '+')

{

return (stringToDouble(left) + stringToDouble(right));

}

else if (op == '-')

{

return (stringToDouble(left) - stringToDouble(right));

}

else if (op == '*')

{

return (stringToDouble(left) * stringToDouble(right));

}

else if (op == '/')

{

return (stringToDouble(left) / stringToDouble(right));

}

else if (op == '%')

{

return (stringToInt(left)) % (stringToInt(right));

}

else

{

cout << "操作符錯誤!";

return -1;

}

}

bool isExpression(const char* expression)//判斷表達式是否合法

{

int i = 0;

int leftBracket=0;//記錄左括號個數

int rightBracket=0;//記錄右括號個數

while (expression[i] != '\0')

{

if (expression[i] == ' ')

{

cout << "不要輸入空格!";

return false;

}

if (i == 0 && !(isNumber(expression[i]) || isBracket(expression[i])))//第一個元素不是數字或者左括號

{

cout << "異常1";

return false;

}

if (!(isNumber(expression[i]) || isOperator(expression[i]) || isBracket(expression[i])))//其它符合要求的字符

{

cout << "異常2";

return false;

}

if (i != 0 && isOperator(expression[i - 1]) && (isOperator(expression[i]) || expression[i] == ')'))//操作符后還是操作符或右括號不合法

{

cout << "異常3";

return false;

}

if (i!=0 && expression[i-1] == '(' && !isNumber(expression[i]))//左括號右邊不是數字debug2(i-1誤寫i)

{

cout << "異常4";

return false;

}

else

{

if (expression[i] == '(')

leftBracket++;

if (expression[i] == ')')

rightBracket++;

}

i++;//debug1添加上i++;

}

if (leftBracket == rightBracket)

{

return true;//表達式合理

}

else

{

cout << "異常5";

return false;

}

}

string dealBasicChar(char c, int n)//c表示位上的字符,n表示位級別,234,中c=2時n=2,c=3時,n=1,c=4時,n=0每個字符拆成0-9內

{

string temp;

temp.append(1,c);

for (int i = 0; i < n; i++)

{

temp.append("*(9+1)");

}

/*cout << "dealBasicChar" << temp << endl;*/

return temp;

}

string dealBasicString(string s)

{

string temp;

temp.append("(");

int size = s.size();

for (int i = 0;i

{

temp.append(dealBasicChar(s.at(i), size - i - 1));

if (i != size - 1)//不是最后,添加"+";

{

temp.append("+");

}

}

temp.append(")");

/*cout << "dealBasciString" << temp << endl;*/

return temp;

}

string dealExpression(const char* expression)//化為0-9以內的表達式:23+12:(9+1+9+1+3)+(9+1+2)

{

string temp = expression;

string temp2;

string texpression;

int i=0;

while(i

{

if (i!=temp.size()-1 && isNumber(temp.at(i)) && isNumber(temp.at(i+1)))//探測是否是多位數//debug當i=temp.size()-1時調用temp.at(i+1)發生越界,加上條件,i!=temp.size()-1,當i=temp.size()-1時由&&的處理原則,前面不成立不會執行后面條件.

{

/*cout << i<

int j;

for ( j = 0; isNumber(temp.at(i + j)); j++)

{

temp2.append(1,temp.at(i+j));//獲得多位數存儲在temp2中

}

texpression.append(dealBasicString(temp2));//轉化為標準表達式并加入texpression中。

temp2.clear();//debug1:temp2為歸零導致錯誤.

/*cout << texpression << endl;*/

i = i + j ;

}

else

{

texpression.append(1,temp.at(i));

i++;

}

}

/*cout << texpression<

return texpression;

}

double infixCalculate(const char* expression)//直接計算中綴表達式debug1括號括號優先級設置出錯 OK

{

stack opStack;

stack nuStack;

for (int i = 0; expression[i] != '\0'; i++)

{

if (isNumber(expression[i]))

{

cout << "isNumber" << endl;

nuStack.push(string(1,expression[i]));//轉化為string

}

else if (isOperator(expression[i]))

{

cout << "isOperator" << endl;

if (opStack.empty())//棧為空直接將操作符壓入

{

cout << "empty()" << endl;

opStack.push(expression[i]);

}

else//區分優先級

{

cout << "not empty()" << endl;

if (priority(opStack.top()) < priority(expression[i]))

{

cout << "priority" << endl;

opStack.push(expression[i]);

}

else

{

cout << "not priority" << endl;

char op=opStack.top();//stack.top返回頂端元素不刪除,stack.pop無返回值只刪除頂端元素

opStack.pop();

string left = nuStack.top();

nuStack.pop();

string right = nuStack.top();

nuStack.pop();

nuStack.push(doubleToString(stringBasicCalculate(left, op, right)));

opStack.push(expression[i]);

}

}

}

else if (expression[i] == '(')

{

cout << "左括號" << endl;

opStack.push(expression[i]);

}

else if (expression[i] == ')')

{

cout << "右括號" << endl;

while (1)

{

if (opStack.top() == '(')

{

opStack.pop();//彈出左括號結束

break;

}

else

{

char op = opStack.top();

opStack.pop();

string left = nuStack.top();

nuStack.pop();

string right = nuStack.top();

nuStack.pop();

nuStack.push(doubleToString(stringBasicCalculate(left, op, right)));

}

}

}

else

{

cout << "符號錯誤!" << endl;

}

}

while (1)//計算剩余操作符

{

if (opStack.empty())

{

break;

}

else

{

char op = opStack.top();

opStack.pop();

string left = nuStack.top();

nuStack.pop();

string right = nuStack.top();

nuStack.pop();

nuStack.push(doubleToString(stringBasicCalculate(left, op, right)));

}

}

return stringToDouble(nuStack.top());

}

double postfixCalculate(const char* expression)

{

stack nuStack;

for (int i = 0; expression[i] != '\0'; i++)

{

if (isNumber(expression[i]))

{

nuStack.push(string(1, expression[i]));

}

else if (isOperator(expression[i]))

{

char op = expression[i];

string left = nuStack.top();

nuStack.pop();

string right = nuStack.top();

nuStack.pop();

nuStack.push(doubleToString(stringBasicCalculate(left, op, right)));

}

else

{

cout << "符號錯誤!" << endl;

}

}

return stringToDouble(nuStack.top());

}

string infixTranPostfix(const char* expressionIn)

{

stack opStack;

string temp;

for (int i = 0; expressionIn[i] != '\0'; i++)

{

if (isNumber(expressionIn[i]))

{

temp.append(1, expressionIn[i]);

}

else if (isOperator(expressionIn[i]))

{

if (opStack.empty())

{

opStack.push(expressionIn[i]);

}

else

{

if (priority(opStack.top()) < priority(expressionIn[i]))

{

opStack.push(expressionIn[i]);

}

else

{

temp.append(1, opStack.top());

opStack.pop();

opStack.push(expressionIn[i]);

}

}

}

else if (expressionIn[i] == '(')

{

opStack.push(expressionIn[i]);

}

else if (expressionIn[i] == ')')

{

while (1)

{

if (opStack.top() == '(')

{

opStack.pop();

break;

}

else

{

temp.append(1, opStack.top());

opStack.pop();

}

}

}

else

{

cout << "符號錯誤!";

}

}

while (1)

{

if (opStack.empty())

{

break;

}

else

{

temp.append(1, opStack.top());

opStack.pop();

}

}

return temp;

}

double calculate1(const char* expression)

{

if (isExpression(expression))

{

string tExpression = dealExpression(expression);

string ttExpression = infixTranPostfix(tExpression.c_str());

return postfixCalculate(ttExpression.c_str());

}

else

{

cout << "表達式錯誤!" << endl;

}

}

double calculate2(const char* expression)

{

if (isExpression(expression))

{

string s = dealExpression(expression);

return infixCalculate(s.c_str());

}

else

{

cout << "表達式錯誤!" << endl;

}

}

int main()

{

cout << "輸入一個表達式:" << endl;

string expression;

cin >> expression;

cout << "計算結果為:" << endl;

cout << calculate2(expression.c_str())<

/*cout << "請輸入表達式:" << endl;

string expression;

cin >> expression;

cout << "計算結果為:" << endl;

cout << calculate(expression.c_str())<

/*cout << "測試6:postfixCalculate" << endl; OK

string s1 = "1+2+2*3+4+(1+2*3)";

cout << infixTranPostfix(s1.c_str());*/

//5 測試 infixCalculate OK

//4 測試deal expression() Ok

/*string expression;

cin >> expression;

cout << dealExpression(expression);*/

/*char* expression;

double result;

cout << "輸入表達式:" << endl;

cin >> expression;*/

//1 測試isNumber(),isOperator(),isBracket() ?OK

//char c;

//cin >> c;

//if (isNumber(c))

//cout << "數字";

//else if (isOperator(c))

//cout << "操作符";

//else if (isBracket(c))

//cout << "括號";

//else

//cout << "其它字符";

//2 測試isExpression() ?OK

//char expression[100];

//cin >> expression;

//if (isExpression(expression))

//cout << "是表達式" << endl;

//else

//cout << "不是表達式" << endl;

//3 測試basicCalculat() ? OK

/*cout << basicCalculate('3', '%', '5');*/

/*int a = toascii('s');

int b = 's' - '0'+48;

cout << a << endl << b << endl;*/

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內容