PDA

View Full Version : خطا در اجرای پشته



majid_i68
جمعه 26 آبان 1391, 15:41 عصر
سلام دوستان

یکی از دوستان از من خواستند که کد زیر زیر رو اصلاح کنم...البته من هنوز دقیق نگاهش نکرم فعلا سرم شلوغ است:لبخند:.... گفتم این کر رو بزارم تا دوستان راجبعش نظر بدند..بعد از نظرات شما هم استفاده کنم...

قرار است برنامه بنده خدا این کار رو کنه ..با پشته که عملگر ها و اعداد ورودی رو به postfixتبدیل بکنه.البته در آینده:لبخند:.. بیکاز... الان حال نداره کار کنه:لبخند:

#include<stdio.h>
#include<iostream>
#include<conio.h>
#include<string.h>
#include<math.h>
#define MAX 20.b
char stack[MAX];
int top=-1;
char pop();
void push(char item);

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;
}
}

int isoperator(char symbol)
{
switch(symbol)
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '(':
case ')':return 1;
break;
default:return 0;
}
}

void convertip(char infix[],char postfix[])
{
int i,j=0;
char symbol;
stack[++top]='#';
for(i=0;i<strlen(infix);i++)
{
symbol=infix[i];
if(isoperator(symbol)==0)
{
postfix[j]=symbol;
j++;
}
else{
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.
}

void calculate(char postfix[])
{
int i,j=0;
char symbol;
double opr1,opr2,result=0;
for(i=0;i<strlen(postfix);i++)
{
symbol=postfix[i];
if(isoperator(symbol)==0)
{
push(symbol);
}
else{
opr1 = (double)pop();
opr2 = (double)pop();
switch(symbol)
{
case '-' :
result=opr1-opr2;
break;
case '+' :
result=opr1+opr2;
break;
case '*' :
result=opr1*opr2;
break;
case '/' :
result=opr1/opr2;
break;
case '^' :
result=pow(opr1,opr2);
break;
}
push(result);
}
}
while(stack[top]!='#')
{
postfix[j]=pop();
j++;
}
postfix[j]='\0';//null terminate string.
//printf("%d",postfix);
puts(postfix);
}

void main()
{
char infix[20],postfix[20];
clrscr();
printf("Enter the valid infix string:\n");
gets(infix);
convertip(infix,postfix);
printf("The corresponding postfix string is:\n");
puts(postfix);
printf("Resault is:\n");
calculate(postfix);
getch();
}

void push(char item)
{
top++;
stack[top]=item;
}

char pop()
{
char a;
a=stack[top];
top--;
return a;
}

omidshaman
جمعه 26 آبان 1391, 16:00 عصر
اون 20.b چیه تو خط 6؟!
و int main باید باشه نه void main
بعد این یعنی چی خوب دوست شما توضیح نداده نداده درباره کد بعد مثلا تو خط 90 نوشته //null terminate string. خوب این که واضحه!
فانکشن calculate هم به نظر نمیرسه درست کار کنه!
getch(); و clrscr() هم استاندارد نیستن ...
و prototype ها رو هم نزاشتین...
و یک چیز دیگه این که مثلا به جای خط 162 و 163 میشه گذاشت

a=stack[top--];

majid_i68
جمعه 26 آبان 1391, 19:09 عصر
calculate چرا درست کار نمیکه!!!

omidshaman
جمعه 26 آبان 1391, 22:10 عصر
به خاطر خط 106 و 107 چون هر بار که pop خونده میشه یک متغیر char ّبر می گردونه مثلا 2 رو بر می گردونه حالا از اون طرف opr1 نوعش دابله پس به جای 2 که از نوع char ه کاراکتر اسکیش یعنی 52 میره داخل opr1 پس حالا کافیه ما کد اسکی رو منهای 48 یا همون '0' کنیم تا جواب درست در بیاد
اشتباه دوم نحوه نمایش جوابه که چون string ه حتی اگر جواب درست هم باشه بد چاپ میشه
البته میشه این قسمتو بهتر هم نوشت(خیلی بهتر) ولی خوب همینو درستشو میزارم خودت اگر خواستی یک جور دیگه بنویسش...


void calculate(char postfix[])
{
int i,j=0;
char symbol;
double opr1,opr2,result=0;
for(i=0;i<strlen(postfix);i++)
{
symbol=postfix[i];
if(isoperator(symbol)==0)
{
push(symbol);

}
else{

opr1 = pop()-'0';
opr2 = pop()-'0';

switch(symbol)
{
case '-' :
result=opr1-opr2;
break;
case '+' :
result=opr1+opr2;
break;
case '*' :
result=opr1*opr2;
break;
case '/' :
result=opr1/opr2;
break;
case '^' :
result=pow(opr1,opr2);
break;
}
int i2;
push(result+'0');
}
}

while(stack[top]!='#')
{
postfix[j]=pop();
j++;
}
postfix[j]='\0';//null terminate string.

printf("x%dx\n",(int)postfix[0]-'0');

}

majid_i68
جمعه 26 آبان 1391, 23:51 عصر
سلام
برنامه تبدیل رو دارم.. اما چرا .. بعد از نشان دادن جواب ..پیام میده.. شما تستش کنید

#include <iostream>
#include <cstring>
#include <cstdlib>

using namespace std;

struct node {
char data;
node *next;
};

node *top=NULL;
node *bottom=NULL;
node *key;
node *last;
node *before_last;


void push (const char Symbol) {
key = new node;
key->data = Symbol;
key->next = top;
top = key;
}

void push_for_output (node* &stack, int key) {
node* newNode = new node;
newNode->data = key;
newNode->next = stack;
stack = newNode;
}

const char pop() {
if (!top) {
cout << "Stack underflow\n" << endl;
return ' ';
}
node* key = top;
top = top->next;
char ch = key->data;
delete key;
return ch;
}

int pop_for_output (node* &stack) {
int key = stack->data;
node* nodeToDelete = stack;
stack = stack->next;
delete nodeToDelete;
return key;
}

bool isOperator (char *token) {
if (strcmp(token, "+") == 0) {
return true;
}
else if (strcmp(token, "-") == 0) {
return true;
}
else if (strcmp(token, "*") == 0) {
return true;
}
else if (strcmp(token, "/") == 0) {
return true;
}
else {
return false;
}
}



const bool is_empty() {
return !top;
}

int postfix(const char *infix) {
char infix_ch[100]={NULL};
char postfix_ch[100]={NULL};
node* stack = NULL;

strcpy(infix_ch,"(");
strcat(infix_ch, infix);
strcat(infix_ch,")");

char symbol[5]={NULL};
char temp[5]={NULL};

for(int i=0; i<strlen(infix_ch); i++) {
symbol[0]=infix_ch[i];

if(symbol[0]=='(')
push(symbol[0]);

else if(symbol[0]==')') {
symbol[0]=pop( );
while(symbol[0]!='(') {
strcat(postfix_ch, symbol);
symbol[0]=pop( );
}
}

else if(symbol[0]=='^' || symbol[0]=='*' || symbol[0]=='/' || symbol[0]=='+' || symbol[0]=='-') {
if(symbol[0]=='*' || symbol[0]=='/') {
temp[0]=pop( );
while(temp[0]=='^' || temp[0]=='*' || temp[0]=='/') {
strcat(postfix_ch, temp);
temp[0]=pop( );
}
push(temp[0]);
}

else if(symbol[0]=='+' || symbol[0]=='-') {
temp[0]=pop( );
while(temp[0]!='(') {
strcat(postfix_ch, temp);
temp[0]=pop( );
}
push(temp[0]);
}
push(symbol[0]);
}

else
strcat(postfix_ch, symbol);
}

cout << "Postfix: " << postfix_ch;

char postfix[80];
cout << "\nEnter postfix expression (include spaces between each operand and/or operator): ";
cin.getline(postfix, 80);
char *tokens = strtok(postfix, " ");
while (tokens != NULL) {
if (isOperator (tokens)) {
int operand2 = pop_for_output(stack);
int operand1 = pop_for_output(stack);
int result;

if (strcmp(tokens, "+") == 0) {
result = operand1 + operand2;
}
else if (strcmp(tokens, "-") == 0) {
result = operand1 - operand2;
}
else if (strcmp(tokens, "*") == 0) {
result = operand1 * operand2;
}
else if (strcmp(tokens, "/") == 0) {
result = operand1 / operand2;
}

push_for_output (stack, result);
}
else {
push_for_output (stack, atoi (tokens));
}
tokens = strtok(NULL, " ");
}
cout << pop_for_output(stack);
//system("pause");
return 0;
}


int main( ) {
char infix_values[100]={NULL};
cout << "Enter the infix equation: ";
cin >> infix_values;
postfix(infix_values);
}

majid_i68
شنبه 27 آبان 1391, 00:29 صبح
ای ول به خودم ... نظرت راجبعه این چیه
#include<iostream>
#include<stack>
#include<string>
using namespace std;
string infix;
string operand;
string operate;
stack <string> mystack;
string postfix;
string input()
{
cout<<" Ebatrate infix ro vared kon!!: "<<endl;
getline(cin, infix);
return infix;
}
int precedence(string e)
{
int f;
if(e == "*" || e== "/" || e =="%")
f = 2;
else
{
if(e == "+" || e == "-")
f = 1;
}

if(e=="."){
f=0;
}

return f;
}
string convert()
{
for(int i=0; i<infix.length(); i++)
{

switch(infix[i]){

case '+': case'-': case'*': case'/': case'^': case '(': case ')': case'.':

operate=infix[i];
{
if(mystack.empty() || precedence(operate)>= precedence(mystack.top()))
{
mystack.push(operate);
break;
}

else
{
while(precedence(operate)< precedence(mystack.top()))
{
postfix.append(mystack.top());
mystack.pop();
}

mystack.push(operate);


}
}

default: {
operand=infix[i];
postfix.append(operand);
break;

}

}

}

while(!mystack.empty())
{
postfix.append(mystack.top());
mystack.pop();
}

return postfix;
cout<<postfix;

}

int main()
{

input();

convert();
cout<<"postfix Ebatrat Ast --> "<<postfix<<endl;
getchar();
}

majid_i68
شنبه 27 آبان 1391, 00:36 صبح
نمی دونم چرا ..خروجیش اشکال محاسبه میکنه :متفکر:

omidshaman
شنبه 27 آبان 1391, 10:38 صبح
اینا چین دیگه:لبخند:
این دومیه که گذاشتی الگوریتمش مشکل داره پرانتز که بزاری اشتنباه جواب میده
البته این جوری که شما کد می نویسی اگر اشتباه نداشته باشی داخلش جای تعجب داره!
یکم مرتب تر بنویس مثلا بین حلقه های شرطی که به هم ربطی ندارن یا فانکشن ها 2 تا space ّبزار
پایان و شروع اکولاد}{ رو زیر هم بزار...
این e , f هم دو تا اسم بهتر به جاشون بزار که خواناتر باشه کد
می تونی این String هایی که اول معرفی کردیو همرو بزاری داخل یک struct
این قدر هم بیخود از {} استفاده نکن مثلا خط 27-28-29

if(e==".")
f=0;


هدر getchar رو هم نزاشتی

omidshaman
شنبه 27 آبان 1391, 23:32 عصر
این کدو برات مرتبش کردم میزارمش البته اون مشکل پرانتزشو هم حل کردم سعی کن همیشه مرتب بنویسی چون شاید بی نظم نوشتن وقتی کدو می نویسی سریع تر باشه ولی اکثر مواقع موقع تست کردن برنامه چند برابر اون وقت زمانت تلف میشه!
این کد با این که 30 خط از اون کد شما کوتاه تره ولی هم کامل تره هم مرتب تر! اون مشکل پرانتز هم تو خط 48 فیکس شده البته case '%' و 1 دونه break;هم یادت رفته بود بزاری...

#include<iostream>
#include<stack>
#include <vector>
#include<string>
using namespace std;
string infix,operand,operate,postfix;
stack <string> mystack;
string convert(void);
int precedence(string a);
/************************************************** ***************************/
int precedence(string symbol)
{
if(symbol == "*" || symbol== "/" || symbol =="%"||symbol==".")
return 2;
else if(symbol == "+" || symbol == "-")
return 1;
}
/************************************************** ***************************/
string convert()
{
for(int i=0; i<infix.length(); i++)
switch(infix[i])
{
case '+': case'-': case'*': case'/': case'^': case '(': case ')': case'.':case'%':
operate=infix[i];
if(mystack.empty() || precedence(operate)>= precedence(mystack.top()))
{
mystack.push(operate);
break;
}
else
{
while(precedence(operate)< precedence(mystack.top()))
{
postfix.append(mystack.top());
mystack.pop();
}
mystack.push(operate);
break;
}
default:
operand=infix[i];
postfix.append(operand);
break;
}//end of switch
while(!mystack.empty())
{
if(mystack.top()[0]!='('&&mystack.top()[0]!=')')
postfix.append(mystack.top());
mystack.pop();
}
return postfix;
}
/************************************************** ***************************/
int main()
{
cout<<" Ebatrate infix ro vared kon!!: "<<endl;
getline(cin, infix);
convert();
cout<<"postfix Ebatrat Ast --> "<<postfix<<endl;
cin.get();
}

majid_i68
یک شنبه 28 آبان 1391, 00:16 صبح
هزار بار تشکر دوست عزیز کمک بزرگی کردی...