亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來(lái)到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? calculator.cpp

?? 這是一個(gè)對(duì)數(shù)學(xué)表達(dá)式求值的C++ class
?? CPP
字號(hào):
/*
作者介紹:陳碩,男,1982年4月生,現(xiàn)就讀于北京師范大學(xué)電子系2000級(jí)。
通信方法:100875,北京師范大學(xué) 電子系1300信箱 陳碩 
E - Mail : chenshuo@chenshuo.com ,個(gè)人主頁(yè):http://www.chenshuo.com 
代碼的說(shuō)明在readme.txt中
Version 0.99 beta
*/

#include "calculator.h"
#include <stdio.h>

void Calculator::Clear(void)
{ // 初始化計(jì)算器
	PO.Clear();
	Result = 0;
	ErrorID = ERR_NO_ERROR;
	VarCount = 0;
	Expression[0] = '\0';

	for(int i = 0; i < MaxNumber_of_Variable; i++) {
		VarName[i][0] = '\0';
		Vars[i] = 0.0;
	}
}

const char* Calculator::GetErrorMessage(int errid) const
{
	static const char *errmsg[] = {"no errors",
		"expression too long",
		"missing operand",
		"missing operator",
		"missing left parenthesis",
		"missing right paraenthesis",
		"devide by zero",
		"unknown operator",
		"invalid operator",
		"unknown error",
		"too many variables",
		"variable's name too long",
		"UNKNOWN ERROR ID!!!"};

	if(errid >= 0 && errid < 12)
		return errmsg[errid];
	else
		return errmsg[12];
}

void Calculator::Assign(double *pExtVars)
{ // 將pExtVars所指向數(shù)組的值賦給Vars[]
	double *pd = Vars; 
	while(pd < Vars + VarCount)
		*pd++ = *pExtVars++;
}

const char* Calculator::GetVariableName(int i)
{
	if (i>=0 && i<VarCount) {
		return VarName[i];
	} else {
		return 0;
	}
}

void Calculator::Trim(char *buf)
{ //初始化,去除str[]中的非法字符
	
	//char buf[MaxLength_of_Expression];
	char charset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-*/()^."; //合法的字符
	
	strupr(buf);
	
	int i = 0;
	int j = 0;
	char ch;
	
	while(ch = buf[i++]) {
		if(strchr(charset, ch))
			Expression[j++] = ch;
	}

	Expression[j] = '\0';
}

bool Calculator::IsOperandChar(int i) const
{ //判斷是否為操作數(shù)字符
	char ch, ch0, ch1;
	int l = strlen(Expression);
	ch = Expression[i];
	ch0 = Expression[i==0 ? 0:i-1];
	ch1 = Expression[i==l-1 ? i:i+1];

	if(isdigit(ch) || ch == '.')
		return true;

	if(ch == '-'||ch == '+') //判斷這個(gè)"+"或"-"是不是數(shù)字的一部分
		if(strchr("+-*/^(", ch0) != 0 && (isdigit(ch1) || ch1 == '.'))
			return true;

	return false;
}

bool Calculator::IsOperatorChar(int i) const
{ //判斷是否為操作符字符
	char ch = Expression[i];
	
	if(strchr("+-*/^", ch)!=NULL)
		return true;
	if(isalpha(ch))
		return true;
	return false;
}

void Calculator::GetOperand(int &i, char *buf) const
{ //讀取完整的操作數(shù)
	int t = 0;
	
	while(IsOperandChar(i)) 
		buf[t++] = Expression[i++];
	buf[t] = '\0';
}

bool Calculator::GetOperator(int &i, char *buf) const
{ //讀取完整的操作符 如SIN COS及變量名等
	int t = 0;
	char ch;
	ch = Expression[i];

	if(strchr("+-*/^", ch) != 0) { //取單字符的雙目操作符
		buf[t++]=ch;
		i++;
    	buf[t] = '\0';
	    return true;
	} 
	
	//取連續(xù)的由字母和數(shù)字組成的字符串
	while(isalnum(Expression[i])) {
		buf[t++] = Expression[i++];
		if(t >= MaxLength_of_VariableName) {
			Error(ERR_VARIABLE_NAME_TOO_LONG, __LINE__);
			return false;
		}
	}
	
	buf[t] = '\0';
	return true;
}

