1. 程式人生 > >小程式之計算器 【C++ STL棧實現】 + 【C 陣列模擬棧實現】 【適用VC, DEV, codeblack】

小程式之計算器 【C++ STL棧實現】 + 【C 陣列模擬棧實現】 【適用VC, DEV, codeblack】

自己寫的小程式,記錄一下提醒這兩個只能在DEV或者codeblack 執行。 VC能執行的在最後面(哎,畢竟課程設計是在VC裡面測試)。

 C++版本的,用STL棧實現的:

#include <cstdio>
#include <cstring>
#include <stack>
#include <cstdlib>
#include <windows.h>
using namespace std;
int in = 0, out = 0;
void input()
{
	system("color 1f");
	printf("**********************************簡單計算器**********************************\n\n");
	printf("********************功能:實現小數和整數加減乘除四則混合運算*******************\n\n");
	printf(">>>>>>>>>>>輸入: (加號 +) (減號 -) (乘號 *) (除號 /) (數字正常輸入)>>>>>>>>>>>\n\n"); 
	printf("!!!!!!!!!!!!!!!提醒:可以有多個括號, 但模仿計算器不能輸入等號(=)!!!!!!!!!!!!!!!\n\n"); 
	printf("<<<<<<<<<<<<<<<<<<<<<<<<輸出:請按回車(預設保留6位小數)<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
	printf("\n");
	printf("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&模擬鍵盤&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n");
	printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^[  7   8   9   /   (  ]^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
	printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  4   5   6   *   )  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
	printf("____________________________[  1   2   3   -   =  ]___________________________\n");
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~[    0     .   +      ]~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
	printf("\n");
	printf("!!!!!!!!!!!!!輸入像1+2/5*6-7型別的表示式,否則可能無法得到正確結果!!!!!!!!!!!!!\n"); 
	printf("!!!!!!!!!!!!!如果程式出錯誤,應該是輸入出了問題,記著錯誤關閉再開啟!!!!!!!!!!!!!\n");
	printf("@@@@@@@@@@@使用者輸入模擬鍵盤上的數字及運算子,該計算器可以處理空格哦@@@@@@@@@@\n");
	
	printf("\n");
} 
void inputcolor()
{
	if(in > 16)
	in -= 16;
	switch(in)
	{
		case 0: system("color 0f"); break;
		case 1: system("color 1e"); break;
		case 2: system("color 2d"); break;
		case 3: system("color 3c"); break;
		case 4: system("color 4b"); break;
		case 5: system("color 5a"); break;
		case 6: system("color 69"); break;
		case 7: system("color 78"); break;
		case 8: system("color f0"); break;
		case 9: system("color e1"); break;
		case 10:system("color d2"); break;
		case 11:system("color c3"); break;
		case 12:system("color b4"); break;
		case 13:system("color a5"); break;
		case 14:system("color 96"); break;
		case 15:system("color 87"); break;
	}
	in++;
}
void outputcolor()
{
	if(out > 16)
	out -= 16;
	switch(out)
	{
		case 15:system("color 0f"); break;
		case 14:system("color 96"); break;
		case 13:system("color d8"); break;
		case 12:system("color 3c"); break;
		case 11:system("color 4b"); break;
		case 10:system("color 5a"); break;
		case 9: system("color 69"); break;
		case 8: system("color 72"); break;
		case 7: system("color f0"); break;
		case 6: system("color e1"); break;
		case 5: system("color 2e"); break;
		case 4: system("color ca"); break;
		case 3: system("color b4"); break;
		case 2: system("color a5"); break;
		case 1: system("color 97"); break;
		case 0: system("color 8f"); break;
	}
	out++;
}
char compare(char a, char b)//比較運算子a,b優先順序 
{
	if(a == '+' || a == '-')
	{
		if(b == '*' || b == '/' || b == '(')
		return '<';
		else
		return '>';//連續的加減 優先前面的算 
	}
	if(a == '*' || a == '/')
	{
		if(b == '(')
		return '<';
		else
		return '>';//連續的乘除 優先前面的算 
	}
	if(a == '(')
	{
		if(b == ')')
		return '=';
		else
		return '<';//優先括號裡面的運算子 
	}
	if(a == '=')
	{
		if(b == '=')
		return '=';
		else
		return '<';//因為儲存運算子的棧頂為 = 所以後來碰到的運算子除了=外 優先順序均比它高   
	}
}
double work(double a, char op, double b)//對浮點數 a b 進行四則運算 
{
	switch(op)
	{
		case '+': return a + b;
		case '-': return a - b;
		case '*': return a * b;
		case '/': return a / b;
	}
}
bool judge(char a)//判斷字元 是否是數字或者小數點 
{
	return a >= '0' && a <= '9' || a == '.';
}
int main()
{
	input();//列印計算器 視窗 
	int i, j;
	int len;
	char str[1010];//輸入的運算式 
	char s[1010];//把浮點數當成字元儲存起來  
	int t;//記錄儲存浮點數的 字元陣列的位數 
	int exist;//標記是否出現數字 
    double x, y, z;//求每一步的值 用到的變數 
	while(gets(str))//輸入計算內容 
	{
		inputcolor();
		len = strlen(str);
		str[++len] = '=';//在末尾新增一個 =  
		stack<double> num;//儲存浮點數 
		stack<char> op;//儲存運算子 
		op.push('=');//逆波蘭式  = 先進棧 
		t = 0;
		exist = 0;
		for(i = 0; i < len;)
		{
			if(str[i] == ' ')//碰到空格 
			{
				i++;
				continue;
			}
			if(judge(str[i]))
			{
				s[t++] = str[i++];//字串後移一位 
				exist = 1;//出現數字 
				continue;
			}
			if(exist)//出現過數字 且當前字元是運算子 
			{
				s[t] = '\0';
				num.push(atof(s));//上一數字 進棧 
				t = exist = 0;//初始化 
			} 
			/*下面比較上一運算子 和 當前運算子優先順序 */
			/* 若 < 進棧,若 > 計算,若 = 上一運算子出棧*/
			switch(compare(op.top(), str[i]))
			{
				case '<': op.push(str[i++]); break;//字串後移一位 
				case '=': op.pop(), i++;     break;//上一運算子出棧 字串後移一位 
				case '>': x = num.top(), num.pop();
				          y = num.top(), num.pop();
						  z = work(y, op.top(), x), op.pop();//用過的運算子出棧 
						  num.push(z);       break;//新浮點數進棧 
			} 
		}
		outputcolor();
		printf("%.6lf\n", num.top()); 
	}
	return 0;
}


C寫的, 用陣列模擬棧:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
int in = 0, out = 0;
void input()
{
	system("color 1f");
	printf("**********************************簡單計算器**********************************\n\n");
	printf("********************功能:實現小數和整數加減乘除四則混合運算*******************\n\n");
	printf(">>>>>>>>>>>輸入: (加號 +) (減號 -) (乘號 *) (除號 /) (數字正常輸入)>>>>>>>>>>>\n\n"); 
	printf("!!!!!!!!!!!!!!!提醒:可以有多個括號, 但模仿計算器不能輸入等號(=)!!!!!!!!!!!!!!!\n\n"); 
	printf("<<<<<<<<<<<<<<<<<<<<<<<<輸出:請按回車(預設保留6位小數)<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
	printf("\n");
	printf("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&模擬鍵盤&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n");
	printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^[  7   8   9   /   (  ]^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
	printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  4   5   6   *   )  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
	printf("____________________________[  1   2   3   -   =  ]___________________________\n");
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~[    0     .   +      ]~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
	printf("\n");
	printf("!!!!!!!!!!!!!輸入像1+2/5*6-7型別的表示式,否則可能無法得到正確結果!!!!!!!!!!!!!\n"); 
	printf("!!!!!!!!!!!!!如果程式出錯誤,應該是輸入出了問題,記著錯誤關閉再開啟!!!!!!!!!!!!!\n");
	printf("@@@@@@@@@@@使用者輸入模擬鍵盤上的數字及運算子,該計算器可以處理空格哦@@@@@@@@@@\n");
	
	printf("\n");
} 
void inputcolor()
{
	if(in > 16)
	in -= 16;
	switch(in)
	{
		case 0: system("color 0f"); break;
		case 1: system("color 1e"); break;
		case 2: system("color 2d"); break;
		case 3: system("color 3c"); break;
		case 4: system("color 4b"); break;
		case 5: system("color 5a"); break;
		case 6: system("color 69"); break;
		case 7: system("color 78"); break;
		case 8: system("color f0"); break;
		case 9: system("color e1"); break;
		case 10:system("color d2"); break;
		case 11:system("color c3"); break;
		case 12:system("color b4"); break;
		case 13:system("color a5"); break;
		case 14:system("color 96"); break;
		case 15:system("color 87"); break;
	}
	in++;
}
void outputcolor()
{
	if(out > 16)
	out -= 16;
	switch(out)
	{
		case 15:system("color 0f"); break;
		case 14:system("color 96"); break;
		case 13:system("color d8"); break;
		case 12:system("color 3c"); break;
		case 11:system("color 4b"); break;
		case 10:system("color 5a"); break;
		case 9: system("color 69"); break;
		case 8: system("color 72"); break;
		case 7: system("color f0"); break;
		case 6: system("color e1"); break;
		case 5: system("color 2e"); break;
		case 4: system("color ca"); break;
		case 3: system("color b4"); break;
		case 2: system("color a5"); break;
		case 1: system("color 97"); break;
		case 0: system("color 8f"); break;
	}
	out++;
}
char compare(char a, char b)//比較運算子a,b優先順序 
{
	if(a == '+' || a == '-')
	{
		if(b == '*' || b == '/' || b == '(')
		return '<';
		else
		return '>';//連續的加減 優先前面的算 
	}
	if(a == '*' || a == '/')
	{
		if(b == '(')
		return '<';
		else
		return '>';//連續的乘除 優先前面的算 
	}
	if(a == '(')
	{
		if(b == ')')
		return '=';
		else
		return '<';//優先括號裡面的運算子 
	}
	if(a == '=')
	{
		if(b == '=')
		return '=';
		else
		return '<';//因為儲存運算子的棧頂為 = 所以後來碰到的運算子除了=外 優先順序均比它高   
	}
}
double work(double a, char op, double b)//對浮點數 a b 進行四則運算 
{
	switch(op)
	{
		case '+': return a + b;
		case '-': return a - b;
		case '*': return a * b;
		case '/': return a / b;
	}
}
int judge(char a)//判斷字元 是否是數字或者小數點 
{
	return (a >= '0' && a <= '9' || a == '.') ? 1 : 0;
}
int main()
{
	input();//列印計算器 視窗 
	int i, j;
	int len;
	char str[1010];//輸入的運算式 
	char s[1010];//把浮點數當成字元儲存起來  
	int t;//記錄儲存浮點數的 字元陣列的位數 
	int exist;//標記是否出現數字 
    double x, y, z;//求每一步的值 用到的變數 
    int numtop;//浮點數陣列頂部 用陣列模擬棧 
	int optop;//運算子陣列頂部 模擬棧 
	while(gets(str))//輸入計算內容 
	{
		inputcolor();
		numtop = optop = 0;//初始化 
		len = strlen(str);
		str[++len] = '=';//在末尾新增一個 =  
		double num[1010];//儲存浮點數 
		char op[1010];//儲存運算子 
		op[optop++] = '=';//逆波蘭式  = 先進棧 
		t = 0;
		exist = 0;
		for(i = 0; i < len;)
		{
			if(str[i] == ' ')//碰到空格 
			{
				i++;
				continue;
			}
			if(judge(str[i]))
			{
				s[t++] = str[i++];//字串後移一位 
				exist = 1;//出現數字 
				continue;
			}
			if(exist)//出現過數字 且當前字元是運算子 
			{
				s[t] = '\0';
				num[numtop++] = atof(s); //模擬進棧 
				t = exist = 0;//初始化 
			} 
			/*下面比較上一運算子 和 當前運算子優先順序 */
			/* 若 < 進棧,若 > 計算,若 = 上一運算子出棧*/
			switch(compare(op[optop-1], str[i]))
			{
				case '<': op[optop++] = str[i++]; break;//字串後移一位 
				case '=': optop--, i++;     break;//上一運算子出棧 字串後移一位 
				case '>': x = num[numtop-1], numtop--;
				          y = num[numtop-1], numtop--;
						  z = work(y, op[optop-1], x), optop--;//用過的運算子出棧 
						  num[numtop++] = z;       break;//新浮點數進棧 
			} 
		}
		outputcolor();
		printf("%.6lf\n", num[numtop-1]); 
	}
	return 0;
}


在VC實現的,功能效果和上面的一樣:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int in = 0, out = 0;
void output()
{
	system("color 1f");
	printf("**********************************簡單計算器**********************************\n\n");
	printf("********************功能:實現小數和整數加減乘除四則混合運算*******************\n\n");
	printf(">>>>>>>>>>>輸入: (加號 +) (減號 -) (乘號 *) (除號 /) (數字正常輸入)>>>>>>>>>>>\n\n"); 
	printf("!!!!!!!!!!!!!!!提醒:可以有多個括號, 但模仿計算器不能輸入等號(=)!!!!!!!!!!!!!!!\n\n"); 
	printf("<<<<<<<<<<<<<<<<<<<<<<<<輸出:請按回車(預設保留6位小數)<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
	printf("\n");
	printf("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&模擬鍵盤&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n");
	printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^[  7   8   9   /   (  ]^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
	printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  4   5   6   *   )  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
	printf("____________________________[  1   2   3   -   =  ]___________________________\n");
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~[    0     .   +      ]~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
	printf("\n");
	printf("!!!!!!!!!!!!!輸入像1+2/5*6-7型別的表示式,否則可能無法得到正確結果!!!!!!!!!!!!!\n"); 
	printf("!!!!!!!!!!!!!如果程式出錯誤,應該是輸入出了問題,記著錯誤關閉再開啟!!!!!!!!!!!!!\n");
	printf("@@@@@@@@@@@使用者輸入模擬鍵盤上的數字及運算子,該計算器可以處理空格哦@@@@@@@@@@\n");
	printf("\n");
}
void inputcolor()
{
	if(in > 16)
	in -= 16;
	switch(in)
	{
		case 0: system("color 0f"); break;
		case 1: system("color 1e"); break;
		case 2: system("color 2d"); break;
		case 3: system("color 3c"); break;
		case 4: system("color 4b"); break;
		case 5: system("color 5a"); break;
		case 6: system("color 69"); break;
		case 7: system("color 78"); break;
		case 8: system("color f0"); break;
		case 9: system("color e1"); break;
		case 10:system("color d2"); break;
		case 11:system("color c3"); break;
		case 12:system("color b4"); break;
		case 13:system("color a5"); break;
		case 14:system("color 96"); break;
		case 15:system("color 87"); break;
	}
	in++;
}
void outputcolor()
{
	if(out > 16)
	out -= 16;
	switch(out)
	{
		case 15:system("color 0f"); break;
		case 14:system("color 96"); break;
		case 13:system("color d8"); break;
		case 12:system("color 3c"); break;
		case 11:system("color 4b"); break;
		case 10:system("color 5a"); break;
		case 9: system("color 69"); break;
		case 8: system("color 72"); break;
		case 7: system("color f0"); break;
		case 6: system("color e1"); break;
		case 5: system("color 2e"); break;
		case 4: system("color ca"); break;
		case 3: system("color b4"); break;
		case 2: system("color a5"); break;
		case 1: system("color 97"); break;
		case 0: system("color 8f"); break;
	}
	out++;
}
char compare(char a, char b)//比較運算子a,b優先順序 
{
	if(a == '+' || a == '-')
	{
		if(b == '*' || b == '/' || b == '(')
		return '<';
		else
		return '>';//連續的加減 優先前面的算 
	}
	if(a == '*' || a == '/')
	{
		if(b == '(')
		return '<';
		else
		return '>';//連續的乘除 優先前面的算 
	}
	if(a == '(')
	{
		if(b == ')')
		return '=';
		else
		return '<';//優先括號裡面的運算子 
	}
	if(a == '=')
	{
		if(b == '=')
		return '=';
		else
		return '<';//因為儲存運算子的棧頂為 = 所以後來碰到的運算子除了=外 優先順序均比它高   
	}
}
double work(double a, char op, double b)//對浮點數 a b 進行四則運算 
{
	switch(op)
	{
		case '+': return a + b;
		case '-': return a - b;
		case '*': return a * b;
		case '/': return a / b;
	}
}
int judge(char a)//判斷字元 是否是數字或者小數點 
{
	return (a >= '0' && a <= '9' || a == '.') ? 1 : 0;
}
int main()
{ 
	int i, j;
	int len;
	char str[1010];//輸入的運算式 
	char s[1010];//把浮點數當成字元儲存起來  
	int t;//記錄儲存浮點數的 字元陣列的位數 
	int exist;//標記是否出現數字 
    double x, y, z;//求每一步的值 用到的變數 
    int numtop;//浮點數陣列頂部 用陣列模擬棧 
	int optop;//運算子陣列頂部 模擬棧 
	double num[1010];//儲存浮點數 
	char op[1010];//儲存運算子 
	/*列印計算器介面*/
	output();
	while(gets(str))//輸入計算內容 
	{
		inputcolor();
		numtop = optop = 0;//初始化 
		len = strlen(str);
		str[++len] = '=';//在末尾新增一個 =  
		op[optop++] = '=';//逆波蘭式  = 先進棧 
		t = 0;
		exist = 0;
		for(i = 0; i < len;)
		{
			if(str[i] == ' ')//碰到空格 
			{
				i++;
				continue;
			}
			if(judge(str[i]))
			{
				s[t++] = str[i++];//字串後移一位 
				exist = 1;//出現數字 
				continue;
			}
			if(exist)//出現過數字 且當前字元是運算子 
			{
				s[t] = '\0';
				num[numtop++] = atof(s); //模擬進棧 
				t = exist = 0;//初始化 
			} 
			/*下面比較上一運算子 和 當前運算子優先順序 */
			/* 若 < 進棧,若 > 計算,若 = 上一運算子出棧*/
			switch(compare(op[optop-1], str[i]))
			{
				case '<': op[optop++] = str[i++]; break;//字串後移一位 
				case '=': optop--, i++;     break;//上一運算子出棧 字串後移一位 
				case '>': x = num[numtop-1], numtop--;
				          y = num[numtop-1], numtop--;
						  z = work(y, op[optop-1], x), optop--;//用過的運算子出棧 
						  num[numtop++] = z;       break;//新浮點數進棧 
			} 
		}
		outputcolor();
		printf("%.6lf\n", num[numtop-1]); 
	}
	return 0;
}