?? mathstring.cpp
字號:
// MathString.cpp: implementation of the CMathString class.
//
////////////////////////////////////////////////////////////////////
// MathString.cpp: implementation of the CMathString class.
//
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
// 求算術表達式值的類
//
// 湖南城市學院 信息與計算科學系
// 黃江峰
// jiangfenghuang@msn.com
// jiangfenghuang@163.net
// 2003.4.5
//
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
// 功能:
// 求在字符串中的算術表達式的值,
//
// 特點:
// 1.支持字符串中含有各種常用函數,如"7.5+sin(6*ln(8))/exp(5)"
// 2.具有很好的糾錯能力,能檢查出表達式中括號是否配對、庫函數是
// 否正確
// 3.運算過程中能檢查出各種異常,如除數為0、開方函數sqrt(x)中x<0
// 反余弦函數acos(x)中的x<-1或x>1等
// 4.為支持積分、求方程,算術表達式中可含有x,計算時將用類中的成
// 員變量xx代替
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
// 使用方法:
// 1. 定義一個CMathString 的對象,用要求的算術表達式將其初始化
// 如: char *s1="7.5+sin(6)/exp(5)";
// char *s2="4*pow(x,2)+2*x+4";
// CMathString mathstr1(s1);
// CMathString mathstr2(s2);
// 或調用Initial(char *s)、Initial(char *s,double x)將其初始化
// 2.調用checkString方法檢查表達式是否合法
// 3.如果是求積分或j解方程,調用setX(double x)設置表達式中x的值
// 4.調用stringToBolan()將算術表達式轉換為波蘭表達式
// 5.調用compvalue()對波蘭表達式進行計算,若返回值為0,則調
// 用getvalue()取得計算結果,否則可根據返回值判斷出錯地方
//
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
//
// 支持的函數的編號及功能
//
// 編號 函數 功能 調用的math.h庫函數 備注
//
// 1 abs(x) 取絕對值|x| fabs(x)
// 2 acos(x) 反余弦函數 acos(x) -1<=x<=1
// 3 asin(x) 反正弦函數 asin(x) -1<=x<=1
// 4 atan(x) 反正切函數 atan(x)
// 5 acot(x) 反余切函數 PI/2-atan(x)
// 6 cos(x) 余弦函數 cos(x)
// 7 cosh(x) 雙曲余弦函數 cosh(x)
// 8 cot(x) 余切函數 1/tan(x) tan(x)!=0
// 9 exp(x) e的x次方 exp(x)
// 10 floor(x) ⊥x⊥ floor(x) 求不大于x的最大整數
// 11 mod(x,y) x%y mod(x,y) y!=0
// 12 ln(x) 取自然對數 log(x) x>0
// 13 log(x) 取10的對數 log10(x) x>0
// 14 pow(x,y) x的y次方 pow(x,y)
// 15 sin(x) 正弦函數 sin(x)
// 16 sinh(x) 雙曲正弦函數 sinh(x)
// 17 sqrt(x) 對x開方 sqrt(x) x>=0
// 18 tan(x) 正切函數 tan(x)
// 19 tanh(x) 雙曲正切函數 tanh(x)
//
/////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MathString.h"
#include "math.h"
#define PI 3.1415926
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMathString::CMathString()
{
}
CMathString::~CMathString()
{
}
CMathString::CMathString(char *str) //構造函數,將算術表達式str賦給String
{
strcpy(string,str);
}
CMathString::CMathString(char *str,double x)
{ //表達式中帶未知數的構造函數
//算術表達式*s賦給string,未知數x賦給xx
//用于積分表達式
strcpy(string,str);
xx=x;
}
void CMathString::setX(double x) //設置成員變量xx的值
{
xx=x;
}
int CMathString::seekStr(char *str,int &i, char *s)
{ //檢查字符竄str的第i個位置開始的后面字符是否與字符竄s相匹配
//是的話將i=i+len(s),并返回1,否則返回0
int j=0;
for(j=0;j<strlen(s);j++)
if(str[i+j]!=s[j])
break;
if(j==strlen(s))
{
i=i+strlen(s);
return 1;
}
else return 0;
}
void CMathString::Initial(char *s) //初始化函數,將算術表達式s賦給String
{
strcpy(string,s);
}
void CMathString::Initial(char *str, double x)
{
//表達式中帶未知數的初始化函數
//算術表達式*str賦給string,未知數x賦給xx
//用于積分表達式
strcpy(string,str);
xx=x;
}
int CMathString::checkString()
{ //檢查輸入的表達式是否正確,包括括號是否配對、庫函數是否正確,
//不包括小數點是否正確,若正確,將表達式中的大、中括號該成小括號
//并在表達式尾加‘#’標識
//若正確,返回值為1;否則返回0;
//因積分表達式中有x,所以表達式中的x作為字符處理
char st[MAX/2]; //存放括號的棧
int top=0, //棧頂
i;
for(i=0;string[i]!='\0';i++)
{
//如果是左括號,則入棧
if(string[i]=='(' || string[i]=='[' || string[i]=='{')
{ //如果是左括號,則入棧
top++;
st[top]=string[i];
continue;
}
//小括號
if(string[i]==')') //小括號
{
if(st[top]=='(') //配對
{
top--; //出棧
continue;
}
else return 0; //不配對,返回0
}
//中括號
if(string[i]==']')
{
if(st[top]=='[') //配對
{
top--; //出棧
continue;
}
else return 0; //不配對,返回0
}
//大括號
if(string[i]=='}')
{
if(st[top]=='{') //配對
{
top--; //出棧
continue;
}
else return 0; //不配對,返回0
}
//運算符
if(string[i]=='+' || string[i]=='-' || string[i]=='*' || string[i]=='/')
{ //如果有連續運算符則錯誤
if(string[i+1]=='+' || string[i+1]=='-' || string[i+1]=='*' ||string[i+1]=='/')
return 0; //錯誤,返回0
else
continue; //無連續運算符情況
}
//數字、小數點、逗號
if(('0'<=string[i] && string[i]<='9') || string[i]=='.'
||string[i]==',')
continue;
//未知數x
if(string[i]=='x')
continue;
//是以a開頭的函數
if(string[i]=='a')
{
if(seekStr(string,i,"abs")||seekStr(string,i,"acos")||
seekStr(string,i,"asin")||seekStr(string,i,"atan")||
seekStr(string,i,"acot"))//是以a開頭的庫函數
{
if(string[i]=='('||string[i]=='['||string[i]=='{')
{ //如果函數后是括號
st[++top]=string[i]; // 括號入棧
continue;
}
else //如果函數后不是括號,返回0
return 0;
}
else //不是以a開頭的庫函數,返回0
return 0;
}
//是以c開頭的函數
if(string[i]=='c')
{
if(seekStr(string,i,"cos")||seekStr(string,i,"cosh")||
seekStr(string,i,"cot"))
{
if(string[i]=='('||string[i]=='['||string[i]=='{')
{ //如果函數后是括號
st[++top]=string[i]; // 括號入棧
continue;
}
else //如果函數后不是括號,返回0
return 0;
}
else //不是以c開頭的庫函數,返回0
return 0;
}
//是以e開頭的函數
if(string[i]=='e')
{
if(seekStr(string,i,"exp"))
{
if(string[i]=='('||string[i]=='['||string[i]=='{')
{ //如果函數后是括號
st[++top]=string[i]; // 括號入棧
continue;
}
else //如果函數后不是括號,返回0
return 0;
}
else //不是以e開頭的庫函數,返回0
return 0;
}
//是以f開頭的函數
if(string[i]=='f')
{
if(seekStr(string,i,"floor"))
{
if(string[i]=='('||string[i]=='['||string[i]=='{')
{ //如果函數后是括號
st[++top]=string[i]; // 括號入棧
continue;
}
else //如果函數后不是括號,返回0
return 0;
}
else //不是以f開頭的庫函數,返回0
return 0;
}
//是以m開頭的函數
if(string[i]=='m')
{
if(seekStr(string,i,"mod"))
{
if(string[i]=='('||string[i]=='['||string[i]=='{')
{ //如果函數后是括號
st[++top]=string[i]; // 括號入棧
continue;
}
else //如果函數后不是括號,返回0
return 0;
}
else //不是以m開頭的庫函數,返回0
return 0;
}
//是以l開頭的函數
if(string[i]=='l')
{
if(seekStr(string,i,"ln")||seekStr(string,i,"log"))
{
if(string[i]=='('||string[i]=='['||string[i]=='{')
{ //如果函數后是括號
st[++top]=string[i]; // 括號入棧
continue;
}
else //如果函數后不是括號,返回0
return 0;
}
else //不是以l開頭的庫函數,返回0
return 0;
}
//是以p開頭的函數
if(string[i]=='p')
{
if(seekStr(string,i,"pow"))
{
if(string[i]=='('||string[i]=='['||string[i]=='{')
{ //如果函數后是括號
st[++top]=string[i]; // 括號入棧
continue;
}
else //如果函數后不是括號,返回0
return 0;
}
else //不是以p開頭的庫函數,返回0
return 0;
}
//是以s開頭的函數
if(string[i]=='s')
{
if(seekStr(string,i,"sin")||seekStr(string,i,"sinh")||
seekStr(string,i,"sqrt"))
{
if(string[i]=='('||string[i]=='['||string[i]=='{')
{ //如果函數后是括號
st[++top]=string[i]; // 括號入棧
continue;
}
else //如果函數后不是括號,返回0
return 0;
}
else //不是以s開頭的庫函數,返回0
return 0;
}
//是以t開頭的函數
if(string[i]=='t')
{
if(seekStr(string,i,"tan")||seekStr(string,i,"tanh"))
{
if(string[i]=='('||string[i]=='['||string[i]=='{')
{ //如果函數后是括號
st[++top]=string[i]; // 括號入棧
continue;
}
else //如果函數后不是括號,返回0
return 0;
}
else //不是以t開頭的庫函數,返回0
return 0;
}
else // 如果string[i]是其他字符,則返回0
return 0;
}//for(i=0;string[i]!='\0';i++)
if(top!=0) //括號不匹配,返回0
return 0;
//表達式正確
//在表達式尾加‘#’標識
string[i]='#';
string[++i]='\0';
//將表達式中的大、中括號該成小括號
for(i=0;string[i]!='\0';i++)
{
if((string[i]=='[')||(string[i]=='{'))
string[i]='(';
else if((string[i]==']')||(string[i]=='}'))
string[i]=')';
}
return 1;
}
//將算術表達式string轉化成波蘭表達式,
//波蘭表達式放在bolan[]中
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -