【数据结构入门精讲 | 第五篇】栈知识点及考研408、企业面试练习

实验四顺序栈的实现 实验4:栈和队列的基本操作实现及其应用 一、实验目的 1、 熟练掌栈和队列的结构特点,掌握栈和队列的顺序存储和链式存储结构和实现。 2、 学会使用栈和队列解决实际问题。 二、实验内容 1、 自己确定结点的具体数据类型和问题规模: 分别建立一个顺序栈和链栈,实现栈的压栈和出栈操作。 分别建立一个顺序队列和链队列,实现队列的入队和出队操作。 2、 设计算法并写出代码,实现一个十将二进制 阅读详情

在上一篇中我们进行了表的专项练习,在这篇文章中我们将介绍栈的相关知识点。

在这里插入图片描述

基础概念

栈是限定仅在栈顶(即表首)进行插入和删除操作的线性表,也称为后进先出(Last In First Out) 的线性表,简称 LIFO 结构。

栈的内部实现原理其实就是数组或链表的操作,而之所以引入 栈 这个概念,是为了将程序设计问题模型化,利用栈的先进后出特性对特定的一些问题进行简化。(栈是线性表的特例)

允许插入和删除元素的一端称为栈顶,另一端称为栈底,不含任何任何数据元素的栈称为空栈。

在这里插入图片描述

顺序栈

当使用线性表的顺序存储结构(即数组)实现栈时,该栈被称为顺序栈

伪代码

//创建一个容量为size的空栈
Stack StackInit(int size)
{ Stack S=malloc(sizeof *S);
S->data=malloc(size *sizeof(StackItem));
S->maxtop=size-1;
S->top=-1;
return S;
}



//判断栈空StackEmpty(S)
int StackEmpty (Stack S) 
{return S->top<0;}//top=-1时为空栈



// 判断栈满StackFull(S)
int StackFull (Stack S) 
{return S->top==S->maxtop;}//top==maxtop时为满栈



//释放空间StackFree(S)
int StackFree (Stack S) {free(S->data); free(S);}



//返回栈顶元素StackItem StackTop(Stack S)
{ if (StackEmpty(S)) Error("Stack is empty");
else
return S->data[S->top]; //直接返回栈顶top元素即可
}



//入栈操作push(x,S)
void Push (StackItem x, Stack S)
{ if (StackFull(S)) Error("Stack is full");
else S->data[++S->top]=x;}//前置自加
//x为新的栈顶元素,存放在插⼊前的top+1单元



//出栈操作Pop(S)
void Pop (Stack S)
{ if (StackEmpty(S)) Error("Stack is empty ");
else return S->data[S->top--];}//后置自减
//删除栈顶元素x后,新的栈顶位置为删除前的top-1单元

注意点:当使用数组存储栈的时候,设数组大小为M,当栈为空时,栈顶指针值为-1,当栈满时,栈顶指针为M-1。若此时入栈,则上溢(overflow)

链栈

当使用线性表的链式存储结构(单链表)实现栈时,该栈被称为链栈。为维护堆栈的FILO的存储特性,链栈中维护的top指针始终指向栈顶元素。

伪代码

//空栈的创建
Stack StackInit()
{ Stack S=malloc(sizeof *S);
S->top=0;//将top置为空指针,创建一个空栈
return S;
}//o(1)

//检查是否空栈StackEmpty(S)
int StackEmpty (Stack S)
{//检测top是否为空指针
return S->top==0;
}

//返回栈顶元素
StackItem StackTop(Stack S)
{
if (StackEmpty(S))
Error("Stack is empty");
else return S->top->element;
}

//插入元素
void Push(StackItem x, Stack S)
{ slink p;
if (StackFull(S)) Error("Stack is Full");
p=NewStackNode();//为元素x创建一个新结点
p->element=x;
p->next=S->top;//修改栈顶结点指针top
S->top=p;//新结点成为新的栈顶指针top
}

//删除元素
StackItem Pop(Stack S)
{ slink p; StackItem x;
if (StackEmpty(S)) Error("Stack is empty");
x=S->top->element;//将栈顶指针top所指元素放入x中
p=S->top;
S->top=p->next;//修改栈顶指针使其指向栈顶元素的下一个结点
free(p);
return x;
}

顺序栈与链栈的异同点:顺序栈和链栈的时间复杂度均为O(1)
为了使每个栈在算法运行过程中不会溢出,通常要为每个栈预置一个较大的栈空间,但它的优势是存取时定位很方便。

链栈要求每个元素都要配套一个指向下个结点的指针域,增大了内存开销,但好处是栈的长度无限,因此,如果栈的使用过程中元素变化不可预料,有时很小,有时很大,那么最好使用链栈。反之,如果它的变化在可控范围内,则建议使用顺序栈。

接下来让我们进行栈的相关练习。

判断题

1.若一个栈的输入序列为1,2,3,…,N,输出序列的第一个元素是i,则第j个输出元素是j−i−1。(错)

解析:不确定,如果输出的第一个是1,则第二个可以是任何数。

2.栈结构不会出现溢出现象。(错)

链式存储的栈结构不会溢出,但顺序存储的栈结构会溢出,因为它一开始就定义了栈的长度。

3.若一个栈的输入序列为{1, 2, 3, 4, 5},则不可能得到{3, 4, 1, 2, 5}这样的出栈序列。(对)

结合题目且1比2先入栈,所以出栈的顺序肯定是2在1前面,所以不可能得到{3, 4, 1, 2, 5}

4.两个栈共享一片连续空间,可以将两个栈的栈底分别设在这片空间的两端。(对)

选择题

1.若采用带头、尾指针的单向链表表示一个堆栈,那么该堆栈的栈顶指针top应该如何设置?
A.随便哪端作为top都可以
B.链表头、尾都不适合作为top
C.将链表头设为top
D.将链表尾设为top
选C,解析:栈顶为表首,即链表头。

