回 帖 发 新 帖 刷新版面

主题:求助:大哥大姐们,帮个忙啊!帮我看一下这道题.谢谢

要求用链表实现堆栈,并用堆栈进行四则求表达式 (((2*(1+(8-4)))-8)/2)值。可以设3个堆栈,分别存放右括号(,整数,计算符。
每读到‘)’,弹出堆栈栈顶元素,处理计算,中间计算结果再压栈。
这是头程序:下面的不会做了.帮忙喔 


 main()
 { int result;
   char str="(((2*(1+(8-4)))-8)/2)";
   result=process(str);
   printf("%d\n",result);
 }
 int process(char *str)
{.........

回复列表 (共5个回复)

沙发

这是以前写的一个程序,计算任意表达式的值:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct stackNode {
    char value;
    struct stackNode * nextPtr;
};

typedef struct stackNode STACKNODE;
typedef STACKNODE * STACKNODEPTR;

char *convertToPostfix (char []);
int isOperator (char c);
int precedence (char operator1,char operator2);
void push (STACKNODEPTR *topPtr, char info);
char pop (STACKNODEPTR *topPtr);
char stackTop (STACKNODEPTR  topPtr);
int isEmpty (STACKNODEPTR topPtr);
void printStack (STACKNODEPTR);    /*打印堆栈,多半看看堆栈是什么样子的,是否真的压进去了,或者弹出来了*/

/*下面的是用来计算后缀表达式*/
int postfix_Result(char *);

struct stackNode2 {
    int data;
    struct stackNode2 * nextPtr;
};

typedef struct stackNode2 STACKNODE2;
typedef STACKNODE2 * STACKNODEPTR2;

void push2 (STACKNODEPTR2 *topPtr, int info);
int pop2 (STACKNODEPTR2 *topPtr);   
 

main()
{
    char infix[30]={0},*postfix;

    puts("Now, please enter your expression:");
    scanf("%s",infix);

        postfix=convertToPostfix (infix);
        printf("%d\n",postfix_Result(postfix));


    getch();
}

char *convertToPostfix (char *infix)
{
    STACKNODEPTR topPtr=NULL;
    int len,i,j;
    static char postfix[30]={0};
    char b;

    push(&topPtr,'(');       /*把左括号压入堆栈*/

    len=strlen(infix);
    infix[len]=')'; /*在infix的末端补右括号*/

    for(i=0,j=0;infix[i]!='\0';i++){

        if(infix[i]=='('){        /*当当前字符是左括号时,把它压入堆栈*/          
            push(&topPtr,'(');
            continue;
        }

        if(infix[i]>=49&&infix[i]<=57){   /*当字符是一个数字时,就把它传给postfix*/
            postfix[j++]=infix[i];
            if(infix[i+1]>=49&&infix[i+1]<=57)  /*如果下一个也是数字,说明非一个一位数字,于是在后面加一个','以便以后处理*/
                postfix[j++]=',';
            continue;
        }
        
        if(isOperator(infix[i])){                                                   /*当是运算符时,进行不同操作*/
            if(stackTop (topPtr)=='('||precedence(infix[i],stackTop (topPtr))==1){  /*当栈顶是左括号或者当前运算符比栈顶高*/
                push(&topPtr,infix[i]);                                              /*时,直接把当前运算符压入堆栈*/  
            }
            else{
                postfix[j++]=pop(&topPtr);  /*栈顶字传给postfix*/
                push(&topPtr,infix[i]);     /*当前字符压入堆栈*/
            }
            continue;
        }
        if(infix[i]==')'){                  /*如果是右符号,就不断弹出栈中运算符直到遇到左括号*/
            while(1){ 
                
                b=pop(&topPtr);

                if(b=='(')
                    break;                   /*如果是左括号就跳出,这样就不会把左括号赋给postfix了*/
                postfix[j++]=b;
            }
        }
    }
   
   
    return postfix;       /*返回一个字符串首地址,与书中略有不同*/
}


int isOperator (char c)   /*看是否是一个操作符*/
{
    if(c==37||c==42||c==43||c==45||c==47||c==94)
        return 1;
    else 
        return 0;
}

int precedence (char operator1,char operator2)     /*判断两个运算符谁的优先级高*/
{
     if(operator1==43||operator1==45)
         operator1=1;
     if(operator1==42||operator1==47||operator1==37)
         operator1=2;
     if(operator1==94)
         operator1=3;

     if(operator2==43||operator2==45)
         operator2=1;
     if(operator2==42||operator2==47||operator2==37)
         operator2=2;
     if(operator2==94)
         operator2=3;

     if(operator1<operator2)
         return -1;
     if(operator1==operator2)
         return 0;
     if(operator1>operator2)
         return 1;
     else
         return -9;  /*编译器出现not all control paths return a value的报文,所以在这里返回一个-9 */
}

板凳

void push (STACKNODEPTR *topPtr,char info)      /*将一个字符压入堆栈*/
{   
    STACKNODEPTR newPtr;

    newPtr=malloc(sizeof(STACKNODE));
    if(newPtr!=NULL){
        newPtr->value=info;
        newPtr->nextPtr=*topPtr;
        *topPtr=newPtr;
    }
    else
        printf("马的,没内存了!");
}

char pop (STACKNODEPTR *topPtr)     /*弹出栈顶的字符*/
{
    STACKNODEPTR tempPtr;
    char popValue;

    tempPtr=*topPtr;
    popValue=(*topPtr) ->value;
    *topPtr=(*topPtr) ->nextPtr;
    free(tempPtr);
    return popValue;
}

char stackTop (STACKNODEPTR topPtr)   /*返回栈顶的字符,但不弹出最上面的一个结构*/
{
    return topPtr->value;
}


int isEmpty (STACKNODEPTR topPtr)    /*看是否堆栈为空*/
{
    return topPtr==NULL;     /*若成立则返回1*/
}

void printStack (STACKNODEPTR topPtr)   /*打印堆栈*/
{
    if(topPtr==NULL)
        printf("List is empty.\n\n");
    else{
        printf("The list is:\n");

        while(topPtr!=NULL){
            printf("%c--->",topPtr->value);
            topPtr=topPtr->nextPtr;
        }
        printf("NULL\n\n");
    }
}



int postfix_Result(char *postfix)
{
    STACKNODEPTR2 topPtr=NULL;
    int x,y,i,j,result,n,toHigh;      /* n用来记住逗号的个数*/   
    for(i=0;postfix[i]!='\0';i++){

        if(postfix[i]>=49&&postfix[i]<=57){

            for(j=i+1,n=0;postfix[j]==',';j+=2)    /* 记下逗号的个数为n */
                ++n;
            
            for(j=0,toHigh=1;j<n;j++)    /*当是一个二位数或是三位数时,记下需乘的倍数*/
                toHigh*=10;
            
            for(result=0;n>=0;--n,i+=2,toHigh/=10)   
                result=result+(postfix[i]-48)*toHigh;    /*计算总值并存入result,并将i的值相应增加*/
                  
            
            i-=2;     /*由于上面执行了i+=2,故在此减 2 */
            push2(&topPtr,result);   /*将结果压入堆栈*/
        }
        
        else{
            x=pop2(&topPtr);
            y=pop2(&topPtr);

            switch(postfix[i]){
                case '+':
                    result=y+x;
                    break;
                case '-':
                    result=y-x;
                    break;
                case '*':
                    result=y*x;
                    break;
                case '/':
                    result=y/x;
                    break;
                case '%':
                    result=y%x;
                    break;
                case '^':
                    result=1;
                    for(i=0;i<x;i++)
                        result*=y;
                    break;
            }

            push2(&topPtr,result);
        }
    }
    return pop2(&topPtr);
}


void push2 (STACKNODEPTR2 *topPtr,int info)      /*将一个字符压入堆栈*/
{   
    STACKNODEPTR2 newPtr;

    newPtr=malloc(sizeof(STACKNODE2));
    if(newPtr!=NULL){
        newPtr->data=info;
        newPtr->nextPtr=*topPtr;
        *topPtr=newPtr;
    }
    else
        printf("乱机子,没内存了!");
}

int pop2 (STACKNODEPTR2 *topPtr)     /*弹出栈顶的数字*/
{
    STACKNODEPTR2 tempPtr;
    int popValue;

    tempPtr=*topPtr;
    popValue=(*topPtr) ->data;
    *topPtr=(*topPtr) ->nextPtr;
    free(tempPtr);
    return popValue;
}

3 楼

在自己未动脑袋之前看别人的程序是没有半点好处的,只会增长你的依赖性.

4 楼

忽然发现这个程序有个小BUG就是当最后一个数的最后一位是0的时候,这个0竟然被忽略了,你试试.

5 楼

这个太复杂了..能不能就我的题写一个呢.谢谢.我的题都用括号括起来了...

我来回复

您尚未登录,请登录后再回复。点此登录或注册