四則運算的實現

c++版

#include <iostream>
#include <string>
#include <cmath>
#include <deque>
using namespace std;

#define LENGTH 61440 //60KB
bool isNo(char c) //is Number
{
	return c >= '0' && c <= '9' || c == '.';
}
bool isSyb(const char* c)//is Symbol
{
	return (*c == '+' || *c == '-' || *c == '*' || *c == '/') && strlen(c) == 1; //ver1.2
}
bool isSyb(char c)//is Symbol
{
	return c == '+' || c == '-' || c == '*' || c == '/';
}

bool isIlg(char c) //is illegal
{
	return !isNo(c) && !isSyb(c) && !(c == '(' || c == ')' || c == ' ');
}

const char* GetSubtext(const char* S,size_t bgn,size_t end) //follow "left-inclusive interval"
{
	char* subtext  = new char[end - bgn + 1];
	subtext[end - bgn] = '\0';
	for (size_t i = bgn; i != end; i++)
		subtext[i - bgn] = S[i];
	return subtext;
}
const char* calc(const char* S,size_t len)
{
	deque<string> words;
	bool inNo = false; //door for isNo
	//bool inSyb = false; //door for isSyb
	size_t NoPos = 0;
	//size_t SybPos = 0;
	size_t ParPos = 0, ParDep = 0;
	for (size_t i = 0; i <= len; i++) //build standard formula
	{
		
		if(isIlg(S[i]) && i != len) //formula illegal checking
		{
			return "The formula is illegal!";
			//exit(1);
		}
		
		if (isNo(S[i]) && !inNo) //Number postion begin
		{
			inNo = true;
			NoPos = i;
		}
		if (!isNo(S[i]) && inNo) //Number postion end
		{
			inNo = false;
			words.push_back(GetSubtext(S,NoPos,i));
		}

		if (isSyb(S[i])/* && !inSyb*/)
		{
			/*
			inSyb = true;
			SybPos = i;
			*/
			words.push_back(GetSubtext(S,i,i + 1));
		}
		/*
		if (!isSyb(S[i]) && inSyb)
		{
			inSyb = false;
			words.push_back(GetSubtext(S,SybPos,i));
		}*/
		
		if (S[i] == '(')
		{
			//inPar = true;
			ParDep++;
			ParPos = i + 1; //left-inclusive interval
			size_t j;
			for (j= i + 1; ParDep && j <= len; j++)
			{
				if (S[j] == '(') ParDep++;
				if (S[j] == ')') ParDep--;
			}
			if (j <= len)
			{
				string recResult(calc(GetSubtext(S,ParPos,j - 1),strlen(GetSubtext(S,ParPos,j - 1))));
				if (recResult == "The formula is illegal!")
					return "The formula is illegal!";
				else if (recResult == "Parentheses is not match!")
					return "Parentheses is not match!";
				else
					words.push_back(recResult);
			}
			else
			{
				//parentheses is not match
				return "Parentheses is not match!";
			}
			i = j; //jump over subtext
		}
		if (S[i] == ')')
			return "Parentheses is not match!";
	} //end for

	long double tempResult = 0;
	static char CtmpResult[50];

	//check formula
	if (words.size() == 0) return "0."; // 0 element
	if (words.size() == 1 ) //1 element
		if( !isSyb(words.front().c_str()))
		{
			strcpy_s(CtmpResult,words.front().c_str());
			return CtmpResult;
		} 
		else
		return "The formula is illegal!";
	if (words.front() == "*" || words.front() == "/")  //front is symble
		return "The formula is illegal!";
	if (words.front() == "+" || words.front() == "-")
	{
		if (!isSyb((words.begin() + 1) -> c_str()))
		{
			words.front() += *(words.begin() + 1);
			words.erase(words.begin() + 1); //erase second one
		}
		else
		return "The formula is illegal!";
	}
	if (isSyb(words.back().c_str()))
		return "The formula is illegal!";
	for (deque<string>::iterator i = words.begin() + 1; i < words.end(); i++)
	{
		if ((*i == "*" || *i == "/") && (isSyb((i-1) -> c_str())) && strlen((i-1) -> c_str()))
			return "The formula is illegal!";
		if ((*i == "+" || *i == "-") && (isSyb((i-1) -> c_str())) && strlen((i-1) -> c_str()))
			if(!isSyb(*((i+1) -> c_str())))
			{
				*(i + 1) = *i + *(i + 1);
				i = words.erase(i);
			}
			else
			return "The formula is illegal!";
	}

	//start calculate
	for (deque<string>::iterator i = words.begin(); i != words.end(); i++) 
	{
		//calculate * and /
		if (*i == "*")
		{
			tempResult = atof((i-1) -> c_str()) * atof((i+1) -> c_str());
			_gcvt_s(CtmpResult,tempResult,47);//double to string
			i = words.erase(i - 1);
			i = words.erase(i);
			*i = CtmpResult;
		}
		if (*i == "/")
		{
			tempResult = atof((i-1) -> c_str()) / atof((i+1) -> c_str());
			_gcvt_s(CtmpResult,tempResult,47); //double to string
			i = words.erase(i - 1);
			i = words.erase(i);
			*i = CtmpResult;
		}
	}
	for (deque<string>::iterator i = words.begin(); i != words.end(); i++) 
	{
		//calculate + and -
		if (*i == "+")
		{
			tempResult = atof((i-1) -> c_str()) + atof((i+1) -> c_str());
			_gcvt_s(CtmpResult,tempResult,47); //double to string
			i = words.erase(i - 1);
			i = words.erase(i);
			*i = CtmpResult;
		}
		if (*i == "-")
		{
			tempResult = atof((i-1) -> c_str()) - atof((i+1) -> c_str());
			_gcvt_s(CtmpResult,tempResult,47);//double to string
			i = words.erase(i - 1);
			i = words.erase(i);
			*i = CtmpResult;
		}
	}

	strcpy_s( CtmpResult, words.front().c_str());
	return CtmpResult;
}
void main(int argc,char* argv[])
{
	if (argc > 1)
	{
		cout<<argv[1]<<ends<<'='<<ends<<calc(argv[1],strlen(argv[1]))<<endl;
	}
	else
	{
		cout<<"請輸入公式,如需退出請按CTRL + C。\nVER1.3 design by zuozhiwen.\n";
		char S[LENGTH];
		while(1)
		{
			cin.getline(S,LENGTH);
			cout<<calc(S,strlen(S))<<endl;
		}
	}
}

C版

#include <stdio.h>
#include <assert.h>
int cal(int c1,char op,int c2)
{
	if(op=='+') return c1+c2;
	if(op=='-') return c1-c2;
	if(op=='*') return c1*c2;
	if(op=='/') return c1/c2;
}
int calculate(int len,char *expstr)
{
	assert(expstr);
	if(len<3) return -1;
	//出錯的情況
	char *p=expstr;
	int c1=p[0]-'0';
	char op=p[1];
	int c2=p[2]-'0';
	p+=3;
	//只有兩個操作數和一個符號的情況
	while(*p)
	{
		if(*p=='*'||*p=='/')
		{
			c2=cal(c2,*p,p[1]-'0');
		}
		else
		{
			c1=cal(c1,op,c2);
			op=*p;
			c2=p[1]-'0';
		}
		p+=2;
	}
//多於3個的情況
	return cal(c1,op,c2);
}

int main()
{
	int res=calculate(11,"1+2*3/5-6*7");
	printf("value:%d",res);
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章