bool Calculator::GetUnary(element &EL, char ch, int rank) const
{ // 處理單字符非字母操作符
	if(rank == 1) { // 需要雙目操作符
    	EL.isp = 1; EL.icp = 1;
	    switch (ch) {
		    case '+': EL.type = OPTR_ADD; break;
		    case '-': EL.type = OPTR_SUBTRACT; break;
		    case '*': EL.type = OPTR_MULTIPLY; EL.isp = EL.icp = 2; break;
		    case '/': EL.type = OPTR_DIVIDE; EL.isp = EL.icp = 2; break;
		    case '^': EL.type = OPTR_POWER; EL.isp = 3; EL.icp = 4; break;
		    default : Error(ERR_UNKNOWN_OPERATOR, __LINE__); return false;
	    }
	    return true;
	}
	
	if(rank == 0) { // 需要單目操作符
	    EL.isp = 4; EL.icp = 5;
	    switch (ch) {
    		case '+': EL.type = OPTR_POSITIVE; break;
		    case '-': EL.type = OPTR_MINUS; break;
		    default : Error(ERR_UNKNOWN_OPERATOR, __LINE__); return false;
	    }
	    return true;
	}
	
	return false; //Error!
}

bool Calculator::GetVariable(element &EL, const char *buf, int &rank)
{
    int j;
    
    for(j = 0; j < VarCount; j++) {//是否為已知變量
		if(strcmp(VarName[j], buf) == 0) { //若是變量,則EL為操作數(shù)
			EL.type = 1 + j;
			EL.isp = 0; EL.icp = 0;
			rank++; // 操作數(shù)的等級(jí)為1,累計(jì)等級(jí)rank自加1
			if (rank > 1) {
				Error(ERR_MISS_OPERATOR, __LINE__);
				return false;
			}
		    return true;
    	}
	}
	
	if (VarCount < MaxNumber_of_Variable) {
		strcpy(VarName[VarCount], buf); //添加新變量
		EL.type = 1 + j;
		EL.isp = 0; EL.icp = 0;
		VarCount++;
		rank++;
		if (rank > 1) {
			Error(ERR_MISS_OPERATOR, __LINE__);
			return false;
		}
		return true;
	} else {
		Error(ERR_TOO_MANY_VARIABLES, __LINE__);
		return false;
	}
}

bool Calculator::GetElement(element &EL, const char *buf, int &rank)
{ // 得到buf所指的字符串對(duì)應(yīng)的表達(dá)式元素的屬性
	static char *fname[]={"SIN", "COS", "TAN", "SQR", "LOG10", 
			"LOG", "COT", "ABS", "INT", "ARCSIN", "ARCCOS", "ARCTAN",
			"SINH", "COSH", "TANH", "EXP", "SQRT", 0}; //支持的數(shù)學(xué)函數(shù)的名稱
	int l, j;
	char ch;

	l = strlen(buf);
	ch = buf[0];
	if(l == 1 && !isalpha(ch))  //非字母的單字節(jié)操作符
	    return GetUnary(EL, ch, rank);

     //處理字母字符串
	for(j = 0; fname[j] != 0; j++) {//是否為已有的數(shù)學(xué)函數(shù)
		if(strcmp(fname[j], buf) == 0) {
			EL.type = 51 + j;
			EL.isp = 4; EL.icp = 5;
			return true;
		}
	}
		
	if(GetVariable(EL, buf, rank)) {
		return true;
    }

	return false;
}

bool Calculator::Construe_Numeric(element &EL, int &i, int &rank) const
{
	char buf[MaxLength_of_Expression];
	GetOperand(i, buf);
	EL.type = 0;
	EL.value = atof (buf);
	
	rank++;
	if (rank > 1) {
		Error(ERR_MISS_OPERATOR, __LINE__);
		return false;
	}
	return true;
}

