栈和队列题解

二级公共基础 - 栈、循环队列、二叉树计算题 栈、循环队列、二叉树计算题 阅读详情

NO.2:表达式求值

今天讲一道学习栈时,绕不开的一道题,就是表达式的求值问题。(反正我是非常不喜欢字符处理性的题目,因为要考虑的细节太多了……)所以我尽量讲的更细致一些,也顺便巩固一下知识点。

题目要求

背景:

我们的教材(《数据结构与算法》-清华第三版)中已经介绍了表达式求值的算法,现在我们将该算法的功能进行扩展,要求可以处理的运算符包括:+、-、*、/、%(整数取余)、^(乘方)。

要求:

采用算符优先算法,计算的中间结果只保留整数。

输入:

第一行为整数N。表示下面有N个表达式

从第二行起的后面N行为N个由整数构成的表达式

输出:

共N行,每行为相应表达式的计算结果。

如果判断出表达式有错误,则输出:error.

如果在计算过程中出现除数为0的情况,则输出:Divide 0.

然后看一下它给的输入输出用例:

测试输入期待的输出时间限制内存限制
测试用例 1以文本方式显示
  1. 4↵
  2. 2^3↵
  3. 2^0↵
  4. 2^3^2↵
  5. 2^(3-1)^(10-8)↵
以文本方式显示
  1. 8↵
  2. 1↵
  3. 512↵
  4. 16↵
