![]() |
#2
lhjok2010-09-19 13:23
回复 楼主 lhjok
|

#include <iostream> //标准输入输出流头文件。
#include <cstdlib> //标准“exit()”所包含的头文件。
#include <cmath> //标准数学库函数。
#include <iomanip> //标准流格式头文件。
#include <windows.h> //Windows头文件。
#include "stack.h" //自定义(栈)类模板头文件。
using namespace std; //命名空间。
stack<long double> A; //数据栈(存有效数字)。
stack<char> B; //字符栈(存运算符)。
void Run(); //综合运算函数。
int Priority( char ); //运算符优先级。
long double Computing( char ); //简单运算函数。
void SetColor( unsigned short FColor=4, unsigned short BColor=0 ) //字体颜色设置。
{ HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute( hCon, FColor | BColor ); }
void help() //帮助与程序说明。
{ cout<<"&-Calculator 1.1---------------------------------------->\n"
<<"数学表达式求值计算器: 程序编写者(C++ Language): 刘华军\n"
<<"说 明:(^)是乘方运算符,键入(S)清屏,键入(Q)退出。\n"
<<"本程序支持负数运算以及错误警告。\n"
<<"请在下面输入数学表达式: 例 6+(6+8/2*(8-5)^8)*2\n"
<<"&---------------------------------------------->"; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
system("cls"); //清屏函数。(调用DOS命令)
help(); //帮助与程序说明。
for(;;) //无限循环。
Run(); //调用综合运算函数。
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Run()
{
int c,d;
long double P,Z=0;
const long double Max=999999999999.999; //long double 的最长数字是15位包括小数点后面的精度位数,小数点不包括在内。
char ch,ab=0; //"ab"变量用来标记上一次进栈的是数字还是运算符。
cout<<endl;
SetColor(7,0);
cin.clear(); cin.sync(); //清空输入流。
A.clear(); B.clear(); //清空A-B栈。
while ( cin ) //检查输入流是否可用。
{
cin.get( ch ); //输入表达式。(能读取空格符、换行符、回车符。)
switch ( ch )
{
case '(': if ( ab !='A' ) //左括号前不能是数字。
{ B.push( ch ); break; }
SetColor(); cerr<<"Error:01"; return;
case ')': if ( B.find('(') && ab =='A' ) //运算符栈中必须有左括号与右括号前必须是数字。(右括号不进栈)
{
while ( B.top() != '(' )
{
try //异常定义。(可能抛出异常的语句)
{ A.push( Computing(B.top()) ); } //如果出现异常,函数内部会抛出异常。
catch ( long double ) //捕获并处理异常。
{ SetColor(); cerr<<"Error:04"; return; }
B.pop(); //运算符出栈。
}
B.pop(); break; //左括号出栈。
}
SetColor(); cerr<<"Error:01"; return;
case '+':
case '-':
case '*':
case '/':
case '^': if ( ch =='-' && ab !='A' ) //当上一次进栈的数据是运算符,当前'-'为负数标号。
{
cin.putback( ch ); //此函数将当前字符送回到缓冲区中。
if ( cin>>P ) //检查读取的数字是否有效。
{ A.push( P ); ab='A'; break; } //读取的数字进栈,"ab"变量记录下来。
SetColor(); cerr<<"Error:01"; return;
}
else if ( ab =='A' ) //运算符前面必须是数字。
{
while ( !B.empty() && B.top() != '(' ) //运算符栈为空或栈顶元素为左括号时停止循环。
{
c= Priority( B.top() );
d= Priority( ch );
if ( c >= d )
{
try //异常定义。(可能抛出异常的语句)
{ A.push( Computing(B.top()) ); } //如果出现异常,函数内部会抛出异常。
catch ( long double ) //捕获并处理异常。
{ SetColor(); cerr<<"Error:04"; return; }
B.pop();
}
else
break; //跳出循环。
}
B.push( ch ); ab='B'; break; //运算符进栈,"ab"变量记录下来。
}
SetColor(); cerr<<"Error:01"; return;
case '\n':
case '\r':
case '=': if ( B.empty() && A.empty() || B.find('(') || ab !='A' ) //A-B栈不能为空,等号前不能出现左括号和不能没有数字。
{ SetColor(); cerr<<"Error:01"; return; }
else if ( B.empty() && !A.empty() ) //等号前只有一个数字。
Z= A.top();
while ( !B.empty() )
{
try //异常定义。(可能抛出异常的语句)
{ Z= Computing( B.top() ); } //如果出现异常,函数内部会抛出异常。
catch ( long double ) //捕获并处理异常。
{ SetColor(); cerr<<"Error:04"; return; }
A.push( Z ); B.pop();
}
A.pop(); //清空最后一个数据栈。
if ( Max < Z ) //检查结果是否超出最大数据范围。
{ SetColor(); cerr<<"Error:03"; return; }
SetColor(2,0);
cout<<fixed<<setprecision(3)<<Z; return;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.': cin.putback( ch ); //此函数将当前字符送回到缓冲区中。
if ( cin>>P && ab !='A' ) //检查读取的数字是否有效,上一次进栈的数据不可以还是数字。
{ A.push( P ); ab='A'; break; } //读取的数字进栈,"ab"变量记录下来。
SetColor(); cerr<<"Error:01"; return;
case 'Q':
case 'q': exit(1); //退出程序。
case 's':
case 'S': system("cls"); help(); return; //清屏后打印帮助与程序说明。
default : SetColor(); cerr<<"Error:02"; return;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int Priority( char x )
{
switch ( x )
{
case '+':
case '-': return 0; //将运算符优先级标记为数字。
case '*':
case '/': return 1; //将运算符优先级标记为数字。
case '^': return 2; //将运算符优先级标记为数字。
default : exit(1);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
long double Computing( char x )
{
int n;
long double a,b;
switch ( x )
{
case '+': b= A.top(); A.pop(); //(数字栈)栈顶元素赋给b,然后出栈。
a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。
return a+b;
case '-': b= A.top(); A.pop(); //(数字栈)栈顶元素赋给b,然后出栈。
a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。
return a-b;
case '*': b= A.top(); A.pop(); //(数字栈)栈顶元素赋给b,然后出栈。
a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。
return a*b;
case '/': b= A.top(); A.pop(); //(数字栈)栈顶元素赋给b,然后出栈。
a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。
if ( b != 0 )
return a/b;
throw b; //抛出异常。
case '^': n= static_cast<int>( A.top() ); A.pop(); //(数字栈)栈顶元素(强制转换成整型)赋给n,然后出栈。
a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。
return pow(a,n); //数学库函数。(乘方运算函数)
default : exit(1);
}
}
[local]1[/local] #include <cstdlib> //标准“exit()”所包含的头文件。
#include <cmath> //标准数学库函数。
#include <iomanip> //标准流格式头文件。
#include <windows.h> //Windows头文件。
#include "stack.h" //自定义(栈)类模板头文件。
using namespace std; //命名空间。
stack<long double> A; //数据栈(存有效数字)。
stack<char> B; //字符栈(存运算符)。
void Run(); //综合运算函数。
int Priority( char ); //运算符优先级。
long double Computing( char ); //简单运算函数。
void SetColor( unsigned short FColor=4, unsigned short BColor=0 ) //字体颜色设置。
{ HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute( hCon, FColor | BColor ); }
void help() //帮助与程序说明。
{ cout<<"&-Calculator 1.1---------------------------------------->\n"
<<"数学表达式求值计算器: 程序编写者(C++ Language): 刘华军\n"
<<"说 明:(^)是乘方运算符,键入(S)清屏,键入(Q)退出。\n"
<<"本程序支持负数运算以及错误警告。\n"
<<"请在下面输入数学表达式: 例 6+(6+8/2*(8-5)^8)*2\n"
<<"&---------------------------------------------->"; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
system("cls"); //清屏函数。(调用DOS命令)
help(); //帮助与程序说明。
for(;;) //无限循环。
Run(); //调用综合运算函数。
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Run()
{
int c,d;
long double P,Z=0;
const long double Max=999999999999.999; //long double 的最长数字是15位包括小数点后面的精度位数,小数点不包括在内。
char ch,ab=0; //"ab"变量用来标记上一次进栈的是数字还是运算符。
cout<<endl;
SetColor(7,0);
cin.clear(); cin.sync(); //清空输入流。
A.clear(); B.clear(); //清空A-B栈。
while ( cin ) //检查输入流是否可用。
{
cin.get( ch ); //输入表达式。(能读取空格符、换行符、回车符。)
switch ( ch )
{
case '(': if ( ab !='A' ) //左括号前不能是数字。
{ B.push( ch ); break; }
SetColor(); cerr<<"Error:01"; return;
case ')': if ( B.find('(') && ab =='A' ) //运算符栈中必须有左括号与右括号前必须是数字。(右括号不进栈)
{
while ( B.top() != '(' )
{
try //异常定义。(可能抛出异常的语句)
{ A.push( Computing(B.top()) ); } //如果出现异常,函数内部会抛出异常。
catch ( long double ) //捕获并处理异常。
{ SetColor(); cerr<<"Error:04"; return; }
B.pop(); //运算符出栈。
}
B.pop(); break; //左括号出栈。
}
SetColor(); cerr<<"Error:01"; return;
case '+':
case '-':
case '*':
case '/':
case '^': if ( ch =='-' && ab !='A' ) //当上一次进栈的数据是运算符,当前'-'为负数标号。
{
cin.putback( ch ); //此函数将当前字符送回到缓冲区中。
if ( cin>>P ) //检查读取的数字是否有效。
{ A.push( P ); ab='A'; break; } //读取的数字进栈,"ab"变量记录下来。
SetColor(); cerr<<"Error:01"; return;
}
else if ( ab =='A' ) //运算符前面必须是数字。
{
while ( !B.empty() && B.top() != '(' ) //运算符栈为空或栈顶元素为左括号时停止循环。
{
c= Priority( B.top() );
d= Priority( ch );
if ( c >= d )
{
try //异常定义。(可能抛出异常的语句)
{ A.push( Computing(B.top()) ); } //如果出现异常,函数内部会抛出异常。
catch ( long double ) //捕获并处理异常。
{ SetColor(); cerr<<"Error:04"; return; }
B.pop();
}
else
break; //跳出循环。
}
B.push( ch ); ab='B'; break; //运算符进栈,"ab"变量记录下来。
}
SetColor(); cerr<<"Error:01"; return;
case '\n':
case '\r':
case '=': if ( B.empty() && A.empty() || B.find('(') || ab !='A' ) //A-B栈不能为空,等号前不能出现左括号和不能没有数字。
{ SetColor(); cerr<<"Error:01"; return; }
else if ( B.empty() && !A.empty() ) //等号前只有一个数字。
Z= A.top();
while ( !B.empty() )
{
try //异常定义。(可能抛出异常的语句)
{ Z= Computing( B.top() ); } //如果出现异常,函数内部会抛出异常。
catch ( long double ) //捕获并处理异常。
{ SetColor(); cerr<<"Error:04"; return; }
A.push( Z ); B.pop();
}
A.pop(); //清空最后一个数据栈。
if ( Max < Z ) //检查结果是否超出最大数据范围。
{ SetColor(); cerr<<"Error:03"; return; }
SetColor(2,0);
cout<<fixed<<setprecision(3)<<Z; return;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.': cin.putback( ch ); //此函数将当前字符送回到缓冲区中。
if ( cin>>P && ab !='A' ) //检查读取的数字是否有效,上一次进栈的数据不可以还是数字。
{ A.push( P ); ab='A'; break; } //读取的数字进栈,"ab"变量记录下来。
SetColor(); cerr<<"Error:01"; return;
case 'Q':
case 'q': exit(1); //退出程序。
case 's':
case 'S': system("cls"); help(); return; //清屏后打印帮助与程序说明。
default : SetColor(); cerr<<"Error:02"; return;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int Priority( char x )
{
switch ( x )
{
case '+':
case '-': return 0; //将运算符优先级标记为数字。
case '*':
case '/': return 1; //将运算符优先级标记为数字。
case '^': return 2; //将运算符优先级标记为数字。
default : exit(1);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
long double Computing( char x )
{
int n;
long double a,b;
switch ( x )
{
case '+': b= A.top(); A.pop(); //(数字栈)栈顶元素赋给b,然后出栈。
a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。
return a+b;
case '-': b= A.top(); A.pop(); //(数字栈)栈顶元素赋给b,然后出栈。
a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。
return a-b;
case '*': b= A.top(); A.pop(); //(数字栈)栈顶元素赋给b,然后出栈。
a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。
return a*b;
case '/': b= A.top(); A.pop(); //(数字栈)栈顶元素赋给b,然后出栈。
a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。
if ( b != 0 )
return a/b;
throw b; //抛出异常。
case '^': n= static_cast<int>( A.top() ); A.pop(); //(数字栈)栈顶元素(强制转换成整型)赋给n,然后出栈。
a= A.top(); A.pop(); //(数字栈)栈顶元素赋给a,然后出栈。
return pow(a,n); //数学库函数。(乘方运算函数)
default : exit(1);
}
}