鱼C论坛

 找回密码
 立即注册
楼主: 小甲鱼

第二十八讲 栈和队列6(视频+课件+源代码)

[复制链接]
发表于 2015-3-8 13:02:42 | 显示全部楼层
强烈支持楼主ing……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-3-20 15:44:13 | 显示全部楼层
激动人心,无法言表! 跪舔圣天玄武大帝,西风发财红中战神。才华横溢,帅到掉渣的小甲鱼大神。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

鱼币不够怎么办。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-18 14:14:20 | 显示全部楼层
shi_xin398 发表于 2013-9-16 13:55
小甲鱼 不知道你能不能看到我的回复
你的程序有问题
当输入2*3/4

乘除的优先级是一样的吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-18 14:16:13 | 显示全部楼层
小甲鱼老师,这个鱼币怎么赚到呀?没有鱼币的童鞋好伤心啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-21 13:41:15 | 显示全部楼层
强烈支持楼主ing……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-7-9 17:34:54 | 显示全部楼层
真贵,想看和上一章合在一起的代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-21 16:48:09 | 显示全部楼层
。。。。。。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-2-28 01:28:14 | 显示全部楼层
蜗牛般的速度慢慢前行着,真痛苦!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-6-16 12:36:52 | 显示全部楼层
加油
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-7-25 21:10:46 | 显示全部楼层
小甲鱼,你在这一讲的视频里说会把完整的源代码放在论坛里,可是这个代码还只是你视频里讲的那些啊! 能不能把中缀表达式变成后缀表达式,然后再计算出来的代码分享一下,我水平比较低,谢谢了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-19 22:25:43 | 显示全部楼层
好贵啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-20 15:40:01 | 显示全部楼层
有没有两个程序合并的啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-4 19:39:07 | 显示全部楼层
求合并的代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-5 11:43:42 | 显示全部楼层
小甲鱼,你程序中当乘除或者左括号直接进栈,那么就会有一个问题,如果栈里面本来就有一个*或者/,不应该也要把之前那个*和/输出吗?比如说,输入2*2*2 你的程序结果就会是2 2 2 * *,但是不应该是2 2 * 2 *吗?
对于2+2+2,结果是2 2 + 2 +,这和程序结果一样,是因为程序中有输出栈里之前优先级高的。我觉得在乘除那边应该也要这么做吧?~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-28 19:22:43 | 显示全部楼层
学习中,我的代码调试老是出问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-21 12:42:10 | 显示全部楼层
哪里有一次下完所有课程视频和代码的压缩包
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-27 20:16:06 | 显示全部楼层
本帖最后由 yzw 于 2017-5-27 20:17 编辑

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

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

今天就是因为一直想不明白这点才决定买VIP下载代码看看的,结果发现没有这个代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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[MAX_INIT_SIZE];
        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[MAX_INIT_SIZE];
        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[i++] = c;
                                lastbuf[i] = ' ';
                                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[i++] = temp;
                                                        lastbuf[i++] = ' ';
                                                }
                                        }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[i++] = temp;
                                                        lastbuf[i++] = ' ';
                                                }
                                        }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[i++] = temp;
                                                lastbuf[i++] = ' ';
                                        }
                                        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[i++] = temp;
                                                lastbuf[i++] = ' ';
                                        }
                                        else
                                        {
                                                push( &stack , temp );
                                        }
                                                push( &stack , c );
                                }
                                break;
                        case '(':
                                push(&stack , c);
                                break;
                        case ')':       //括号配对,知道碰见左括号
                                pop( &stack , &temp );
                                while( '(' != temp )
                                {
                                        lastbuf[i++] = temp;
                                        lastbuf[i++] = ' ';
                                        pop( &stack , &temp );
                                }
                                break;
                }
                if( '#' != c)     // 如果前面数字处理时已经读到了#,就不需要再读了
                {
                        std::cin.get(c);
                }
                
        }
        while( stack.top != stack.base )    //把栈里面没有用到的符号全部弹出来
        {
                pop( &stack , &lastbuf[i++] );
                lastbuf[i++] = ' ';
        }
        lastbuf[i] = '\0';       //数组最后的结束符,防止内存泄漏
}

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

        
        char c , str[MAX_BUFFER];
        c = lastbuf[bufcount++];

        while(c != '\0')
        {
                while( isdigit(c) || c=='.')          //数字处理,把连续的数字转换为一个double型
                {
                        str[i++] = c;
                        str[i] = '\0';
                        if( i>=10 )
                        {
                                std::cout << "输入的数字位数过多!\n";
                        }
                        c = lastbuf[bufcount++];
                        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[bufcount++];  
        }
        pop(&s , &d);      //最终计算结果弹出到 d 中   
        return d;
}


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

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

        return 0;
}

还有注意一下,甲鱼老师的中缀转换后缀有些问题,加减法 或者 乘除法 需要按照顺序求,就是说需要先判断站定是否有相同优先级或高优先级的运算符,如果有,就要先出栈,然后再进行压栈操作!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

发表于 2017-8-4 19:31:09 | 显示全部楼层
yzw 发表于 2017-5-27 20:16
不是说有合并之后的代码吗,怎么没有啊!

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

对的,需要两个栈,可以看我在下面发的代码 !
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-21 19:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表