530876864 发表于 2015-3-8 13:02:42

强烈支持楼主ing……

demonzjf 发表于 2015-3-20 15:44:13

激动人心,无法言表! 跪舔圣天玄武大帝,西风发财红中战神。才华横溢,帅到掉渣的小甲鱼大神。

demonzjf 发表于 2015-3-20 15:45:53

demonzjf 发表于 2015-3-20 15:44
激动人心,无法言表! 跪舔圣天玄武大帝,西风发财红中战神。才华横溢,帅到掉渣的小甲鱼大神。

鱼币不够怎么办。

鱼儿爱学习 发表于 2015-5-18 14:14:20

shi_xin398 发表于 2013-9-16 13:55
小甲鱼 不知道你能不能看到我的回复
你的程序有问题
当输入2*3/4


乘除的优先级是一样的吧

鱼儿爱学习 发表于 2015-5-18 14:16:13

小甲鱼老师,这个鱼币怎么赚到呀?没有鱼币的童鞋好伤心啊

2413780002 发表于 2015-5-21 13:41:15

强烈支持楼主ing……

妖龙腾空 发表于 2015-7-9 17:34:54

真贵,想看和上一章合在一起的代码

18983422070 发表于 2016-1-21 16:48:09

。。。。。。。。。。。

fzquchs 发表于 2016-2-28 01:28:14

蜗牛般的速度慢慢前行着,真痛苦!!!

小猪发飙 发表于 2016-6-16 12:36:52

加油

liyuanjun 发表于 2016-7-25 21:10:46

小甲鱼,你在这一讲的视频里说会把完整的源代码放在论坛里,可是这个代码还只是你视频里讲的那些啊! 能不能把中缀表达式变成后缀表达式,然后再计算出来的代码分享一下,我水平比较低,谢谢了

yinjia哈哈 发表于 2016-9-19 22:25:43

好贵啊

yinjia哈哈 发表于 2016-9-20 15:40:01

有没有两个程序合并的啊

天下无敌小萨萨 发表于 2016-10-4 19:39:07

求合并的代码{:10_266:}

ai1361720220000 发表于 2017-1-5 11:43:42

小甲鱼,你程序中当乘除或者左括号直接进栈,那么就会有一个问题,如果栈里面本来就有一个*或者/,不应该也要把之前那个*和/输出吗?比如说,输入2*2*2 你的程序结果就会是2 2 2 * *,但是不应该是2 2 * 2 *吗?
对于2+2+2,结果是2 2 + 2 +,这和程序结果一样,是因为程序中有输出栈里之前优先级高的。我觉得在乘除那边应该也要这么做吧?~

sevennight1989 发表于 2017-1-28 19:22:43

学习中,我的代码调试老是出问题

WorlD_HellO 发表于 2017-5-21 12:42:10

哪里有一次下完所有课程视频和代码的压缩包

yzw 发表于 2017-5-27 20:16:06

本帖最后由 yzw 于 2017-5-27 20:17 编辑

不是说有合并之后的代码吗,怎么没有啊!

创建 和 计算 逆波兰式子的函数用到的结构体不一样啊,一个用double型、一个用char型
难道我要定义两个结构体,写两个Pop 两个Push 两个InitStack 两个 StackLen吗?求解答。

今天就是因为一直想不明白这点才决定买VIP下载代码看看的,结果发现没有这个代码{:10_245:}

秋名山老司机 发表于 2017-8-4 19:29:38


这个是头文件的内容:

//栈操作基本表达式运算头文件
//创建人:mingming
//创建时间:2017.8.4
//最后修改时间:2017.8.4


#ifndef CACULATE_H
#define CACULATE_H

typedef double ElemType;       //数字栈空间元素类型
typedef char   ElemType2;      //运算符栈空间元素类型
#define MAX_INIT_SIZE 20       //初始化的栈空间
#define NEW_SIZE 10                           //每次新增的栈空间
#define MAX_BUFFER 10          //数字识别的缓冲区

//定义一个栈
typedef struct
{
        ElemType *base;
        ElemType *top;
        int StackSize;
} sqStack;