bool Calculator::Construe_Operator(element &EL, int &i, int &rank)
{
	char buf[MaxLength_of_VariableName];

	if(!GetOperator(i, buf)) // 取得整個(gè)操作符的名稱
		return false; //發(fā)生錯(cuò)誤

	if(!GetElement(EL, buf, rank)) // 取得相應(yīng)的屬性
		return false ; //發(fā)生錯(cuò)誤

	if(EL.type < 40 && EL.type > 20) // 若是雙目操作符,rank自減1
		rank--;
		
	if (rank < 0) {
		Error(ERR_MISS_OPERAND, __LINE__);
		return false;
	}
	return true;
}

void Calculator::Construe(Queue<element> &IN)
{ // 把輸入的表達(dá)式整理為中綴表達(dá)式
	element EL;

	char ch;
	int rank = 0; //表達(dá)式等級(jí)
	int i = 0;
	
	EL.icp = 0; EL.isp = 0; EL.value = 0;

	IN.Clear();

	while((ch = Expression[i]) != '\0') { //掃描表達(dá)式
		if(IsOperandChar(i)) { //處理數(shù)字
		    if(!Construe_Numeric(EL, i, rank))
		        return;
            IN.Insert(EL);
			continue;
			}
		
		if(ch == '(') {
			EL.type = 20; EL.icp = 6; EL.isp = -1;
			i++;
			IN.Insert(EL);
			continue;
			}
		
		if(ch == ')') {
			EL.type = 40; EL.icp = 0; EL.isp = 0;
			i++;
			IN.Insert(EL);
			continue;
			}
		
		if(IsOperatorChar(i)) { //處理操作符
            if (!Construe_Operator(EL, i, rank))
                return;
			IN.Insert(EL);
            continue;
		}
	} // end of while()

	if(rank != 1) 
		Error(ERR_MISS_OPERAND, __LINE__);
	return;
}

void Calculator::Conversion(Queue<element> &IN)
{ //轉(zhuǎn)換中綴表達(dá)式為后綴式

	element EL;
	int type;
	Stack<element> STE; // Stack to elements

	PO.Clear();
	
	while(!IN.IsEmpty()) { //依次取出中綴表達(dá)式的元素EL
		EL = IN.Delete();
		type = EL.type;
		
		if(type < 20) { // 若是操作數(shù)
			PO.Insert(EL);
			continue;
		}
		
		if(STE.IsEmpty()) { // 棧空時(shí),操作符直接壓棧
			STE.Push(EL);
			continue;
		}
		
		if(type == OPTR_RIGHT_PARENTHESIS) { // 若為右括號(hào)
			while(!STE.IsEmpty() \
				&& STE.Peek().type != OPTR_LEFT_PARENTHESIS) { // 取出左括號(hào)之前的操作符
				EL = STE.Pop();
				PO.Insert(EL);
			}
			if(STE.IsEmpty()) { 
				Error(ERR_MISS_LEFT_PARENTHESIS, __LINE__);
				return;
			}
			STE.Pop(); // 彈出左括號(hào)
			continue;
		}
		
		if(STE.Peek().isp < EL.icp) // 棧外優(yōu)先級(jí)高,則直接把EL壓棧
			STE.Push(EL);
		else { // 否則彈出棧內(nèi)的優(yōu)先級(jí)比EL.icp高的元素
			while(!STE.IsEmpty() && STE.Peek().isp >= EL.icp) {
				PO.Insert(STE.Pop());
			}
			STE.Push(EL);
		}
	}

	while(!STE.IsEmpty()) { // 棧內(nèi)剩余的操作符送入中綴表達(dá)式PO
		EL = STE.Pop();
		if(EL.type == OPTR_LEFT_PARENTHESIS) {
			Error(ERR_MISS_RIGHT_PARAENTHESIS, __LINE__);
			return;
		}
		PO.Insert(EL);
	}
}

