PDA

View Full Version : سوال: تبدیل infix به postfix و ارزیابی آن برای عملوند های چند رقمی



Omid707
جمعه 12 آذر 1389, 19:07 عصر
سلام
برنامه ای برای تبدیل infix به postfix و ارزیابی عبارت postfix نوشتم اما فقط با اعداد تک رقمی کار میکنه
مثلا عبارت 4/8-5*(2+6) به عبارت -/48*5(+62) تبدیل و سپس عبارت دوم را ارزیابی وجواب را (38)بدست می آورد اما نمیتواند عبارت های دو یا چند رقمی را تبدیل و محاسبه کند مانند 65+38
جستجو کردم الگوریتم هایی که در سایت پیدا کردم واسه عملوند های یک رقمی بود و یکی از برنامه هایی که در لیست منابع ،مراجع ومقالات مفید تالار بود اصلا جواب درستی نمیداد یا شاید من بلد نبودم درست استفاده کنم
عبارت 7+2 رو بصورت 7+ نمایش میداد:متعجب:
ممنون میشم راهنمایی کنید.در ضمن ارسال پیام خصوصی برای من وشاید برای همه کار نمیکنه چند ماه پیش برای یکی از مدیران پیام نوشتم ولی ارسال نشد برای همین مورد تاپیکی جداگانه زدم وتذکر دادم مدیر محترم تاپیک بنده رو حذف کرد ونوشت از طریق پیام خصوصی مطرح کنید آخه اگه ارسال پیام خصوصی امکان پذیر بود که من تاپیک نمیزدم:متفکر:

Salar Ashgi
جمعه 12 آذر 1389, 23:07 عصر
ببینید در مسائل الگوریتمی ابتکار و خلاقیت ، حرف اول را میزند . مطمئنا قرار نیست همیشه ، همه چیز
آماده باشد . دوست عزیز شما در بحث مبناها برای نمایش اعداد بزرگتر از 10 ، چه کاری انجام میدهید ،
اینجا هم همین کار را بکنید ، یعنی مثلا A=10 و B=11 و ... بدین ترتیب مثلا عدد 36 میشود 6+3*A !
بعد از این نحوه تفسیر برنامه بستگی به خود برنامه نویس دارد .
موفق باشید ./

Pouri_sb
شنبه 13 آذر 1389, 07:46 صبح
کدتون رو بزارید، الگوریتمی که من دیده بودم این مشکل رو نداشت،

Omid707
شنبه 13 آذر 1389, 16:58 عصر
کدتون رو بزارید، الگوریتمی که من دیده بودم این مشکل رو نداشت،
ببخشید منظورتون کد من بود یا کدی که از این سایت برداشتم چون کد من که براساس راهنمایی کتاب دیتل نوشته شده برای اعداد تک رقمی مشکل نداره و فقط باید کمی خلاقیت به خرج بدم تا اون رو برای کار با عملوند های چند رقمی بهینه سازی کنم
این کد سایت بود که اصلا جواب نمیداد وتا اونجا که من دیدم ظاهرا برای کار با کارکتر های حروف الفبا نوشته شده بود
کد من از دو کلاس جداگانه یکی برای تبدیل infix به postfix و دیگری برای ارزیابی postfix ومحاسبه ریاضی بود و از کلاس پشته هم استفاده کرده بود اینجا دو کلاس اصلی رو میزارم ولی برای اجرا به همون پشته ای که نوشتم نیاز داره

+سرایند کلاسInfixToPostfixConverter

#ifndef INFIXTOPOSTFIXCONVERTER_H
#define INFIXTOPOSTFIXCONVERTER_H
#include <string>
using std::string;
#include "Stack.h"

class InfixToPostfixConverter
{
public:
InfixToPostfixConverter();
~InfixToPostfixConverter();
string ConvertToPostfix(string &);
bool IsOperator(char &);
bool Precedence(char &,char &);
void PrintInfix()const;
void PrintPostfix()const;

private:
string Infix;
string Postfix;
Stack<char> ST;
//utility function
void SetInfix(string &);
};

#endif
+پیاده سازی کلاسInfixToPostfixConverter

#include <iostream>
using std::cout;
using std::endl;
#include "InfixToPostfixConverter.h"

InfixToPostfixConverter::InfixToPostfixConverter()
:Infix(""),Postfix(""),ST()
{
}

InfixToPostfixConverter::~InfixToPostfixConverter( )
{
}

