#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
class Token
{
private:
double value;
char kind;
public:
void set(double v) // set num token
{
(*this).value = v;
this->kind = 'n';
}
void set(char c) // set char token
{
switch (c)
{
case '(': case ')': case '^': case '*': case '/':
case '+': case '-': case 'q': case ';':
{
kind = c;
value = 0;
break;
}
default:
cout << "Operator \'" << c << "\' is invalid.\n";
}
}
double getvalue() const // for functions that do not modify this
{
return value;
}
char getkind() const
{
return kind;
}
friend ostream& operator<<(ostream& out, const Token& t)
{
if (t.kind == 'n')
out << t.value;
else
out << t.kind;
return out;
}
};
Token gettoken() // this function reads one Token at a time
{
Token t;
double v;
char c;
cin >> c;
switch(c)
{
case '(': case ')': case '^': case '*': case '/':
case '+': case '-': case 'q': case ';':
{
t.set(c);
return t;
}
case '.': case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7': case '8':
case '9':
{
cin.putback(c); // put it back into out stream
cin >> v;
t.set(v);
return t;
}
default:
cout << "Invalid character: \'" << c << "\'.\n";
return t;
}
}
double evaluate(vector<Token>& expr, size_t beg, size_t end)
{
// regularization of -
for (size_t i = beg; i < end; i++)
{
if (expr[i].getkind() == '-')
{
if ( i == beg )
{
expr[i].set(-expr[i+1].getvalue());
expr.erase(expr.begin()+i+1);
}
else if ( expr[i-1].getkind() != 'n')
{
expr[i].set(-expr[i+1].getvalue());
expr.erase(expr.begin()+i+1);
}
}
}
for (size_t i = end-1 ; i > beg; i--)
{
if (expr[i].getkind() == '^')
{
expr[i-1].set( pow(expr[i-1].getvalue(),expr[i+1].getvalue()) );
expr.erase(expr.begin()+i); // removes ^
expr.erase(expr.begin()+i); // removes right term
end-=2;
}
}
// handle mul and div
for (size_t i = beg; i < end; i++)
{
if (expr[i].getkind() == '*')
{
expr[i-1].set( expr[i-1].getvalue() * expr[i+1].getvalue() );
expr.erase(expr.begin()+i); // removes *
expr.erase(expr.begin()+i); // removes right term
i--;
end-=2;
}
else if (expr[i].getkind() == '/')
{
expr[i-1].set( expr[i-1].getvalue() / expr[i+1].getvalue() );
expr.erase(expr.begin()+i); // removes /
expr.erase(expr.begin()+i); // removes right term
i--;
end-=2;
}
}
// handle add and sub
for (size_t i = beg; i < end; i++)
{
if (expr[i].getkind() == '+')
{
expr[i-1].set( expr[i-1].getvalue() + expr[i+1].getvalue() );
expr.erase(expr.begin()+i); // removes +
expr.erase(expr.begin()+i); // removes right term
i--;
end-=2;
}
else if (expr[i].getkind() == '-')
{
expr[i-1].set( expr[i-1].getvalue() - expr[i+1].getvalue() );
expr.erase(expr.begin()+i); // removes -
expr.erase(expr.begin()+i); // removes right term
i--;
end-=2;
}
}
return expr[beg].getvalue();
}
double evaluate( vector<Token>& expr )
{
while(expr.size() > 1)
{
for (size_t i = expr.size()-1; i > 1; i--)
{
if (expr[i].getkind() == ')')
{
size_t rparenpos = i;
for (size_t i = 0; i < rparenpos; i++)
{
if (expr[i].getkind() == '(')
{
size_t lparenpos = i;
evaluate(expr, lparenpos+1, rparenpos);
expr.erase(expr.begin()+lparenpos);
expr.erase(expr.begin()+lparenpos+1);
i--;
}
else
{
cout << "Invalid expression: parentheses not matched";
return 0;
}
}
}
else
{
evaluate(expr, 0, expr.size());
}
}
}
return expr[0].getvalue();
}
int main()
{
vector<Token> expr;
Token t;
double exprval;
cout << "Enter an algebraic expression such as (1+12.5)*4^2\n"
<< "For now we can handle only: +,-,*,/.\n"
<< "Finish expression with character \';\'"
<< endl;
while (true)
{
t = gettoken();
if (t.getkind()=='q')
break;
if ( t.getkind() == ';')
{
for(size_t i = 0; i < expr.size(); i++)
cout << expr[i];
exprval = evaluate(expr);
cout << " = " << exprval << endl;
expr.clear();
}
else
{
expr.push_back(t);
}
}
cout << endl;
return 0;
}
uj5u.com熱心網友回復:
太長的程式沒人愿意看的。基本上所有的程式都是單步除錯出來的。你可以試試,得不到結果肯定是程式邏輯有問題。我以前用中輟表達實作過一個計算器。你可以試試。uj5u.com熱心網友回復:
//-------------------------------------------------------
//自定義堆疊
template <class T> class cMystack
{
public:
static const unsigned int nMax = 10;
cMystack();
~cMystack();
bool IsEmpt();
void Push(T data);
T Pop();
T GetBack();
private:
T* m_pData;
long m_size;
};
template <class T> cMystack<T>::cMystack()
{
m_pData = new T[nMax];
m_size = 0;
}
template <class T> cMystack<T>::~cMystack()
{
delete m_pData;
m_pData = NULL;
m_size = 0;
}
template <class T> bool cMystack<T>::IsEmpt()
{
return m_size==0?true:false;
}
template <class T> void cMystack<T>::Push(T data)
{
if (m_size >= nMax && m_size%nMax == 0)
{
T* pData = new T[m_size];
memcpy(pData, m_pData, m_size);
unsigned int tsize = (m_size/nMax+1)*nMax;
delete m_pData;
m_pData = new T[tsize];
memcpy(m_pData, pData, m_size);
delete pData;
}
m_pData[m_size++] = data;
}
template <class T> T cMystack<T>::Pop()
{
if (m_size <= 0) return 0;
return m_pData[--m_size];
}
template <class T> T cMystack<T>::GetBack()
{
return m_pData[m_size-1];
}
//-------------------------------------------------------
inline double Calculate(double a, double b, char ch)
{
if (ch == '+')
{
return a+b;
}
else if (ch == '-')
{
return a-b;
}
else if (ch == '*')
{
return a*b;
}
else if (ch == '/')
{
if (b == 0) return 0;
return a/b;
}
else
return 0;
}
//-------------------------------------------------------
//不做算式的合法化檢查
typedef cMystack<double> myStackValue;
typedef cMystack<char> myStackOperator;
double Calculator(char* pFormula, int nLength)
{
if (pFormula == NULL || nLength <= 0) return 0;
double lResult = 0;
double lTemp = 0;
myStackValue tValue;
myStackOperator tOperator;
int nCount = 0;
char* pNumber = new char[nLength+1];
memset(pNumber, 0, nLength+1);
char chCurOper, chTemp;
for(int i=0; i<nLength; i++)
{
chCurOper = pFormula[i];
if (chCurOper >= '0' && chCurOper <= '9' || chCurOper == '.')
{
pNumber[nCount++] = chCurOper;
continue;
}
else
{
//有左括號肯定是最左邊
if (chCurOper == '(')
{
tOperator.Push('(');
}
else
{
// 得到前面的數字
if (nCount > 0)
{
pNumber[nCount] = '\0';
lTemp = atof(pNumber);
}
else
{
lTemp = tValue.Pop();
}
nCount = 0;
if (chCurOper == '+' || chCurOper == '-')
{
if (tOperator.IsEmpt())
{
tOperator.Push(chCurOper);
tValue.Push(lTemp);
}
else
{
while(!tOperator.IsEmpt())
{
chTemp = tOperator.GetBack();
if (chTemp == '(') break;
chTemp = tOperator.Pop();
double a = tValue.Pop();
lTemp = Calculate(a, lTemp, chTemp);
}
tOperator.Push(chCurOper);
tValue.Push(lTemp);
}
}
else if (chCurOper == '*' || chCurOper == '/')
{
if (tOperator.IsEmpt())
{
tOperator.Push(chCurOper);
tValue.Push(lTemp);
}
else
{
while(!tOperator.IsEmpt())
{
chTemp = tOperator.GetBack();
if (chTemp == '*' || chTemp == '/')
{
chTemp = tOperator.Pop();
double a = tValue.Pop();
lTemp = Calculate(a, lTemp, chTemp);
}
else
{
break;
}
}
tOperator.Push(chCurOper);
tValue.Push(lTemp);
}
}
else if (chCurOper == ')')
{
while(!tOperator.IsEmpt())
{
chTemp = tOperator.Pop();
if (chTemp == '(') break;
double a = tValue.Pop();
lTemp = Calculate(a, lTemp, chTemp);
}
tValue.Push(lTemp);
}
else if (chCurOper == '^')
{
lTemp *= lTemp;
tValue.Push(lTemp);
}
}
}
}
// 得到前面的數字
if (tOperator.IsEmpt())
{
lResult = tValue.Pop();
}
else
{
lTemp = 0;
if (nCount > 0)
{
pNumber[nCount] = '\0';
lTemp = atol(pNumber);
}
nCount = 0;
//處理結束
while(!tOperator.IsEmpt())
{
chTemp = tOperator.Pop();
if (chTemp == '(') break;
double a = tValue.Pop();
lTemp = Calculate(a, lTemp, chTemp);
}
lResult = lTemp;
}
return lResult;
}
uj5u.com熱心網友回復:

抄來的程式,更沒個看, 鬼知道里面有多少個坑
自己寫的起碼你自己還能知道原理, 錯了也大概明白哪兒不對
從別的地方搬來一個只能挖坑的程式,非要用來建高樓, 高樓變成地下室然后來問你為啥不行?
根源上地方法就不支持,你說為啥不行
你就沒有找到行的方法(抄了一個考試老不及格的卷子還想考高分兒嗎?
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/113118.html
標籤:C++ 語言
上一篇:近似求pi
下一篇:關于c語言實作基數排序的問題!!!我寫的是在頭檔案里的,我加了自己寫的基數排序,程式就無法運行。不知道基礎排序的頭檔案哪里錯了