bool InitStack(sqStack *s)
{
        s->base = new ElemType;
        if(!s->base)
                return false;
        s->top = s->base;
        s->StackSize = MAX_INIT_SIZE;
        return true;
}

bool push(sqStack *s , ElemType e)
{
        if((s->top - s->base) >= s->StackSize)
        {
                s->base = (ElemType *)realloc(s->base , ( NEW_SIZE + s->StackSize )* sizeof( ElemType ));
                if( !s->base )
                        return false;
                s->top = s->base + s->StackSize;
                s->StackSize += NEW_SIZE;
        }

        *(s->top) = e;
        s->top++;
        return true;
}

bool pop(sqStack *s ,ElemType *e)
{
        if(s->top == s->base)
                return false;
        s->top--;
        *e = *s->top;
        return true;
}
//求栈当前长度
int StackLen(sqStack s)
{
        return ( s.top - s.base );
}


//对上面的各个方法进行重载
typedef struct
{
        ElemType2 *base;
        ElemType2 *top;
        int StackSize;
} midStack;

bool InitStack(midStack *s)
{
        s->base = new ElemType2;
        if(!s->base)
                return false;
        s->top = s->base;
        s->StackSize = MAX_INIT_SIZE;
        return true;
}

bool push(midStack *s , ElemType2 e)
{
        if((s->top - s->base) >= s->StackSize)
        {
                s->base = (ElemType2 *)realloc(s->base , ( NEW_SIZE + s->StackSize )* sizeof( ElemType2 ));
                if( !s->base )
                        return false;
                s->top = s->base + s->StackSize;
                s->StackSize += NEW_SIZE;
        }

        *(s->top) = e;
        s->top++;
        return true;
}

bool pop(midStack *s ,ElemType2 *e)
{
        if(s->top == s->base)
                return false;
        s->top--;
        *e = *s->top;
        return true;
}
//求栈当前长度
int StackLen(midStack s)
{
        return ( s.top - s.base );
}

#endif

这个是cpp文件的内容,用的时候要包含上面头文件
#include<iostream>
#include<ctype.h>
#include"Caculate.h"

#define MAXBUFFER 50//存放后缀表达式的最大缓冲区长度


//中缀表达式转换为后缀表达式
void MidtoLast(char *lastbuf)
{
        std::cout << "请输入表达式!以#作为结束标志\n";
        midStack stack;
        InitStack(&stack);   //操作符的栈初始化

        int i=0;
        char c;
        char temp;
        std::cin.get(c);
        while( '#' != c )       //输入以#作为结束符
        {
                if( isdigit(c) || c=='.' )         //对读取到的数字处理,使得数字放在一起,并且一个数字后面有一个空格
                {
                        while(isdigit(c) || c=='.')
                        {
                                lastbuf = c;
                                lastbuf = ' ';
                                std::cin.get(c);   
                        }
                                i++;                         //保护一个数字完了之后的空格不变
                }
               
                switch( c )
                {
                        case '+':                        // + 只要前面有非括号运算符,就应该先出栈
                                if(stack.top == stack.base)
                                {
                                        push( &stack , c );
                                }
                                else
                                {
                                        do
                                        {
                                                pop( &stack , &temp );
                                                if( '(' == temp )
                                                {
                                                        push( &stack , temp );
                                                }
                                                else
                                                {
                                                        lastbuf = temp;
                                                        lastbuf = ' ';
                                                }
                                        }while( '(' != temp && StackLen(stack));
                                        push( &stack , c );
                                }
                                break;
                        case '-':                     //- 只要前面有非括号运算符,就应该先出栈
                                if(stack.top == stack.base)
                                {
                                        push( &stack , c );
                                }
                                else
                                {
                                        do
                                        {
                                                pop( &stack , &temp );
                                                if( '(' == temp )
                                                {
                                                        push( &stack , temp );
                                                }
                                                else
                                                {
                                                        lastbuf = temp;
                                                        lastbuf = ' ';
                                                }
                                        }while( '(' != temp && StackLen(stack));
                                        push( &stack , c );
                                }
                                break;
                        case '*':                           //   * / 需要那顺序计算,谁在先,先算谁
                                if(stack.top == stack.base)
                                {
                                        push( &stack , c );
                                }
                                else
                                {
                                        pop( &stack , &temp );
                                        if( '*'==temp || '/'==temp)
                                        {
                                                lastbuf = temp;
                                                lastbuf = ' ';
                                        }
                                        else
                                        {
                                                push( &stack , temp );
                                        }
                                                push( &stack , c );
                                }
                                break;
                        case '/':                  //   * / 需要那顺序计算,谁在先,先算谁
                                if(stack.top == stack.base)
                                {
                                        push( &stack , c );
                                }
                                else
                                {
                                        pop( &stack , &temp );
                                        if( '*'==temp || '/'==temp)
                                        {
                                                lastbuf = temp;
                                                lastbuf = ' ';
                                        }
                                        else
                                        {
                                                push( &stack , temp );
                                        }
                                                push( &stack , c );
                                }
                                break;
                        case '(':
                                push(&stack , c);
                                break;
                        case ')':       //括号配对,知道碰见左括号
                                pop( &stack , &temp );
                                while( '(' != temp )
                                {
                                        lastbuf = temp;
                                        lastbuf = ' ';
                                        pop( &stack , &temp );
                                }
                                break;
                }
                if( '#' != c)   // 如果前面数字处理时已经读到了#,就不需要再读了
                {
                        std::cin.get(c);
                }
               
        }
        while( stack.top != stack.base )    //把栈里面没有用到的符号全部弹出来
        {
                pop( &stack , &lastbuf );
                lastbuf = ' ';
        }
        lastbuf = '\0';       //数组最后的结束符,防止内存泄漏
}