bool InfixToPostfixConverter::IsOperator(char &X)
{
switch(X)
{
case '*':
case '/':
case '%':
case '+':
case '-':
case '^':
return true;
break;

default:
return false;
break;
}
}
//مقایسه دو عملگر برای بررسی اولویت آنها
bool InfixToPostfixConverter::Precedence(char &A/*Operator of infix*/,char &B/*Operator of postfix*/)
{
int PrecedenceA=0;
int PrecedenceB=0;
switch(A)
{
case '(':
case ')':
PrecedenceA=1;//عدد کمتر تقدم بالاتر
break;
case '*':
case '/':
case '%':
PrecedenceA=2;
break;

case '+':
case '-':
PrecedenceA=3;
break;

case '^':
PrecedenceA=4;//عدد بیشتر تقدم پایین تر
break;

default:
break;
}//end of - switch(A)

switch(B)
{
case '(':
case ')':
PrecedenceB=1;
break;
case '*':
case '/':
case '%':
PrecedenceB=2;
break;

case '+':
case '-':
PrecedenceB=3;
break;

case '^':
PrecedenceB=4;
break;

default:
break;
}//end of - switch(B)
//باید اولویت و تقدم عملگر پشته از عملگر میانوندی بیشتر یا برابر باشد
if( PrecedenceB <= PrecedenceA) { return true; }
else { return false; }
}

string InfixToPostfixConverter::ConvertToPostfix(string &value)
{
SetInfix(value);
char v;
while( !ST.IsEmpty() ) { ST.Pop(v);}
ST.Push('(');
Infix+=')';
int i=0;
while( !ST.IsEmpty() )
{
v=Infix[i];
switch(v)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
Postfix+=v;
break;

case '(':
ST.Push(v);
break;

default:
if( IsOperator(v) )
{
char n;
char X=ST.StackTop();
while( Precedence(v,X) && (X!='(') )
{
ST.Pop(n);
Postfix+=( n );
X=ST.StackTop();
}
ST.Push(v);
}//end of - if( IsOperator(v) )
else if( v == ')')
{
char n;
while( ST.StackTop() != '(')
{
Postfix+=( ST.StackTop() );
ST.Pop(n);
}
ST.Pop(n);
}//end of - else if( v == ')')
break;

}//end of - switch(v)
i++;
}//end of - while( !ST.IsEmpty() )
return Postfix;
}

void InfixToPostfixConverter::PrintInfix() const
{
cout<<endl<<Infix<<endl;
}

void InfixToPostfixConverter::PrintPostfix() const
{
cout<<endl<<Postfix<<endl;
}

void InfixToPostfixConverter::SetInfix(string &value)
{
Infix=value;
}
+سرایند کلاس PostfixEvaluator

#ifndef POSTFIXEVALUATOR_H
#define POSTFIXEVALUATOR_H

#include "InfixToPostfixConverter.h"

class PostfixEvaluator :public InfixToPostfixConverter
{
public:
PostfixEvaluator(string &);
~PostfixEvaluator();
int EvaluatePostfixExpression();
void PrintEvaluatePostfix()const;
int Calculate(int X,char Operator,int Y);

private:
string Value;
Stack<int> EPostfix;
};
#endif
+پیاده سازی کلاسPostfixEvaluator

#include <cmath>
#include "PostfixEvaluator.h"

PostfixEvaluator::PostfixEvaluator(string &T)
:Value(T),EPostfix()
{
}

PostfixEvaluator::~PostfixEvaluator()
{
}

int PostfixEvaluator::EvaluatePostfixExpression()
{
int i=0;
char c;
Value+=')';
c=Value[i];
while( c != ')')
{
int Charecter=c;
int Zero='0';
switch(c)
{
case'0':
case'1':
case'2':
case'3':
case'4':
case'5':
case'6':
case'7':
case'8':
case'9':
EPostfix.Push(Charecter-Zero);
break;

default:
if( IsOperator(c) )
{
int V,X,Y;
EPostfix.Pop(V);
Y=V;
EPostfix.Pop(V);
X=V;
V=Calculate(X,c,Y);
EPostfix.Push(V);
}//end of - if( IsOperator(c) )
}//end of - switch(c)
i++;
c=Value[i];
}//end of - while( c != ')')
int V;
EPostfix.Pop(V);
return V;
}

int PostfixEvaluator::Calculate(int X, char Operator, int Y)
{
int Result;
switch(Operator)
{
case'*':
Result=X*Y;
break;

case'/':
Result=X/Y;
break;

case'%':
Result=X%Y;
break;

case'+':
Result=X+Y;
break;

case'-':
Result=X-Y;
break;

case'^':
Result=pow(static_cast<double>(X),Y);
break;
}//end of - switch(Operator)
return Result;
}

void PostfixEvaluator::PrintEvaluatePostfix() const
{
EPostfix.Print();
}