PDA

View Full Version : سوال: تبدیل عبارت میانوندی به پسوندی



GENERAL IRAJ
چهارشنبه 22 آبان 1392, 14:00 عصر
با عرض سلام خدمت دوستان و اساتید عزیز ، با توجه به الگوریتمی که برای من تعریف شده بود دارم برنامه ای برای تبدیل یک عبارت میانوندی به پسوندی می نویسم ، کدش رو هم نوشتم ، ولی ارور می ده:
توضیحات:
برنامه بدین صورت است که یک رشته را به صورت عبارت میانوندی خوانده و پس از تبدیل به پسوندی آن را درون یک پشته کاراکتری ریخته و آن را چاپ می کنیم، تابع PRE برای تشخیص تقدم عملگرها استفاده می کنیم.
از پشته opt برای نگهداری عملگرها و از پشته st1برای نگهداری اعداد( به صورت کاراکتری ) و در انتها برای نگهداری عبارت پسوندی اشتفاده می شود.

#include "stdafx.h"
#include <iostream>
#include <string>
#include <stdlib.h>
#include <stack>






bool pre(char,char);

using namespace std;
int main()
{
string str;
stack<char>st1;
stack<char>opt;
cout <<"please Enter your pharese:\n";
cin >> str;
cout << "your INFIX pherase is :\n" <<endl<<str;
for (int i = 0;i<str.length()-1;i++)
{
char c = str.at(i);
if (i=='+'||i=='*'||i=='-'||i=='/'||i==')'||i=='('||i=='^' && (pre(c,opt.top())==true))
{
opt.push(c);
}
else if(pre(c,opt.top())!=true && st1.empty()!=true)
{
char op1,op2,op;
op1 = st1.top();
st1.pop();
op2 = st1.top();
st1.pop();
op = opt.top();
opt.pop();
st1.push(op1);
st1.push(op2);
st1.push(op);
}
else if (c==')')
{
while (c!='(')
{
char op1,op2,op;
op1 = st1.top();
st1.pop();
op2 = st1.top();
st1.pop();
op = opt.top();
opt.pop();
st1.push(op1);
st1.push(op2);
st1.push(op);
}
}
else // if caracter beetween '0'&&'9'
{
st1.push(c);
}
}
while (st1.empty()!=true)
{
cout <<st1.top();
st1.pop();
}
system("PAUSE");
return 0;
}
bool pre(char op1,char op2)
{
if (op1 == '*'||op1 == '/'&&op2 == '+'||op2 == '-') return true;
if (op1 == op2) return false;
if (op1 == '(' && op2 == '+'||op2 == '*'||op2 == '/'||op2 == '-'||op2== '^') return true;
if (op1 == '+'||op1 == '*'||op1 == '/'||op1 == '-'||op1 == '^' &&op2 == '(') return true;
if (op1 == '+'||op1 == '*'||op1 == '/'||op1 == '-'||op1 == '^' && op2 == '0\'') return true;
}







ایت برنامه در visual studio نوشته شده است.
ارورش هم اینه:
Debuge Assertion fieled

البته تا جایی که عبارت رو چاپ کنه میاد ولی ایراد از جایی که می خواهد وارد حلقه for بشه شروع می شه ،
ولی نمیدونم چیه.
ممنون می شم کمکم کنید.

GENERAL IRAJ
پنج شنبه 23 آبان 1392, 00:24 صبح
آقا تو رو خدا کسی نیست کمکم کنه:گریه:
من که کد رو گذاشتم ، ایرادش گفتم ، حتی هنوز هم نتونستم درستش کنم،
من باید این پروژه رو تحویل بدم.

rahnema1
پنج شنبه 23 آبان 1392, 10:32 صبح
ما که نمی دونیم الگوریتم شما چه بوده و انقدر هم از op , pop ,opt و کلمات شبیه هم استفاده کرده اید که گیج کننده است به این سایت هم می تونید مراجعه کنید http://cboard.cprogramming.com/c-programming/11099-expression-convert-infix-notation-postfix-notation.html

omidshaman
پنج شنبه 23 آبان 1392, 20:16 عصر
اون pre(c,opt.top())
توی خط 26 مشکل داره چون داری روی یک stack خالی عمل top رو انجام میدی .
خوانایی کدتم زیر صفره ! ...