1秒64M
测试用例 2以文本方式显示
  1. 11↵
  2. (2+8↵
  3. 2+8)↵
  4. 8/0↵
  5. 8/(8+5-13)↵
  6. 2^(2-5)↵
  7. 10-(80-30(/3*3+4↵
  8. 10-80-30)/3*3+4↵
  9. (2+8)(3+2)↵
  10. (2)3(8)↵
  11. 30(/3+3)+4↵
  12. 10(20-8)+2↵
以文本方式显示
  1. error.↵
  2. error.↵
  3. Divide 0.↵
  4. Divide 0.↵
  5. error.↵
  6. error.↵
  7. error.↵
  8. error.↵
  9. error.↵
  10. error.↵
  11. error.↵
1秒64M
测试用例 3以文本方式显示
  1. 2↵
  2. 10(10)↵
  3. 14*10-(10)2↵
以文本方式显示
  1. error.↵
  2. error.↵
1秒64M
测试用例 5以文本方式显示
  1. 14↵
  2. 18-32↵
  3. 18/4↵
  4. 18%3↵
  5. 10+20*4↵
  6. 10-20/4↵
  7. (18-3)*3↵
  8. 10*(10)↵
  9. (10+2)/(8-10)↵
  10. (2*3)/(5*2)↵
  11. 10-(80-30)/3*3+4↵
  12. (((2+8)*2-(2+4)/2)*2-8)*2↵
  13. (((8+2)*(4/2)))↵
  14. 10/0↵
  15. (10-80*2↵
以文本方式显示
  1. -14↵
  2. 4↵
  3. 0↵
  4. 90↵
  5. 5↵
  6. 45↵
  7. 100↵
  8. -6↵
  9. 0↵
  10. -34↵
  11. 52↵
  12. 20↵
  13. Divide 0.↵
  14. error.↵
1秒64M

解决思路

首先我们先简单过一遍用栈解决表达式求值问题的原理。先来画图模拟一下表达式求值的过程:

我们有两个栈,OPTR(运算符栈)和OPND(运算数栈)。当遍历到运算数时,直接入栈。而当遍历到运算符时,通过观察可以发现,若OPND为空或当前运算符优先级比运算符栈顶更高则直接入栈;但若当前运算符优先级低于OPND栈顶元素,则OPND(运算数栈)出栈两次,OPTR(运算符栈)出栈一次,然后将三者的元素结果入OPND,再将该运算符入OPTR。

然后我们提炼一下相关的操作,出入OPTR栈、出入OPND栈、比较得出两运算符优先级、计算一个最简单的表达式(两个数一个运算符),其中最关键的应该是如何得出两运算符之间的优先级,这里我们构建一个n阶矩阵:

简单解释一下这张表,\theta _{1} \theta _{2}分别代指先出现的符号和后出现的符号,那么当我要比较两者关系时,只需要将一组下标(i,j)对应的关系返回即可。

也就是这样:

#define Nul 0x00   /*Nul意味着不存在这两者的关系*/

char PRI[9][9]=      /* 优先级表 */ 
{ 
  {'>','>','<','<','<','<','<','>','>'}, 
  {'>','>','<','<','<','<','<','>','>'}, 
  {'>','>','>','>','<','<','<','>','>'}, 
  {'>','>','>','>','<','<','<','>','>'}, 
  {'>','>','>','>','>','<','<','>','>'}, 
  {'>','>','>','>','>','<','<','>','>'}, 
  {'<','<','<','<','<','<','<','=',Nul}, 
  {'>','>','>','>','>','>',Nul,'>','>'}, 
  {'<','<','<','<','<','<','<',Nul,'='} 
}; 

很明显这样就建立了符号与数组下标的一一对应关系:

int signswitch( char a )        /* 符号转换 */ 
{ 
   switch( a ) 
   {  case '+': return 0;   case '-': return 1; 
      case '*': return 2;   case '/': return 3; 
      case '%': return 4;   case '^': return 5; 
      case '(': return 6;   case ')': return 7; 
      case '#': return 8; 
   } 
} 

那么我将可以过找到两个运算符构成的有序数对在表中的对应值,来输出优先级:

char refusal(int i,int j){
    return PRI[i][j];
} 

// i、j就是先后出现的两个运算符通过int signswitch()转换后的数字

PS:然后这道题与教材上的例题不同的是:教材上默认表达式没有语法错误,但这道题要求考虑程序健壮性,即判断出语法错误,并且做出相关输出。 

代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<math.h> 
#define Nul 0x00 

char cur[100];        //用来预存表达式
char *p=cur;          //用来遍历表达式的指针
int operationgFlag=0;       //这个是出现除数为0的判断标记

                                            //都使用全局变量是为了方便后续操作,访问

typedef struct optr{
    char op[100];
    int top;
}OPTR;

typedef struct opnd{
    int num[100];
    int top;
}OPND;

void initoptr(OPTR *optr){         //初始化OPTR
    optr->op[0]='#';
    optr->top=1;
}

void initopnd(OPND *opnd){     //初始化OPND
    opnd->top=0;
}

void pushoptr(OPTR *optr,char a){          //OPTR入栈
    optr->op[optr->top++]=a;
}

void pushopnd(OPND *opnd,int a){        //OPND入栈

    return optr->op[--optr->top];
}

char popoptr(OPTR *optr){                      //OPTR出栈
    return optr->op[--optr->top];
}

int pooopnd(OPND *opnd){                     //OPND出栈
    return opnd->num[--opnd->top];
}

//这里是两个栈的结构体定义,以及初始化、入栈、出栈的基本操作

 然后为了方便大家理解,我就用注释的方式讲解了,大家可以一步一步的看:

//这两个子函数这里可以先不看,之后用到了再回来看

int change(){
    int b=0;
    b=b*10+*p-'0';
    p++;
    while(*p<='9'&&*p>='0'){     //直到不是数字字符
        b=b*10+*p-'0';
        p++;
    }
    return b;
}

//因为是使用字符输入的,所以一个两位数(及以上)必须是多个字符

//也就是我们要考虑多位数的情况,举个例子:2 3(一个两位数,但其实输入时,是 2 和 3 //两个字符)

//所以出现两个连续的数字字符,我们将其合并成为一个完整的数

int operation(int x, int y, char a) { 
    switch( a ) 
   { case '+': return x+y; 
     case '-': return x-y; 
     case '*': return x*y; 
     case '/': if ( y )    return x/y; 
               else { printf("Divide 0.\n"); operationgFlag=1; return 0;} 
     case '%': return ((long int) fmod(x,y)); 
     case '^': if (y>=0 )    return pow(x,y); 
              else  { printf("error.\n"); operationgFlag=1; return 0;} 
   } 
} 

//将刚才接受的两个运算数和一个运算符,传入并计算出结果

//然后当取商、取模运算的除数为0是输出错误提示

//当幂运算的指数小于0时,打印表示错误(就是默认不考虑这种情况)

下面是主函数部分: 

int main (){
	OPTR *optr=(OPTR*)malloc(sizeof(OPTR));
	OPND *opnd=(OPND*)malloc(sizeof(OPND));
	int N;                                   //N是题目中表达式的数量
	scanf("%d\n",&N);
	int flag=0;                              //flag是用来判断括号是否已经成对的标志
	int n1,n2;                               //这三个参数,后面用到的是后你会明白的
	char op;
	while(N--){
		initoptr(optr);                      //然后是初始化这些参数
		initopnd(opnd);
		flag=0;
		operationgFlag=0;                    //判断是否除数为0的标志
		scanf("%s",cur);                     //用cur接收一个表达式
		strcat(cur,"#");                     //strcat将 # 插入cur尾部
                                             //这个地方重点说明一下,大家看一下OPND的初始化
		                                     //第一位也放了一个#,这是为了与这里放入的成对
                                             //表示一个完整表达式的结束
        while(*p!='#'||optr->op[optr->top-1]!='#'){
			if(*p<='9'&&*p>='0'){                    //然后开始遍历这个表达式
				int num=change();                    //中止条件就是p到了最后一个#,或者OPTR
				pushopnd(opnd,num);                  //中没有运算符了
			}                                        //理解了的话可以去看change
			else{
				if(*p=='('&&optr->top-1==0&&opnd->top!=0){
              	printf("error.\n");                     //然后就是这几行,目的是判断表达式
              	goto h;                                 //是否有问题,我举了例子在下面
				}
              
				if ( flag==1 && *p=='(' ) { 
	                printf("error.\n"); 
	                goto h; 
	            } 
	            else if ( *p==')')   
	                flag = 1; 
	            else            
	                flag = 0; 
				switch(refusal(optr->op[optr->top-1],*p)){ //后面的逻辑就比较简单了
					case'<':pushoptr(optr,*p);p++;break;   //当前运算符优先级更高,直接入栈
					case'=':popoptr(optr);p++;break;       //这里提醒大家看下优先级表中  
					case'>':                               //只有一种情况会相等哦
						n1=pooopnd(opnd);                  //当优先级更低时
						n2=pooopnd(opnd);                  //这里就用到n1、n2、op了
						op=popoptr(optr);                  //很好理解是什么吧?
						n2=operation(n1,n2,op);   //就是用来接收出栈的两个数和一个运算符
						if(operationgFlag==1){    //然后大家理解了这里,就可以去看operation
							goto h;
						}
						else{
							pushopnd(opnd,n2);
							break;
						}
					case Nul: 
						printf("error.\n"); 
	                	goto h; 
					}
			}
		}
		if(opnd->top-1 == 0)  //数字栈中只有一个数,那就是最终结果 
            printf("%d\n",opnd->num[opnd->top]); /* 输出 */ 
        else 
           	printf("error.\n"); 
        h:; /* 继续下一个 */ 
	}
	return 0;
}

30 ( 2 + 2 )

//也就是说在出现左括号,前面没有运算符,但却有数字出现,那这个表达式就肯定是错误的

//ps没有运算符,而且没有数子不一定是错的哦,如:( 2 + 2 ) *21 是没有错误的

30 * ( 2 - 1 ) ( 2 + 1 ) 

//就是当flag还没有重置为0前又出现了左括号,这个表达式也肯定是错误的

//有人可能会有疑问 30 * ( 2 - 1 ) * ( 2 + 1 )  也错了吗?

//这当然并没有错,因为当右括号后面有别的运算符出现时,就一定会先算括号中的表达式

//那么flag就会被重置为0 

最后这个判断也很巧妙:

if(opnd->top-1 == 0)  //数字栈中只有一个数,那就是最终结果 
            printf("%d\n",opnd->num[opnd->top]); /* 输出 */ 

else 
            printf("error.\n"); 

h:; /* 继续下一个 */  

//大家可以思考一下,如果一个表达式是合法的,那么遍历结束后,OPTR(运算符栈)肯

//定就是空的了,并且OPND(运算数栈)也只会剩下一个数,那就是最终的结果

//如果OPND中还有数的话,那么这个表达式肯定就是非法的

然后我们运行一下:

给出的四个测试用例都没有问题,然后我就开心的提交了!!!

但是我真服了:

居然有一个用例没有过!!!我检查了好久(真的好久,好久……)

然后后发现了这个:

 (不出意外应该是这个有关的用例)反正我当时都崩溃了,这意味这,在判断表达式是否合法上,我之前的逻辑有一部分不能用。然后我就开始摆烂了……我直接交了。那这个就留给评论区的大家吧!!!

源代码

表达式求值

写在最后

在我这一坨……的讲解下,你居然还能看到最后,你!!!没错,就是你!!!必成大器!!!我的讲解可能确实有一些繁琐,但是那些确实是我在敲代码中的所想所感,反正真的相信“书读百遍,其意自现”,只要花时间,就能熟练掌握。就像浙大翁恺老师在他的C语言课程中说到:“所有你现在觉得很高大上的东西,只不过是你还没有学了,并不是你不会!”。

希望能与君共勉!!!

RT-Thread 5.1.0 实战:手把手教你用CubeMX和RT-Studio创建第一个工程(附常见编译错误修复) 本文详细介绍了如何使用STM32CubeMX和RT-Thread Studio 5.1.0创建第一个RT-Thread工程,包括开发环境准备、CubeMX配置、工程整合及常见编译错误修复。通过实战指南,帮助开发者快速上手RT-Thread 5.1.0,解决开发过程中的典型问题,提升嵌入式开发效率。 阅读详情

相关推荐

深度学习笔记(1)机器学习与深度学习基础

一些深度学习的简单概念和Transformer的学习。

hanliu2003的博客 1493

【数据结构】栈和队列 + 经典算法题

本文完整实现了栈和队列的数据结构,以及栈和队列的一些经典算法题,让我们更加清楚了解这两种数据结构特点,并熟悉运用。

x_p96484685433的博客 2102

高频面波成像实战:从频散曲线到全波形反演

面波勘探是近地表工程勘察的重要手段,其核心原理在于不同频率的面波对地下介质的敏感深度不同,由此形成的频散曲线能够反映浅层剪切波速结构。相较于传统钻探与折射波法,高频面波成像具有无损、高效、对低速夹层敏感等优势,广泛应用于路基检测、空洞探测、滑坡调查等领域。在实际工程中,从野外采集的排列设计、震源选型,到频散谱提取与频散曲线反演,每一步都直接影响成像精度。然而频散反演受限于一维层状假设,难以刻画横向剧烈变化的地质体。全波形反演通过拟合完整波形信息,能够突破频散曲线的分辨率边界,获得更精细的近地表速度模型。本文

weixin_29090917的博客 270

3-4 双端队列 (20分)【技巧】

3-4 双端队列 (20分) 双端队列(deque,即double-ended queue的缩写)是一种具有队列和栈性质的数据结构,即可以(也只能)在线性表的两端进行插入和删除。若以顺序存储方式实现双端队列,请编写例程实现下列操作:

WR的博客 910

干扰管理学习日志4-------信道估计方法 LS(最小二乘)、MMSE(最小均方误差)

信道估计,就是从接收数据中将假定的某个信道模型的模型参数估计出来的过程。如果信道是线性的话,那么信道估计就是对系统冲激响应进行估计。需强调的是信道估计是信道对输入信号影响的一种数学表示,而“好”的信道估计则是使得某种估计误差最小化的估计算法。本文主要讲述非盲信道估计中的LS估计和MMSE估计。LS全称为,即估计的信道参数与实际信道参数的差,进行平方求和后得到的误差累积最小。MMSE估计是LS估计的改进,在LS估计的最终结果的基础上乘以加权矩阵,使之与实际信道参数更为接近。

taiyuezyh的博客 1万+

什么是plm系统?-数字化转型网

当今世界,产品研发能力是企业在激烈的市场竞争中保持战略优势的核心竞争力之一。如何有效地缩短产品研发周期、改善产品服务的设计迭代流程、有效降低产品的研发成本,也是企业面临的主要问题之一。PLM(Product Lifecycle Management,产品生命周期管理)在优化产品研发的全管理流程、增强企业产品的市场竞争力方面具有关键的作用。

cxo17757154043的博客 883

栈与队列——图示分析+习题应用!

栈与队列在数据结构中占据很重要的地位,在今天的学习中我们要初步掌握栈与队列的基本性质以及相关的容器操作,除此之外大家也要对栈与队列的底层实现多加了解。

wyr1849089774的博客 496

如何用Arduino和HX711压力传感器制作一个简易电子秤(含OLED显示)

本文详细介绍了如何使用Arduino、HX711压力传感器和OLED显示屏制作一个简易电子秤。从硬件连接到软件编程,提供了分步教程,包括核心元件功能解析、接线方法、库安装、模块测试以及关键的校准流程。项目实践性强,适合创客和DIY爱好者学习嵌入式系统与传感器应用。

tea88的博客 536

陪女朋友学习计算机二级之栈和队列

队列是一种线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作,和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除操作的端称为队头.队列的数据元素又称为队列元素​。

weixin_68929783的博客 1035

PBR:双向反射分布函数(BRDF)介绍与Cook-Torrance模型的实现

PBR:双向反射分布函数(BRDF)介绍与Cook-Torrance模型的实现 BRDF简介 再介绍BRDF之前我们要引入渲染方程这个东西: 其中L表示辐射率,其公式为: 它表示了一个拥有辐射强度Φ的光源在单位面积A,单位立体角ω上的辐射出的总能量。 辐射率是辐射度量学上表示一个区域平面上光线总量的物理量,它受到入射光线与平面法线间的夹角θ的余弦值cosθ的影响:当直接...

小龙虾的博客 1万+

Claude Code 任务编排 头脑风暴与 疯狂拷问:Superpowers vs Grill-me 硬核对比与工程落地

Superpowers和Grill-me是AI编程中的互补工具:Superpowers提供工程化开发流程(从需求梳理到代码审查),确保规范执行;Grill-me通过持续追问帮助厘清需求,避免方向偏差。两者结合形成"构思-拷问-执行"工作流,前者负责方案生成与落地,后者专注需求审查。根据场景选择:个人项目可用Grill-me快速澄清需求,企业项目推荐Superpowers全流程,复杂开发则建议组合使用。它们分别解决"如何落地"和"是否对齐"的问题,共

十年老程序猿,AI 疯狂研究专家,前沿硬核知识分享 327

栈和队列经典题题解

栈和队列的经典题解

黄超的博客 890

Linux驱动学习--HCI框架及源码分析

目录 一、引言 二、HCI框架 三、pcm_read简要分析 一、引言 最近一直在分析蓝牙驱动,发现在底层驱动与上层协议栈间还有一层HCI,主机控制层,两者之间通过HCI协议通讯 而Linux也将HCI协议抽象层了一个框架。 为上层提供一个统一的接口,让上层协议不依赖于具体硬件的实现。HCI在硬件中的固件与HCI在主机端的驱动通信方式有多种,比如像 UART、USB和PC Card等等。hci_core.c相当于一个框架,用于把各种具体通信方式绞合起来,并提供一些公共函数的实现。 今天就来简单的分析一下 二

文艺小少年的博客 2003

LeetCode题解——栈和队列

文章目录用栈实现队列解法用队列实现栈解法最小栈解法有效的括号解法每日温度解法下一个更大元素 II解法推荐阅读 用栈实现队列 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部。 pop() -- 从队列首部移除元素。 peek() -- 返回队列首部的元素。 empty() -- 返回队列是否为空。   示例: MyQueue queue = new MyQueue(); queue.push(1); queue.push(2); queue.peek(); /

wardseptember的博客 589

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Leetcode 题解 - 栈和队列

用栈实现队列 232. Implement Queue using Stacks (Easy) 栈的顺序为后进先出,而队列的顺序为先进先出。使用两个栈实现队列,一个元素需要经过两个栈才能出队列,在经过第一个栈时元素顺序被反转,经过第二个栈时再次被反转,此时就是先进先出顺序。 class MyQueue { private Stack<Integer> in = new Stack<>(); private Stack<Integer> out = new

Cybenko 207

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

leetcode中的有关链表和栈与队列知识的简单题解

本题只需要判断是否存在喜欢栈顶甜点的学生是否存在。

2401_87978007的博客 247

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

剑指Offer题解——栈和队列

文章目录剑指 Offer 09. 用两个栈实现队列解法剑指 Offer 30. 包含min函数的栈解法剑指 Offer 59 - I. 滑动窗口的最大值双端队列剑指 Offer 59 - II. 队列的最大值解法剑指 Offer 11. 旋转数组的最小数字二分查找推荐阅读 剑指 Offer 09. 用两个栈实现队列 剑指 Offer 09. 用两个栈实现队列 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除

wardseptember的博客 551

Leetcode题解-算法-栈和队列

文章目录1、用栈实现队列 1、用栈实现队列 232. Implement Queue using Stacks(Easy) Implement the following operations of a queue using stacks. push(x) – Push element x to the back of queue. pop() – Removes the element fr...

桑凯旋的博客 512

【题解】数组和链表分别实现栈与队列

int *data;// 动态数组// 总容量int top;// 栈顶指针(-1表示空)data:指向动态分配的整型数组,用于实际存储栈中元素。capacity:当前栈能容纳的最大元素个数。top:栈顶索引。初始为-1表示栈为空;当有元素入栈后,top指向最新压入的元素下标。栈的特点:后进先出(LIFO)。所有操作都在栈顶进行。int data;} Node;Node *top;// 栈顶指针Node:链表节点,包含数据data和指向下一个节点的指针next。

2502_93869639的博客 1110

【数据结构】栈和队列题目的简单题解

本文介绍了经典算法问题: 用栈实现队列:通过两个栈(输入栈和输出栈)模拟队列操作,入队时压入输入栈,出队时从输出栈弹出,若输出栈为空则将输入栈元素全部转移,确保先进先出特性。 用队列实现栈:利用队列的先进先出特性,通过反复出队入队操作模拟栈的后进先出,出栈时将队列前n-1个元素重新入队,保留最后一个元素出队。 有效的括号:使用栈结构检查括号匹配,遇到左括号入栈,右括号时检查栈顶是否匹配,最终栈为空则有效,否则无效。 每种问题均通过特定的数据结构转换实现功能,核心在于理解并巧妙利用栈和队列的特性差异

2401_87853595的博客 586

栈和队列训练赛题解

高考的大伙,不要忘了提防题目里十分欧内的陷阱,以好汉的态度细心手写出满意的答卷。不要让身心状态被阿黑路西干扰,一定要保持一得格拉米的心境,多多奥利安费,祝大家都能all in!​

Tanya_xiaomai的博客 1325
上一篇: 程序设计方法与实践-减治法
下一篇: 线性表题解
小陈又菜
博客等级 码龄3年 680粉丝 102原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值