bool Calculator::Input(char *exp)
{
	Queue<element> IN;
	
	Clear();

	if (strlen(exp) > MaxLength_of_Expression) {
		Error(ERR_EXPRESSION_TOO_LONG, __LINE__);
		return false;
	}

	Trim(exp); // 去除表達(dá)式的非法字符
	
	Construe(IN); // 整理為中綴表達(dá)式
	
	if(GetErrorID() != ERR_NO_ERROR)
		return false;
	
	Conversion(IN); // 轉(zhuǎn)換為后綴表達(dá)式
	return GetErrorID() == 0;
}

double Calculator::Calculate(element EL, double x, double y) const
{ // 雙目運(yùn)算符的具體運(yùn)算
	int type = EL.type;
    
	if (type > 20 && type < 40) //處理雙目運(yùn)算
   		switch(type)  { // '+' , '-' , '*' , '/' , '^'
   		case OPTR_ADD : return ( x + y ); 
   		case OPTR_SUBTRACT : return ( x - y ); 
   		case OPTR_MULTIPLY : return ( x * y ); 
   		case OPTR_DIVIDE : 
			if (y == 0.0) 
				Error(ERR_DEVIDE_BY_ZERO, __LINE__);
   			else
				return ( x / y );
    		break;
		case OPTR_POWER : return (pow( x, y));
		default : Error(ERR_INVALID_OPERATOR, __LINE__); return 0.0;
		}
    else {
		Error(ERR_INVALID_OPERATOR, __LINE__); 
		return 0.0;
    }
	return 0.0;
}

double Calculator::Calculate(element EL, double x) const
{// 單目運(yùn)算符的具體運(yùn)算
    static double (*fun[])(double)={sin, cos, tan, sqrt, 
		log10, log, cot, fabs, floor, asin, acos, atan, sinh,
		cosh, tanh, exp, sqrt}; //*fname[]對(duì)應(yīng)的C函數(shù)名,其中cot為自己寫的
	int type = EL.type;

	if (type > 40) { //處理單目運(yùn)算
		switch(type)  {
		case OPTR_MINUS: return -x;
		case OPTR_POSITIVE: return  x;
		}
		if(type>50) //函數(shù)運(yùn)算
			return ((*fun[type-51])(x));
		else {
			Error(ERR_INVALID_OPERATOR, __LINE__); return 0.0;
		}
	}
	else {
		Error(ERR_INVALID_OPERATOR, __LINE__); return 0.0;
	}
	return 0.0;
}


bool Calculator::Compute(void)
{ // 后綴表達(dá)式求值
    int i, l, type;
	double x, y, r;
    element EL;
	Stack<double> ST; //Stack to operands
    Queue<element> postfix(PO); // 將PO復(fù)制到postfix

    ST.Clear();
    l = postfix.GetLength();

    for (i = 0; i < l; i++) { //逆波蘭表達(dá)式求值
    	EL = postfix.Delete();
    	type = EL.type;
    	
		if (type < 20) { // 操作數(shù)直接壓棧
    		if (type == 0) // 壓入數(shù)字
    		  ST.Push(EL.value);
    		else // 壓入變量
    		  ST.Push(Vars[type-1]);
			continue;
    	}

		if (type > 40) { // 單目操作符
			x = ST.Pop();
			r = Calculate(EL, x);
			ST.Push(r);
			continue;
    	}

		if (type > 20 && type < 40) { // 雙目操作符
			y = ST.Pop(); x = ST.Pop();
			r = Calculate(EL, x, y);
			ST.Push(r);
			continue;
    	}
    }

	if(!ST.IsEmpty()) { // 取出最后結(jié)果
		Result = ST.Pop();
		if (ST.IsEmpty())
			return true;
		else {
			Error(ERR_MISS_OPERATOR, __LINE__);
			return false;
		}
	}
	else  
		Error(ERR_UNKNOWN_ERROR, __LINE__);
	return false;
}


