头歌实训作业数据结构与算法 - 栈和队列的应用

第1关:括号是否匹配

任务描述


本关任务:给定一串字符,不超过100个字符,可能包括括号、数字、字母、标点符号、空格,编程检查这一串字符中的( ) ,[ ],{ }是否匹配。

相关知识


为了完成本关任务,你需要掌握:1.栈的基本特性和操作,2.C++ 标准模板库(STL)中的容器栈(stack)的基本操作。

1. 栈的基本特性和操作


本关提供一个顺序栈SqStack的基本运算及其实现,你可以调用其有关函数完成指定操作。各函数详细功能请参见代码目录中的sqstack.h头文件,基本操作如下:

//初始化顺序栈
void InitStack(SqStack *&s);
//判断栈空否
bool StackEmpty(SqStack *s);
//进栈
bool Push(SqStack *&s, ElemType e);
//出栈
bool Pop(SqStack *&s, ElemType &e);
//取栈顶元素
bool GetTop(SqStack *s, ElemType &e);


2. C++ STL中的栈(stack)


stack翻译为栈,是STL中一个后进先出(Last In First Out,LIFO)的一个容器。
如果要使用stack,需要添加stack头文件,#include <stack>。除此之外,还需要在头文件下面加上一句:“using namespace std;”,这样就可以在代码中使用stack了。下面来看stack 的一些常用用法。

2.1 stack的定义


定义一个stack的语法如下,其中typename可以是任意基本数据类型或容器,stack_name为容器对象名称:

stack<typename> stack_name;
//例如:
stack<int> st1;    //定义一个名称为st1存放int型数据的栈
stack<char> st2; //定义一个名称为st2存放char型数据的栈
stack<string> st3; //定义一个名称为st3存放string型数据的栈


2.2 stack容器内元素的访问


由于栈(stack)本身就是一种后进先出的数据结构,因此在STL中只能通过pop()来访问栈顶元素。
示例如下:

#include <stdio.h>
#include <stack>
using namespace std;
int main() {
    stack<int> st;
    for (int i = 1; i <= 5; i++) {
        st.push(i); //push(i)将元素入栈,因此1 2 3 4 5依次入栈
    }
    printf("%d\n", st.top()); //访问栈顶元素
    return 0;
}


程序运行后,栈中元素如下图所示:

程序输出结果:
5

2.3. stack常用函数实例解析


(1) push()
push(x)将x入栈,时间复杂度为O(1)。
(2) top()
top()获取栈顶元素,时间复杂度O(1)。 
(3) pop()
pop()弹出栈顶元素,时间复杂度为O(1)。
示例如下:

#include <stdio.h>
#include <stack>
using namespace std;
int main() {
    stack<int> st;
    for (int i = 1; i <= 5; i++) {
        st.push(i); //将1 2 3 4 5依次入栈
    }
    for (int i = 1; i <= 3; i++) {
        st.pop(); //连续三次将栈顶元素出栈,即5 4 3依次出栈
    }
    printf("%d\n", st.top()); //访问栈顶元素
    return 0;


输出结果:
2


(4) empty()
empty()检测stack是否为空,为空则返回true,非空则返回false。复杂度为O(1)。


示例如下:

#include <stdio.h>
#include <stack>
using namespace std;
int main() {
    stack<int> st;
    if (st.empty() == true) { //一开始栈内没有元素,所以是空
        printf("Empty\n");
    } else {
        printf("Not empty\n");
    }
    st.push(1);
    if (st.empty() == true) { //入栈“1”后,栈非空
        printf("Empty\n");
    } else {
        printf("Not empty\n");
    }
    return 0;
}


输出结果:
Empty
Not empty

(5) size()


size()返回stack内元素的个数,复杂度为O(1)。


示例如下:

#include <stdio.h>
#include <stack>
using namespace std;
int main() {
    stack<int> q;
    for (int i = 1; i <= 5; i++) {
        q.push(i); //push(i)用来将i入栈
    }
    printf("%d\n", q.size()); //栈中有5个元素
    return 0;
}


输出结果:
5

2.4 stack的常见用途
栈用来模拟实现一些递归,防止程序对栈内存的限制而导致程序出错。一般来说,程序的栈内存空间很小,对有些题目来说,如果用普通的函数来进行递归,一旦递归层数过深(不同的机器不同,一般约几千至几万层),则会导致程序运行崩溃。如果用栈来模拟递归算法的实现,则可以避免这一方面的问题(不过这种应用较少出现)。

2.5 一个完整的stack程序示例


#include<iostream>
#include<stack>
using namespace std;
int main() {
    stack<int> st;    //定义栈对象st
    for (int i = 1; i <= 10; i++) {
        st.push(i); //1 2 3 4 5 6 7 8 9 10依次入栈
    }
    //输出栈的元素个数
    cout << st.size() << endl; //10
    //输出栈顶元素
    cout << st.top() << endl; //10
    //输出栈的所有元素
    while (!st.empty()) {
        int tmp = st.top();     //取栈顶元素
        cout << tmp << " ";     //输出栈顶元素
        st.pop();               //删除栈顶元素
    }
    cout << endl;
    return 0;
}


输出结果:
10
10
10 9 8 7 6 5 4 3 2 1

编程要求


根据提示,在右侧编辑器补充完成函数bool is_valid(char* str)的代码,该函数的功能为判断传入的字符串str中包含的括号是否匹配,如果匹配函数返回true,否则返回false。

测试说明


平台会对你编写的代码进行测试:

测试输入:
sin(10+20)
预期输出:
yes

测试输入:
[](){}{
预期输出:
no

测试输入:
[  ,   {  (   ,   .  )   [,,,,,]  }  , , ]
预期输出:
yes

初始代码: 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <stack>
using namespace std;

#include "sqstack.h" //包含顺序栈基本运算

bool is_valid(char* str)
{
	//请在下面编写代码
	/*************************Begin*********************/
	



    
	/**************************End**********************/
}

int main(int argc, char const *argv[])
{
	char exp[1000];
	fgets(exp, 1000, stdin);
	bool flag = is_valid(exp);
	if (flag)printf("yes\n");
	else printf("no\n");

	return 0;
} 

补充代码: 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <string>

#include <stack>

using namespace std;

#include "sqstack.h" //包含顺序栈基本运算

bool is_valid(char * str) {
  //请在下面编写代码
  /*************************Begin*********************/
  int len = strlen(str);
  int pos = 0;
  int * ans = (int * ) malloc(sizeof(int) * len);
  for (int i = 0; i < len; i++) {
    if ((str[i] == '(') || (str[i] == '{') || (str[i] == '[')) {
      ans[pos++] = str[i];
    }
    if (str[i] == ')') {
      if ('(' == ans[pos - 1]) {
        pos--;
      } else {
        return false;
      }
    }
    if (str[i] == '}') {
      if ('{' == ans[pos - 1]) {
        pos--;
      } else {
        return false;
      }
    }
    if (str[i] == ']') {
      if ('[' == ans[pos - 1]) {
        pos--;
      } else {
        return false;
      }
    }
  }
  if (pos != 0) {
    return false;
  }
  return true;

  /**************************End**********************/
}

int main(int argc, char
  const * argv[]) {
  char exp[1000];
  fgets(exp, 1000, stdin);
  bool flag = is_valid(exp);
  if (flag) printf("yes\n");
  else printf("no\n");

  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值