GENERAL IRAJ
پنج شنبه 23 آبان 1392, 23:12 عصر
ما که نمی دونیم الگوریتم شما چه بوده و انقدر هم از op , pop ,opt و کلمات شبیه هم استفاده کرده اید که گیج کننده است
در مورد الگوریتم:
ابتدا عبارتی را به صورت رشته وارد می کنیم(str) و دو پشته یکی برای عملوندها (st1)و یکی برای عملگرها(opt) و مراحل زیر را انجام می دهیم:
1- عنصر اول عبارت ورودی را می خوانیم(عنصر شامل:عملوند،عملگر،پرانتز باز و بسته)
2- اگر عملوند باشد آنرا درون پشته عملوندی pushمی کنیم(خط 59)
3- اگر عملگر باشد و نسبت به عملگر بالای پشته تقدم داشته باشد آنرا درون پشته عملگری قرار می دهیم(خط 26)
4- اگر عملگر باشد ونسبت به عملگر بالای پشته تقدم نداشته باشد آنگاه دستورات زیر را اجرا میکنیم:

char op1,op2,op;
op1 = st1.top();
st1.pop();
op2 = st1.top();
st1.pop();
op = opt.top();
opt.pop();
st1.push(op1);
st1.push(op2);
st1.push(op);
خطوط 32 الی 41
5 - اگر رانتز بسته بود تارسیدن به اولین پرانتز باز به ازای هر عملگر بالای پشته عملیات محاسباتی مرحله 4 را انجام می دهیم.(خطوط 43 الی 56)
6- اگر به انتهای عبارت نرسیده باشیم عنصر بعدی را خوانده و به مرحله 2 می وریم
7- تا خالی شدن پشته عملگری محاسبات را انجام می دهیم.
8 - فرم پسوندی عبارت روی پشته عملوندی قرار دارد:لبخند:

توی خط 26 مشکل داره چون داری روی یک stack خالی عمل top رو انجام میدی .
خوانایی کدتم زیر صفره ! ...
اون مشکل این جوری حل میشه:
char x ;
if (opt.empty()!=true)x=opt.top();opt.pop();
در مورد خوانایی کد هم ازتون معذرت می خواهم.
برنامه موقع کامپایل ارورو نمی ده ولی 2 تا warning داره:
Warning 1 warning C4018: '<' : signed/unsigned mismatch c:\users\general iraj\desktop\st6\st6\st.cpp 20 1 st6
Warning 2 warning C4715: 'pre' : not all control paths return a value c:\users\general iraj\desktop\st6\st6\st.cpp 78 1 st6
در مورد اولی چیزی نمی دونم ولی دومی به تابع pre مربوط میشه.

GENERAL IRAJ
جمعه 24 آبان 1392, 23:39 عصر
خداییش باز هم خودم باور کنید تقریباً 2 روز واسش وقت گذاشتم:قهقهه:
(آخه خیلی وقته که کد نویسی نکردم یه سری مطالب پایه رو دوباره خوندم)
البته این رو هم بگم ریا نشه قسمتی از کد رو از جای دیگه اضافه کردم
امید وارم این تایپیک به نتیجه رسیده باشه

#include <iostream>
#include <conio>
#include <stdlib>
#define MAX 100
char stack[MAX];
int top=-1;
char pop();
void push(char item);
int prcd(char symbol);
bool isoperator(char symbol);
void convert(char infix[],char postfix[]);
int main()
{
char infix[100],postfix[100];
cout << "please Enter your INFIX notation:\n";
cin >> infix;
convert (infix,postfix);
cout <<"the POSTFIX notation is:\n"<<postfix;
getch();
return 0;
}
char pop()
{
char a;
a=stack[top];
top--;
return a;
}
void push(char i)
{
top++;
stack[top]=i;
}
int prcd(char symbol)
{
switch(symbol)
{
case '+':
case '-':return 2;
break;
case '*':
case '/':return 4;
break;
case '^':
return 6;
break;
case '(':
case ')':
case '#':return 1;
break;
}
}
bool isoperator(char symbol)
{
switch(symbol)
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '$':
case '(':
case ')':return 1;
break;
default:return 0;
}
}
void convert(char infix[],char postfix[])
{
int i,symbol,symbol2,j=0;
stack[++top]='#';
for(i=0;i<strlen(infix);i++)
{
symbol=infix[i];
if(!isoperator(symbol))
{
postfix[j]=symbol;
j++;
}
else{
if(!isoperator(symbol))
{ postfix[j]=symbol;
j++;
}
if(symbol=='(')push(symbol);
else if(symbol==')')
{
while(stack[top]!='(')
{
postfix[j]=pop();
j++;
}
pop();
}
else{
if(prcd(symbol)>prcd(stack[top]))
push(symbol);
else{
while(prcd(symbol)<=prcd(stack[top]))
{
postfix[j]=pop();
j++;
}
push(symbol);
}
}
}
}
while(stack[top]!='#')
{
postfix[j]=pop();
j++;
}
postfix[j]='\0';//null terminate string.
}

camelia.ji
یک شنبه 12 دی 1395, 13:00 عصر
میشه ی توضیح مختصر از تابع convert,isoperator,prcdبدین