void Calculator::Test(void)
{ // 測(cè)試計(jì)算器的功能
	int i, nv;
	int errid;
	char buf[1000];
	const char *name;
	const char *pch;
	double varsfrom[MaxNumber_of_Variable], var;
	
	cout << "Input a expression: "<<endl;
	//cin.getline(buf, sizeof(buf));
	fgets(buf, sizeof(buf), stdin);

	if(!Input(buf)) {
		errid = GetErrorID();
		pch = GetErrorMessage(errid);
		cout << endl << "ERROR : " << pch << "\nNear Line "<< GetErrorLineNo() <<endl;
		return ;
	}
	
	nv = GetNumberOfVariables();
	if (nv > 0) {
		cout << "\nThere seems to be " << nv << 
			" Variable(s) in your expression, please input them :" << endl;
		for(i = 0; i < nv; i++) {
			name = GetVariableName(i);
			cout << "No." << i + 1 << "  " << name << " = ";
			cin >> var;
			varsfrom[i] = var;
		}
		Assign(varsfrom);
	}
	
	if(!Compute()) {
		errid = GetErrorID();
		
		cout << endl << "ERROR : " << GetErrorMessage(errid) << "\nNear Line "<< GetErrorLineNo() << endl;
		return ;
	}

    cout << "Answer: " << GetResult() << endl;
}