2.给定有限符号集 S , in 和 out 均为 S 中所有元素的任意排列。 对于初始为空的栈 ST, 下列叙述中,正确的是:(选A)
A.若 in 是 ST 的入栈序列,out 是对应 in 的出栈序列, 则 in 与 out 可能互为倒序
B.若 out 是 ST 的出栈序列,则不能判断 in 是否为其可能的入栈序列
C.若 in 是 ST 的入栈序列,out 是对应 in 的出栈序列, 则 in 与 out 一定不同
D.若 in 是 ST 的入栈序列, 则不能判断 out 是否为其可能的出栈序列

3.将5个字母ooops按此顺序入栈,则有多少种不同的出栈顺序可以仍然得到ooops?(选A)
A.5
B.3
C.1
D.6

解析:

  1. o1进o1出、o2进o2出、o3进o3出
  2. o1进o2进、o2出o1出、o3进o3出
  3. o1进o2进、o2出o3进、o3出o1出
  4. o1、o2、o3进,o3、o2、o1出
  5. o1进o1出、o2进o3进、o3出o2出
4.下列关于栈的叙述中,错误的是:

1. 采用非递归方式重写递归程序时必须使用栈
2. 函数调用时,系统要用栈保存必要的信息
3. 只要确定了入栈次序,即可确定出栈次序
4. 栈是一种受限的线性表,允许在其两端进行操作

解析:计算斐波拉契数列迭代实现只需要一个循环即可实现,故1错
2对。3错,不做过多解释。4错,栈是一种受限的线性表,只允许在一端进行操作。

5.若一个栈的入栈序列为1、2、3、…、N,其输出序列为p1、p2、p3、…、pN。若p1=N,则pi为:()
解析:栈的特点是后进先出,入栈序列是 1,2,3,…,n,输出对应的应该是 n,n-1,n-2,…,1,所以答案是 n - i + 1。

6.给定一个堆栈的入栈序列为{ 1, 2, ⋯, n },出栈序列为{ p1, p2, ⋯, pn }。如果p2=n,则存在多少种不同的出栈序列?
解析:在n出栈之前,前n-1个元素都可以第一个出栈,所以答案为n-1。

7.若元素a、b、c、d、e、f依次进栈,允许进栈、退栈操作交替进行,但不允许连续三次进行退栈工作,则不可能得到的出栈序列是?(D)
A.c b d a e f
B.b c a e f d
C.d c e b f a
D.a f e d c b
解析: 假设选项成立,推得其操作即可。

8.在作进栈运算时,应先判别栈是否(① );在作退栈运算时应先判别栈是否(② )。当栈中元素为n个,作进栈运算时发生上溢,则说明该栈的最大容量为(③ )。
①: A. 空 B. 满 C. 上溢 D. 下溢
②: A. 空 B. 满 C. 上溢 D. 下溢
③: A. n-1 B. n C. n+1 D. n/2
A. ① B ② A ③ A
B. ① C ② D ③ B
C. ① B ② A ③ B
D. ① B ② B ③ A
答案选C,解析:在作进栈运算时,应先判别栈是否满。在作退栈运算时应先判别栈是否空。当栈中元素为n个,作进栈运算时发生上溢,则说明该栈的最大容量为n。

9.若一个栈的入栈序列为1、2、3、…、N,输出序列的第一个元素是i,则第j个输出元素是:
A.不确定
B.i−j
C.i−j−1
D.j−i−1
选A,解析:i如果是1,则第j个输出的元素可以是2~N任何一个。

10.设一个堆栈的入栈顺序是1、2、3、4、5。若第一个出栈的元素是4,则最后一个出栈的元素必定是:
A.3
B.1或者5
C.5
D.1
选B,解析:第一个出栈的元素是4,说明这时候5还没入栈,所以下一步可能是入栈或者出栈。

11.检查表达式中的括号是否匹配的问题需要借助________来解决。
A.有向无环图
B.队列
C.二叉搜索树
D.堆栈
选D,解析:具体解析可看后面的编程题。