ElemType caculate(char *lastbuf)
{
        sqStack s;
        InitStack( &s );
        int i = 0,bufcount=0;
        double d,e;

       
        char c , str;
        c = lastbuf;

        while(c != '\0')
        {
                while( isdigit(c) || c=='.')          //数字处理,把连续的数字转换为一个double型
                {
                        str = c;
                        str = '\0';
                        if( i>=10 )
                        {
                                std::cout << "输入的数字位数过多!\n";
                        }
                        c = lastbuf;
                        if(' '== c )         // 碰见空格说明一个数字完了
                        {
                                d = atof(str);
                                push( &s , d );
                                i = 0;
                                break;
                        }
                }

                switch( c )
                {
                        case '+':
                                pop( &s , &e );
                                pop( &s , &d);
                                push(&s , d+e);
                                break;
                        case '-':
                                pop( &s , &e );
                                pop( &s , &d );
                                push(&s , d-e);
                                break;
                        case '*':
                                pop( &s , &e );
                                pop( &s , &d );
                                push(&s , d*e);
                                break;
                        case '/':
                                pop( &s , &e );
                                pop( &s , &d );
                                if( e != 0 )
                                {
                                        push(&s , d/e);
                                }
                                else
                                {
                                        std::cout << "除数为0,错误!\n";
                                        return -1;
                                }
                                break;
                }
                c = lastbuf;
        }
        pop(&s , &d);      //最终计算结果弹出到 d 中   
        return d;
}


int main()
{
        char lastbuf; //后缀表达式缓冲区

        MidtoLast(lastbuf);   //中缀转后缀
       
        std::cout << "运算结果为" << caculate(lastbuf) << std::endl;

        return 0;
}

还有注意一下,甲鱼老师的中缀转换后缀有些问题,加减法 或者 乘除法 需要按照顺序求,就是说需要先判断站定是否有相同优先级或高优先级的运算符,如果有,就要先出栈,然后再进行压栈操作!

秋名山老司机 发表于 2017-8-4 19:31:09

yzw 发表于 2017-5-27 20:16
不是说有合并之后的代码吗,怎么没有啊!

创建 和 计算 逆波兰式子的函数用到的结构体不一样啊,一个用d ...

对的,需要两个栈,可以看我在下面发的代码 !
页: 1 [2] 3
查看完整版本: 第二十八讲 栈和队列6(视频+课件+源代码)