?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产凹凸在线观看一区二区| 天堂一区二区在线免费观看| 欧美电影免费观看高清完整版在线| 成人av在线看| 97精品久久久午夜一区二区三区 | 国产亚洲1区2区3区| 日韩欧美一区二区三区在线| 欧美一区二区三区的| 91麻豆精品国产91久久久久久久久| 欧美日韩国产一区| 欧美一区二区三区播放老司机| 欧美精品在线视频| 精品国产成人系列| 国产欧美精品国产国产专区| 国产亚洲欧美激情| 最近日韩中文字幕| 一区二区三区在线观看欧美| 五月天丁香久久| 麻豆精品视频在线观看视频| 国产成人精品免费| 99精品欧美一区二区三区小说 | 久久精品一二三| 欧美国产激情一区二区三区蜜月 | 91在线视频官网| 色999日韩国产欧美一区二区| 欧洲色大大久久| 日韩精品综合一本久道在线视频| 久久综合久久久久88| 最新国产精品久久精品| 亚洲国产aⅴ成人精品无吗| 蜜桃视频免费观看一区| 成人国产精品免费| 欧美久久久久久久久中文字幕| 欧美一区二区三区不卡| 国产精品热久久久久夜色精品三区 | 不卡一区中文字幕| 欧美日韩成人一区| 久久综合狠狠综合| 综合激情成人伊人| 免费久久99精品国产| 国产精品一区二区在线看| 欧美在线观看18| 欧美激情艳妇裸体舞| 亚洲二区在线观看| 国产电影精品久久禁18| 欧美午夜宅男影院| 国产精品美女一区二区在线观看| 亚洲电影欧美电影有声小说| 国产精品一区二区果冻传媒| 在线观看91视频| 国产欧美一区二区三区在线老狼| 亚洲第一激情av| caoporn国产精品| 久久免费美女视频| 亚洲成人tv网| 91亚洲精品乱码久久久久久蜜桃 | 国产亚洲欧美日韩日本| 日韩精品欧美精品| 在线一区二区视频| 国产欧美日韩久久| 久久精品国产77777蜜臀| 91久久香蕉国产日韩欧美9色| 国产亚洲精品资源在线26u| 日韩中文字幕不卡| 欧美日韩视频在线一区二区| 国产精品久久久久久久久晋中 | 日本在线不卡一区| 欧洲一区二区av| 中文字幕字幕中文在线中不卡视频| 国产精品一区二区久久精品爱涩| 7777精品伊人久久久大香线蕉最新版 | 在线精品观看国产| 国产精品久久久久一区二区三区 | 亚洲成年人影院| 91麻豆成人久久精品二区三区| 国产亚洲欧美在线| 激情六月婷婷综合| 精品久久久久久久人人人人传媒| 免费观看在线色综合| 欧美一区二区私人影院日本| 同产精品九九九| 欧美高清hd18日本| 蜜桃一区二区三区四区| 欧美肥妇毛茸茸| 另类小说视频一区二区| 欧美哺乳videos| 国内精品在线播放| 久久女同精品一区二区| 国产精品白丝jk黑袜喷水| 久久午夜色播影院免费高清| 国产经典欧美精品| 国产精品国产三级国产aⅴ无密码| 成人av高清在线| 亚洲人成在线播放网站岛国| 色88888久久久久久影院按摩| 一级中文字幕一区二区| 91麻豆精品国产91久久久久久| 视频一区欧美日韩| 精品成人一区二区三区四区| 国产伦精品一区二区三区视频青涩 | 琪琪一区二区三区| 久久看人人爽人人| 91在线免费看| 日韩精品欧美成人高清一区二区| 精品福利二区三区| 成人免费视频一区| 亚洲午夜国产一区99re久久| 91精品国产综合久久精品app| 韩国女主播一区| 亚洲另类在线视频| 日韩一区二区精品葵司在线| 成人在线视频一区二区| 一区二区三区在线免费播放| 欧美mv日韩mv国产网站| av电影在线观看一区| 免费日本视频一区| 日韩理论电影院| 欧美成人r级一区二区三区| 91首页免费视频| 精品一区二区三区在线播放| 中文字幕日韩av资源站| 日韩视频一区二区三区| 91丝袜美女网| 国产中文字幕精品| 一区二区三区欧美| 久久精品亚洲麻豆av一区二区| 91久久国产最好的精华液| 激情综合色播五月| 亚洲一区二区四区蜜桃| 欧美国产日本视频| 日韩亚洲欧美高清| 色噜噜夜夜夜综合网| 国产成人精品亚洲午夜麻豆| 丝瓜av网站精品一区二区| 中文在线一区二区| 精品国产免费一区二区三区四区| 日本道免费精品一区二区三区| 国产乱色国产精品免费视频| 五月天中文字幕一区二区| 亚洲特级片在线| 日本一区二区三区在线观看| 日韩欧美一二三| 日韩写真欧美这视频| 欧美日韩一区二区三区四区五区| 97久久人人超碰| 成人一区二区三区在线观看| 狠狠色狠狠色综合日日91app| 天堂一区二区在线免费观看| 亚洲一区成人在线| 亚洲精品久久7777| 一区二区三区在线看| 亚洲理论在线观看| 国产精品夫妻自拍| 亚洲欧美一区二区在线观看| 国产精品少妇自拍| 国产精品亲子伦对白| 国产亚洲精品久| 国产欧美日韩另类视频免费观看| 久久久久亚洲综合| 国产欧美日韩在线看| 国产精品丝袜91| 一区二区在线电影| 亚洲一区二区av电影| 日韩精品电影在线| 麻豆91精品91久久久的内涵| 激情深爱一区二区| 国产福利视频一区二区三区| 高清不卡一区二区在线| 成人久久18免费网站麻豆| 成人精品在线视频观看| 99综合电影在线视频| 99久久婷婷国产| 欧美日韩日日夜夜| 欧美一级一级性生活免费录像| 日韩欧美精品在线| 国产欧美精品在线观看| 亚洲人成小说网站色在线| 亚洲综合一区二区三区| 日本成人超碰在线观看| 国产精品乡下勾搭老头1| av亚洲精华国产精华| 欧美色图在线观看| 日韩一级黄色片| 国产精品麻豆视频| 丝袜美腿高跟呻吟高潮一区| 国内外成人在线| 色噜噜狠狠成人网p站| 欧美一区二区三区在| 中文字幕免费观看一区| 一区二区三区**美女毛片| 蓝色福利精品导航| 97se亚洲国产综合在线| 91精品婷婷国产综合久久竹菊| 欧美国产一区二区| 日本不卡高清视频| 91视视频在线直接观看在线看网页在线看| 欧美在线免费观看亚洲| 久久青草国产手机看片福利盒子| 亚洲图片另类小说| 国产乱码精品一区二区三区av |