12.若借助堆栈将中缀表达式a+b*c+(d*e+f)*g转换为后缀表达式,当读入f时,堆栈里的内容是什么(按堆栈自底向上顺序)?
A.+(*+
B.abcde
C.++(+
D.+(+

  • 当输入的是操作数时,直接输出a;

  • 遇到操作符,如果栈为空入栈,+入栈

  • 当输入的是操作数时,直接输出b;

  • 栈顶元素+的优先级小于*的优先级,* 压栈;

  • 当输入的是操作数时,直接输出c;

  • 当输入的是运算符,栈顶元素*的优先级大于+的优先级,* 出栈;循环,栈顶元素+的优先级等于+的优先级,+ 出栈,+入栈;

  • 当输入的是开括号时,把它压栈;

  • 当输入的是操作数时,直接输出d;

  • 当输入的是运算符,因为栈顶是开括号,* 压栈;

  • 当输入的是操作数时,直接输出e;

  • 当输入的是运算符,栈顶元素*的优先级大于+的优先级,* 出栈;+入栈;

当输入的是f停止,此时栈中+(+

总而言之

如果在外面的符号比栈顶符号优先级要高,则入栈
如果外面的小于等于栈顶的,则栈顶出栈;接着再把这个外面的和第二个栈元素比较

13.设有一顺序栈S,元素s1,s2,s3,s4,s5,s6依次进栈,如果6个元素出栈的顺序是s2,s3,s4, s6 , s5,s1,则栈的容量至少应该是( )。
A.3
B.5
C.6
D.2
选A,解析:首先给一个容量让1进,再给一个容量让2进,2出,3进,此时3占有的是第二个容量,3出,4进,此时4占有的是第二个容量,4出,5进,此时5占有的是第二个容量,再给一个容量让6进,此时6占有的是第三个容量,然后依次出栈。所以栈的容量至少是3个。

14.利用大小为n的数组(下标从0到n-1)存储一个栈时,假定栈从数组另一头开始且top==n表示栈空,则向这个栈插入一个元素时,修改top指针应当执行:
A.top–
B.top不变
C.top=0
D.top++
选A,解析:插入元素时,栈的top指针应上移,而该栈存储在数组中,故top的表现形式为top–。

15.元素A,B,C,D依次入栈,出栈无限制,则以下( )是可能的出栈序列。
A. C, A, B, D
B. B, D, A, C
C. A, D, B, C
D. B, A, D, C
选D,解析:对于A,如果C第一个出栈,则A的出栈顺序应该在B后;对于B,如果B,D先后出栈,则说明A的出栈次序应该在C后;对C,如果D在第二个出栈,则说明B的出栈次序应该在C后;D正确。

16.与数据存储结构无关的概念是
A.栈 B.链表 C.顺序表 D.二叉链表
选A,栈可以数组实现也可以链表实现。

17.设指针变量top指向当前链式栈的栈顶,则删除栈顶元素的操作序列为( D )。
A. top=top+1; B. top=top-1;
C. top->next=top; D. top=top->next;

解析:
top->next指向的是空
把top赋为空
即完成了删除操作

填空题

1.用 S 表示进栈操作,用 X 表示出栈操作,若元素的进栈顺序是 1,2,3,4,出栈顺序 是 1,3,4,2,则相应的操作序列为(SXSSXSXX)

2.求该后缀表达式的值:9 2 3 + - 10 2 / -
解:方法是遇到运算符时取前面两个元素进行运算。
即23与+得到5,表达式变为

9 5 - 10 2 / -

9 5 - 得到4,表达式变为

4 10 2 / -

最后得到-1

3.求中缀表达式(3+4*x)-2*y/3的后缀表达式
解:(入栈,3输出,+入栈,4输出,的优先级大于+,*入栈
x输出,遇到),依次出栈,所以
和+依次出栈
-入栈 2输出 入栈 y输出 /优先级等于*
所以
出栈 /入栈 3输出
最后\出栈 -出栈
所以后缀表达式为:

34x*+2y*3/-

4.请把一个十进制数N转换为d进制数,并输出。

在这里插入图片描述

函数题

R6-1 在一个数组中实现两个堆栈

本题要求在一个数组中实现两个堆栈。

函数接口定义:

Stack CreateStack( int MaxSize );
bool Push( Stack S, ElementType X, int Tag );
ElementType Pop( Stack S, int Tag );

其中Tag是堆栈编号,取1或2;MaxSize堆栈数组的规模;Stack结构定义如下:

typedef int Position;
struct SNode {
    ElementType *Data;
    Position Top1, Top2;
    int MaxSize;
};
typedef struct SNode *Stack;

注意:如果堆栈已满,Push函数必须输出“Stack Full”并且返回false;如果某堆栈是空的,则Pop函数必须输出“Stack Tag Empty”(其中Tag是该堆栈的编号),并且返回ERROR。

裁判测试程序样例:

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

#define ERROR 1e8
typedef int ElementType;
typedef enum { push, pop, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
struct SNode {
    ElementType *Data;
    Position Top1, Top2;
    int MaxSize;
};
typedef struct SNode *Stack;

Stack CreateStack( int MaxSize );
bool Push( Stack S, ElementType X, int Tag );
ElementType Pop( Stack S, int Tag );

Operation GetOp();  /* details omitted */
void PrintStack( Stack S, int Tag ); /* details omitted */

int main()
{
    int N, Tag, X;
    Stack S;
    int done = 0;

    scanf("%d", &N);
    S = CreateStack(N);
    while ( !done ) {
        switch( GetOp() ) {
        case push: 
            scanf("%d %d", &Tag, &X);
            if (!Push(S, X, Tag)) printf("Stack %d is Full!\n", Tag);
            break;
        case pop:
            scanf("%d", &Tag);
            X = Pop(S, Tag);
            if ( X==ERROR ) printf("Stack %d is Empty!\n", Tag);
            break;
        case end:
            PrintStack(S, 1);
            PrintStack(S, 2);
            done = 1;
            break;
        }
    }
    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

5
Push 1 1
Pop 2
Push 2 11
Push 1 2
Push 2 12
Pop 1
Push 2 13
Push 2 14
Push 1 3
Pop 2
End

输出样例:

Stack 2 Empty
Stack 2 is Empty!
Stack Full
Stack 1 is Full!
Pop from Stack 1: 1
Pop from Stack 2: 13 12 11
Stack CreateStack(int MaxSize) {
    // 创建一个双栈,并返回指向该双栈的指针
    Stack S = (Stack)malloc(sizeof(struct SNode));
    // 使用动态内存分配来分配栈所需的空间
    S->Data = (ElementType*)malloc(MaxSize * sizeof(ElementType));
    S->Top1 = -1;
    S->Top2 = MaxSize;
    S->MaxSize = MaxSize;
    return S;
}


bool Push(Stack S, ElementType X, int Tag) {
    // 如果双栈已满,则打印 "Stack Full" 并返回 false
    if (S->Top1 + 1 == S->Top2) {
        printf("Stack Full\n");
        return false;
    }
    // 如果 Tag 为 1,则将元素 X 压入栈1
    if (Tag == 1) {
        S->Data[++S->Top1] = X;
    }
    // 如果 Tag 不为 1,则将元素 X 压入栈2
    else {
        S->Data[--S->Top2] = X;
    }
    return true;
}


ElementType Pop(Stack S, int Tag) {
    // 如果 Tag 为 1,则从栈1弹出一个元素
    if (Tag == 1) {
        // 如果栈1为空,则打印 "Stack 1 Empty" 并返回 ERROR
        if (S->Top1 == -1) {
            printf("Stack 1 Empty\n");
            return ERROR;
        }
        return S->Data[S->Top1--];
    }
    // 如果 Tag 不为 1,则从栈2弹出一个元素
    else if (Tag == 2) {
        // 如果栈2为空,则打印 "Stack 2 Empty" 并返回 ERROR
        if (S->Top2 == S->MaxSize) {
            printf("Stack 2 Empty\n");
            return ERROR;
        }
        return S->Data[S->Top2++];
    }
}

编程题

R7-1 汉诺塔的非递归实现

借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”),并保证每个移动符合汉诺塔问题的要求。

输入格式:

输入为一个正整数N,即起始柱上的盘数。

输出格式:

每个操作(移动)占一行,按柱1 -> 柱2的格式输出。

输入样例:

3

输出样例:

a -> c
a -> b
c -> b
a -> c
b -> a
b -> c
a -> c
#include<stdio.h>
using namespace std;

void move(int n, char a, char b, char c);
int main()
{
    int n;
    scanf("%d", &n);
    move(n,'a','b','c');
    return 0;
}
void move(int n,char a,char b,char c)
{
    if(n==1)
      {
	  	printf("%c -> %c\n",a,c);
	  }  
    else
    {
        move(n-1,a,c,b);  
        printf("%c -> %c\n",a,c);
        move(n-1,b,a,c);  
    }
}

R7-2 表达式转换

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。

输入格式:

输入在一行中给出不含空格的中缀表达式,可包含+、-、*、/以及左右括号(),表达式不超过20个字符。

输出格式:

在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。

输入样例:

2+3*(7-4)+8/4

输出样例:

2 3 7 4 - * + 8 4 / +
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// 定义堆栈结构体
typedef struct snode* stack;
struct snode {
    char ch[20];
    int top; // 定义堆栈顶指针
};

stack CreatStack() // 创建堆栈函数
{
    stack s = (stack)malloc(sizeof(struct snode));
    s->top = -1; // 初始化栈顶指针
    return s;
}

void push(stack s, char c) // 入栈函数
{
    (s->top)++;
    s->ch[s->top] = c;
}

char pop(stack s) // 出栈函数
{
    return s->ch[(s->top)--];
}

int main()
{   
    char s[21]; // 输入表达式的字符串,假设长度不超过20
    scanf("%s", s);
    int l = strlen(s); // 获取输入字符串的长度

    char ch1[150]; // 存储符号优先级的数组
    ch1['('] = 0;
    ch1['+'] = ch1['-'] = 1;
    ch1['*'] = ch1['/'] = 2;

    stack st = CreatStack(); // 创建堆栈
    int flag = 0; // 控制格式输出的标志变量,初始为0

    for (int i = 0; i < l; i++) // 遍历输入字符串
    {
        if (s[i] == '(') // 如果当前字符是左括号,则直接入栈
            push(st, s[i]);
        else if (s[i] == ')') // 如果当前字符是右括号,则弹出堆栈中所有元素,直到遇到左括号为止
        {
            char t;
            t = pop(st);
            while (t != '(') // 循环弹出,直到遇到左括号
            {
                printf(" %c", t); // 输出当前符号
                t = pop(st);
            }
            flag = 1; // 标记需要在下一次输出前添加空格
        }
        else if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') // 如果当前字符是运算符
        {
            if (s[i] == '+' && (s[i - 1] == '(' || i == 0)) // 如果当前运算符是正号(表示正数),则不进行操作
                ;
            else if (s[i] == '-' && (s[i - 1] == '(' || i == 0)) // 如果当前运算符是负号(表示负数),则直接输出
            {
                printf("-");
            }
            else if (ch1[s[i]] > ch1[st->ch[st->top]] || st->top == -1) // 如果当前运算符优先级高于栈顶运算符或者堆栈为空,则直接入栈
            {
                push(st, s[i]);
                flag = 1; // 标记需要在下一次输出前添加空格
            }
            else // 如果当前运算符优先级低于等于栈顶运算符,则弹出堆栈中优先级高于或等于当前运算符的所有元素,并将当前运算符入栈
            {
                printf(" %c", pop(st)); // 输出堆栈中优先级高于或等于当前运算符的元素
                while (ch1[s[i]] <= ch1[st->ch[st->top]] && st->top != -1) // 循环弹出符合条件的元素
                {
                    printf(" %c", pop(st));
                }
                push(st, s[i]); // 将当前运算符入栈
                flag = 1; // 标记需要在下一次输出前添加空格
            }
        }
        else // 如果当前字符是操作数,直接输出
        {
            if (flag) // 如果前一个字符是右括号或者运算符,则在输出当前操作数前添加空格
            {
                printf(" ");
                flag = 0;
            }
            printf("%c", s[i]);
        }
    }
    while (st->top != -1) // 将堆栈中剩余的元素全部输出
    {
        printf(" %c", pop(st));
    }
}

R7-3 出栈序列的合法性

给定一个最大容量为 M 的堆栈,将 N 个数字按 1, 2, 3, …, N 的顺序入栈,允许按任何顺序出栈,则哪些数字序列是不可能得到的?例如给定 M=5、N=7,则我们有可能得到{ 1, 2, 3, 4, 5, 6, 7 },但不可能得到{ 3, 2, 1, 7, 5, 6, 4 }。

输入格式:

输入第一行给出 3 个不超过 1000 的正整数:M(堆栈最大容量)、N(入栈元素个数)、K(待检查的出栈序列个数)。最后 K 行,每行给出 N 个数字的出栈序列。所有同行数字以空格间隔。

输出格式:

对每一行出栈序列,如果其的确是有可能得到的合法序列,就在一行中输出YES,否则输出NO。

输入样例:

5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2

输出样例:

YES
NO
NO
YES
NO

这是“火车进站问题”(也有一些人称之为“火车调度问题”)的抽象化题目。

题意:有 n 辆火车需要进站,每辆火车按照编号依次从 1 到 n 进站,每次只能进一辆或出一辆火车,而且进站的火车必须先出站,随时可以查看站内的顺序。问是否可能按照某种顺序将所有火车进站并出站。

解题思路:这是一道典型的模拟题目。我们可以使用一个栈来模拟火车进站和出站的过程。具体思路如下:

  1. 初始化一个栈,用于模拟火车站内的火车顺序,同时初始化一个指针 jin,用于表示下一辆要进站的火车编号,以及一个指针 chu,用于表示下一辆要出站的火车编号。
  2. 依次读入 n 辆火车的编号,将它们保存在一个数组中。
  3. 进入循环,如果 jin 等于当前要出站的火车编号 a[chu],则直接将 jin 和 chu 都加 1;否则,如果栈不为空且栈顶元素等于当前要出站的火车编号 a[chu],则弹出栈顶元素,将 chu 加 1;否则,将 jin 入栈,并将 jin 加 1。
  4. 循环结束后,如果栈为空,则说明所有火车都已经进站出站,输出 YES;否则,输出 NO。

m 表示栈的最大容量,也就是火车站内最多能同时停放的火车数量。

#include <stdio.h>

int main()
{
    int m, n, k;
    scanf("%d%d%d", &m, &n, &k);
    int a[1000], stack[1000];

    for (int i = 0; i < k; i++)
    {
        int jin = 1, chu = 1, top = 0, flag = 1;

        for (int j = 1; j <= n; i++)
        {
            scanf("%d", &a[j]);
        }

        while (1)
        {
            if (jin == a[chu])
            {
                jin++;
                chu++;
            }
            else if (top != 0 && a[chu] == stack[top - 1])
            {
                top--;
                chu++;
            }
            else
            {
                if (jin > n)
                    break;

                stack[top++] = jin;
                jin++;

                if (top >= m)
                {
                    flag = 0;
                    break;
                }
            }
        }

        if (flag == 0 || top != 0)
            printf("NO\n");
        else
            printf("YES\n");
    }
}


方法二:
    #include<bits/stdc++.h>
using namespace std;
int main(){
    int m,n,k;
    cin>>m>>n>>k;
    stack<char> s;
    while(k--){
        int q=1,flag=0;
        int a[n];
        for(int i=0;i<n;i++)cin>>a[i];
        for(int i=0;i<n;i++){
            if(s.size()>0&&s.top()==a[i])
                s.pop();
            else{
                if(q>a[i]){
                    flag=1;
                    break;
                }
                for(;q<a[i];q++){
                    s.push(q);
                }
                if(s.size()>=m){
                    flag=1;
                    break;
                }
                q=a[i]+1;
            }
        }
        if(flag)cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
        while(!s.empty()) s.pop();
    }
    return 0;
}

R7-4 包装机

一种自动包装机的结构如图 1 所示。首先机器中有 N 条轨道,放置了一些物品。轨道下面有一个筐。当某条轨道的按钮被按下时,活塞向左推动,将轨道尽头的一件物品推落筐中。当 0 号按钮被按下时,机械手将抓取筐顶部的一件物品,放到流水线上。图 2 显示了顺序按下按钮 3、2、3、0、1、2、0 后包装机的状态。

在这里插入图片描述
在这里插入图片描述
一种特殊情况是,因为筐的容量是有限的,当筐已经满了,但仍然有某条轨道的按钮被按下时,系统应强制启动 0 号键,先从筐里抓出一件物品,再将对应轨道的物品推落。此外,如果轨道已经空了,再按对应的按钮不会发生任何事;同样的,如果筐是空的,按 0 号按钮也不会发生任何事。

现给定一系列按钮操作,请你依次列出流水线上的物品。

输入格式:

输入第一行给出 3 个正整数 N(≤100)、M(≤1000)和 Smax(≤100),分别为轨道的条数(于是轨道从 1 到 N 编号)、每条轨道初始放置的物品数量、以及筐的最大容量。随后 N 行,每行给出 M 个英文大写字母,表示每条轨道的初始物品摆放。

最后一行给出一系列数字,顺序对应被按下的按钮编号,直到 −1 标志输入结束,这个数字不要处理。数字间以空格分隔。题目保证至少会取出一件物品放在流水线上。

输出格式:

在一行中顺序输出流水线上的物品,不得有任何空格。

输入样例:

3 4 4
GPLT
PATA
OMSA
3 2 3 0 1 2 0 2 2 0 -1

输出样例:

MATA
#include<bits/stdc++.h>
using namespace std;
int n,m,s;
queue<char>q[110];
stack<char>st;
int main(){
    cin>>n>>m>>s;
    for(int i=1;i<=n;i++){
        string a;
        cin>>a;
        for(int j=0;j<a.length();j++){
            q[i].push(a[j]);
        }
    }
    int a;
    while(cin>>a,a!=-1){
        if(a==0){
            if(st.size()){ // 如果栈不为空,输出栈顶元素并出栈
                cout<<st.top();
                st.pop();
            }
        }
        else{
            if(st.size()==s){ // 如果栈已满,执行出栈和入轨道操作
                if(q[a].size()){ // 如果轨道a有物品才进行操作
                    cout<<st.top(); // 输出栈顶元素
                    st.pop(); // 出栈
                    int t=q[a].front(); // 获取轨道a的首个元素
                    q[a].pop(); // 出队
                    st.push(t); // 入栈
                }
            }
            else{ // 如果栈未满,执行入栈操作
                if(q[a].size()){ // 如果轨道a有物品才进行操作
                    int t=q[a].front(); // 获取轨道a的首个元素
                    q[a].pop(); // 出队
                    st.push(t); // 入栈
                }
            }
        }
    }
    return 0;
}

R7-1 彩虹瓶

在这里插入图片描述
彩虹瓶的制作过程(并不)是这样的:先把一大批空瓶铺放在装填场地上,然后按照一定的顺序将每种颜色的小球均匀撒到这批瓶子里。

假设彩虹瓶里要按顺序装 N 种颜色的小球(不妨将顺序就编号为 1 到 N)。现在工厂里有每种颜色的小球各一箱,工人需要一箱一箱地将小球从工厂里搬到装填场地。如果搬来的这箱小球正好是可以装填的颜色,就直接拆箱装填;如果不是,就把箱子先码放在一个临时货架上,码放的方法就是一箱一箱堆上去。当一种颜色装填完以后,先看看货架顶端的一箱是不是下一个要装填的颜色,如果是就取下来装填,否则去工厂里再搬一箱过来。

如果工厂里发货的顺序比较好,工人就可以顺利地完成装填。例如要按顺序装填 7 种颜色,工厂按照 7、6、1、3、2、5、4 这个顺序发货,则工人先拿到 7、6 两种不能装填的颜色,将其按照 7 在下、6 在上的顺序堆在货架上;拿到 1 时可以直接装填;拿到 3 时又得临时码放在 6 号颜色箱上;拿到 2 时可以直接装填;随后从货架顶取下 3 进行装填;然后拿到 5,临时码放到 6 上面;最后取了 4 号颜色直接装填;剩下的工作就是顺序从货架上取下 5、6、7 依次装填。

但如果工厂按照 3、1、5、4、2、6、7 这个顺序发货,工人就必须要愤怒地折腾货架了,因为装填完 2 号颜色以后,不把货架上的多个箱子搬下来就拿不到 3 号箱,就不可能顺利完成任务。

另外,货架的容量有限,如果要堆积的货物超过容量,工人也没办法顺利完成任务。例如工厂按照 7、6、5、4、3、2、1 这个顺序发货,如果货架够高,能码放 6 只箱子,那还是可以顺利完工的;但如果货架只能码放 5 只箱子,工人就又要愤怒了……

本题就请你判断一下,工厂的发货顺序能否让工人顺利完成任务。

输入格式:

输入首先在第一行给出 3 个正整数,分别是彩虹瓶的颜色数量 N(1<N≤103)、临时货架的容量 M(<N)、以及需要判断的发货顺序的数量 K。

随后 K 行,每行给出 N 个数字,是 1 到N 的一个排列,对应工厂的发货顺序。

一行中的数字都以空格分隔。

输出格式:

对每个发货顺序,如果工人可以愉快完工,就在一行中输出 YES;否则输出 NO。

输入样例:

7 5 3
7 6 1 3 2 5 4
3 1 5 4 2 6 7
7 6 5 4 3 2 1

输出样例:

YES
NO
NO
#include<stdio.h>
#include<string.h>

int stack[1001] = {167890}, top = 1; // 初始化一个栈用于模拟颜色堆叠,栈顶指针top初始化为1
// 主函数
int main()
{
    int color_num, capacity, num, i, j; // 定义变量
    scanf("%d%d%d", &color_num, &capacity, &num); // 输入颜色的种类数、堆叠的最大容量和堆叠的次数

    int order[color_num + 1], top_order = color_num - 1; // 定义一个数组用于存储颜色堆叠顺序,初始化顶部指针为color_num-1
    for (i = 0; i < num; i++)  // 循环处理堆叠的次数
    {
        for (j = 0; j < color_num; j++) 
            scanf("%d", &order[top_order--]); // 输入颜色堆叠的顺序

        top_order = color_num; // 重置顶部指针

        for (j = 1; j <= color_num;) // 根据规则进行颜色堆叠操作
        {
            if (stack[top-1] == j) 
            {
                top--; 
                j++;
            }
            else if (order[top_order-1] == j) 
            {
                top_order--; 
                j++;
            }
            else if (order[top_order-1] > stack[top-1]) 
                break;
            else
            {
                stack[top++] = order[--top_order];
                if (top > capacity + 1) 
                    break;
            }
        }   

        if (j == color_num + 1) 
            printf("YES\n"); // 输出堆叠结果
        else 
            printf("NO\n"); // 输出堆叠结果

        memset(stack, 0, sizeof(stack)); // 清空栈
        top = 1; // 重置栈顶指针
        stack[0] = 114514; // 重新设置栈底的值
        memset(order, 0, sizeof(order)); // 清空堆叠顺序数组
        top_order = color_num - 1; // 重新设置顶部指针
    }

    return 0;
}
数据结构与算法学习之路:检查表达式的括号是否匹配——栈 一、什么是栈? 阅读详情

相关推荐

厦门大学计算机考研分析

人工智能研究院以探索全链条大交叉新型科研模式,引领学校信息学科攀升一流,高质量服务国家/区域经济社会发展为目标,校内赋能优势学科,突出计算机视觉、模式识别、空间数据计算、社交网络分析、人工智能芯片、机器翻译等特色,发挥智能声纳、智能能源动力健康、人工智能芯片半导体制备等交叉优势,提升人工智能学科内涵,形成厦大特色的AI优势方向;PPT内容可以包括但不限于:竞赛和科研经历,实习项目经历,软件、硬件能力,毕设、课程设计、大作业中涉及到调研、自学、代码、硬件等,尽量体现自己解决实际问题的能力;

li542525的博客 977

日常选择练习

在同一个信道上的同一时刻,能够进行双向数据传送的通信方式是( ) 2021-05-31 15:25:35 A、 单工 B、 半双工 C、 全双工 D、 上述三种均不是 回答正确 正确答案: C 解析: 全双工(Full Duplex)是通讯传输的一个术语。 通信允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合。全双工指可以同时(瞬时)进行信号的双向传输(A→B且B→A)。指A→B的同时B→A,是瞬时同步的,四线制。 攻击者采用某种手段,使用户访问某网站时获得一个其他网站的IP地址,从而将

qq_43688111的博客 1028

重庆邮电大学计算机考研408备考指南:四科均衡复习与专业选择

计算机考研408科目涵盖数据结构、计算机组成原理、操作系统和计算机网络四大核心课程,是衡量计算机专业基础能力的重要标准。其命题原理强调知识体系的完整性和交叉应用能力,要求考生不仅掌握单科知识点,还要理解各科目间的内在联系。从技术价值看,408考试能够系统检验学生对计算机系统底层原理、算法设计与网络通信等关键技术的掌握程度,为后续科研或工程实践打下坚实基础。在应用场景上,扎实的408知识体系尤其适合从事系统软件开发、人工智能算法优化、大数据平台构建等方向。以重庆邮电大学为例,其计算机科学与技术、软件工程等专业

weixin_34054866的博客 509

数据结构复习笔记

可能有些算法介绍的较为简单了,说的也不够细致,毕竟这个是面向考试才写的,只涉及了必要的考点。对于看这篇文章找思路的人来说不太友善,可能甚至是无用,在这里提前道歉

captaincoke的博客 4714

重邮计算机考研改考408:四专业选择策略与备考指南

计算机专业基础综合(408)作为计算机考研的核心科目,涵盖数据结构、计算机组成原理、操作系统和计算机网络四大基础课程。其命题原理强调知识体系的完整性和综合应用能力,通过全国统一命题确保考试公平性。这一考试模式的技术价值在于能够系统检验考生的计算机科学基础,为研究生阶段的学术研究和工程实践奠定坚实基础。在考研备考场景中,408的复习需要科学的时间分配和策略调整,尤其对于重邮计算机学院新改考408的计算机科学与技术、软件工程等专业,考生需结合自身背景制定个性化备考方案。数据结构中的算法设计和计算机组成原理的数据

weixin_34025051的博客 491

重邮计算机学院408考研指南:四专业对比与备考策略

计算机考研408统考是涵盖数据结构、计算机组成原理、操作系统和计算机网络四门核心课程的国家统一命题考试。其命题原理强调基础知识的系统性和综合运用能力,旨在全面评估考生的计算机专业素养。从技术价值看,408考试不仅提升考生的理论深度,还强化工程实践能力,为后续研究生学习和职业发展奠定坚实基础。在应用场景上,408成绩被众多高校计算机相关专业作为研究生入学的重要参考,尤其适用于重庆邮电大学计算机学院的计算机科学与技术、软件工程、人工智能和网络空间安全四个硕士专业。本文聚焦重邮计算机学院408考情,解析各专业特色

weixin_33716154的博客 367

算法与数据结构 第三章 栈与队列(详解)

目录 一、判断题 二、选择题 一、判断题 1、所谓“循环队列”是指用单向循环链表或者循环数组表示的队列。F 解析:错误,循环队列指的是后者,用数组表示的队列,利用求余数运算使得头尾相接。循环队列本身是一种顺序存储结构,而循环链表是一种链式存储结构。 2、An algorithm to check for balancing symbols in an expression uses a stack to store the symbols.T 解析:balancing symbols指的是一.

m0_62205773的博客 2831

示波器面板上的隐藏功能:如何利用BW Limit和EXT TRIG提升测量精度

本文深入探讨示波器面板上的隐藏功能BW Limit和EXT TRIG,揭示它们如何提升测量精度。通过带宽限制(BW Limit)有效滤除高频噪声,结合外部触发(EXT TRIG)确保稳定信号捕获,为电子测量提供专业解决方案。特别适用于开关电源、传感器信号等复杂场景的高精度测量需求。

weixin_30300225的博客 518

【数据结构入门精讲 | 第十六篇】并查集知识点及考研408、企业面试练习

在许多实际应用场景中,我们需要对元素进行分组,并且在这些分组中进行查询和修改操作。比如,在图论中,我们需要将节点按照连通性进行分组,以便进行最小生成树、最短路径等算法;在计算机视觉中,我们需要将像素进行分组,以便进行图像分割和对象识别等任务。而并查集正是为了解决这些问题而被提出来的一种数据结构。

等风来 4691

FineReport V11.0安装避坑指南:从下载到激活的完整流程(附百度网盘链接)

本文提供FineReport V11.0从下载、安装到激活的完整避坑指南。详细解析了部署前的环境准备、安装过程中的JVM内存等核心配置、激活流程以及安装后的优化与常见问题排查,旨在帮助用户一次部署成功,确保企业级报表平台的稳定运行。

echo99的专栏 1195

从谱峰搜索到多项式求根:Root-MUSIC算法原理与MATLAB实践

本文深入解析Root-MUSIC算法在阵列信号处理中的原理与应用,通过多项式求根替代传统MUSIC算法的谱峰搜索,显著提升计算效率和精度。文章详细介绍了算法核心思想、MATLAB实现步骤及工程优化技巧,帮助读者掌握这一高效的DOA估计方法。

weixin_30832143的博客 80

【数据结构入门精讲 | 第二篇】考研408、企业面试基础概念习题

1.时间复杂度是根据算法写成的程序在执行时耗费时间的长度,往往与输入数据的规模有关。(对)2.斐波那契数列FN的定义为:F0=0, F1=1, F(N)=F(N−1)+F(N−2), N=2, 3, …用递归函数计算FN的空间复杂度是O(N)。(对)3.斐波那契数列FN的定义为:F0=0, F1=1, FN=FN−1+FN−2, N=2, 3, …。用循环函数计算FN的时间复杂度是Θ(FN).(错) 解析:在循环函数中,我们通过迭代的方式依次计算每个斐波那契数列

等风来 4273

PCB工艺-SI9000使用教程

本文介绍了阻抗计算工具SI9000的使用方法,重点讲解了微带线与带状线的区别、共面阻抗概念及参考面选择。通过USB差分走线实例,详细说明了如何选择计算模型、填写参数并确定线宽线距。文章还提供了层叠设计资料和工厂常规阻抗表格作为参考,建议制板时标注需控阻抗的线路供板厂调整。最后简单提及了嘉立创阻抗计算工具作为备选方案。

weixin_50120208的博客 2026

【数据结构入门精讲 | 第六篇】队列知识点及考研408、企业面试练习

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。 队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。

等风来 4625

ROS+Gazebo仿真入门:用TurtleBot3模拟扫地机器人全流程

本文详细介绍了如何利用ROS和Gazebo仿真平台,以TurtleBot3 Waffle Pi模型为核心,从零搭建并运行一个虚拟扫地机器人的全流程。内容涵盖仿真环境搭建、世界与机器人模型解析,并重点演示了SLAM建图、自适应蒙特卡罗定位以及全局与局部路径规划等核心算法实战,为机器人算法开发与验证提供了高效、低成本的解决方案。

sre5engineer的博客 1087

【数据结构入门精讲 | 第十八篇】考研408、企业面试图专项练习(一)

在上一篇中我们学习了图的相关知识点,在这一篇中我们进行图的专项练习。选择两城市间最经济的航行路线用迪杰斯特拉算法(对)2从某顶点出发进行深度优先遍历,最先退出dfs过程的是拓扑序列的最后一个顶点。(对)3对任意一个图,从某顶点出发进行一次深度优先或广度优先遍历,可访问图的所有顶点。(错)若存在回路,则结束遍历,剩下的节点就不能被访问。4检查有向图是否存在回路的一种方法是使用无前驱顶点优先算法对有向图进行拓扑排序。( 对 )5邻接矩阵如下:

等风来 4145

Visual Studio 2022+Qt6.5.3安装教程+环境配置+创建Qt项目+乱码插件+运行很完美(16岁孩子也能看懂)

Visual Studio 2022+Qt6.5.3安装教程+环境配置+创建Qt项目+乱码插件+运行很完美(16岁孩子也能看懂)

Qt历险记,专注Qt技术,三年医疗设备研发经验,1年机器视觉研发经验,半年柔性传感研发经验。 1190

【数据结构入门精讲 | 第四篇】考研408、企业面试表专项习题

在带哨兵结点的双循环链表中,设链结点的后继指针域为next,前驱指针域为prior,指针header指向哨兵结点,则判断该链表是否为空的表达式为:header->next==header 或 header->prior==header

等风来 4270

31、车载通信中的可见光通信(VLC)技术解析

本文详细解析了车载通信中可见光通信(VLC)技术的应用背景、优势及发展前景。对比传统RF通信技术(如DSRC),VLC利用LED照明设备实现高效、安全的车辆与车辆、车辆与基础设施之间的通信,具有频谱资源丰富、安全性高、无电磁干扰等优势。文章还探讨了VLC在交叉口交通控制、高速公路通信、自动驾驶等场景的应用潜力,展望了其在未来智能交通系统中的重要作用。

hill8的博客 318

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

【数据结构入门精讲 | 第十九篇】考研408、企业面试图专项练习(二)

作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。 输入格式: 输入第一行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0 ~ (N−1);M是快速道路的条数;S是出发地的城市编号;D是目的地的城市编号。 第二行给出N个正

等风来 3865

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【数据结构入门精讲 | 第十四篇】散列表知识点及考研408、企业面试练习(1)

散列表(Hash Table),也被称为哈希表或散列映射,是一种常用的数据结构之一。它通过将键(key)映射到值(value)来实现高效的数据存储和检索。散列表的主要思想是利用哈希函数将键转换成对应的索引,然后将值存储在该索引位置上。当需要查找或插入元素时,再次使用哈希函数计算出对应的索引,从而快速定位到目标位置。散列表的优势在于具有高效的查找和插入操作。由于直接通过索引进行访问,时间复杂度通常为O(1),即常数时间装填

等风来 4042

深度学习工具包 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")

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【数据结构入门精讲 | 第十五篇】散列表知识点及考研408、企业面试练习(2)

实现QQ新帐户申请和老帐户登陆的简化版功能。最大挑战是:据说现在的QQ号码已经有10位数了。输入格式:输入首先给出一个正整数N(≤105),随后给出N行指令。每行指令的格式为:“命令符(空格)QQ号码(空格)密码”。其中命令符为“N”(代表New)时表示要新申请一个QQ号,后面是新帐户的号码和密码;命令符为“L”(代表Login)时表示是老帐户登陆,后面是登陆信息。QQ号码为一个不超过10位、但大于1000(据说QQ老总的号码是1001)的整数。密码为不小于6位、不超过16位、且不包含空格的字符串。

等风来 4139

从LeetCode到考研408:时间/空间复杂度分析,如何成为你编程面试和笔试的“隐形加分项”?

本文深入探讨了时间复杂度和空间复杂度分析在编程面试和考研408中的关键作用,提供了从LeetCode到考研真题的实战指南。通过五步法分析框架、递归算法和嵌套循环的深度剖析,帮助读者掌握复杂度分析的技巧,提升在技术面试和笔试中的竞争力。

weixin_30680385的博客 387

考研经验贴

考研经验帖 写在前边 最近几年参加研究生统一招生考试的人数越来越多,伴随着互联网行业的快速发展,许多人也会选择考与计算机专业相关的硕士。在准备考研之前,首先想想为什么要考研呢?是对某个领域感兴趣要继续学习呢?或是当年高考不理想想重新进入目标院校换个平台呢?还是仅仅为了逃避就业而选择考研? 如果是后者,笔者是不建议继续上研的,因为就业是迟早的事,如果抱着这种心态去上研,大概率在读研阶段效率也不会太高...

Solar's Blog 2739

2020考研经验分享——致学弟学妹

转眼间,20届考研已经落下帷幕,但21届考研才刚刚开始。今年我的考研成绩还不错 ,分享一下: 科目 分数 政治 72 英语二 73 数学二 117 专业综合 135 总分 397 政治和英语都还在预期之内,数学和专业课其实有些意料之外,尤其是专业课。 数学二今年题确实难,我的大题部分有好几个都没做出来,但是都把能写的写上了,好在我的小题(选择与填空)只错了1题...

AngelLover2017的博客 7916
上一篇: 【数据结构入门精讲 | 第六篇】队列知识点及考研408、企业面试练习
下一篇: 【数据结构入门精讲 | 第七篇】一文讲清全部排序算法(1)
秋说
秋说 优质创作者: 编程框架、信息安全技术领域 优质创作者: 编程框架、信息安全技术领域
博客等级 码龄4年 3万+粉丝 1906原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋说

感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值