线性表与栈

线性表,栈与队列结构体
线性表:具有相同属性的一组数据元素,相互之间存在先后关系
*
n 个人围成一圈,从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 1 开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。

#include <stdio.h>

int main()
{
    int n, m, s = 0; //s:人数
    int flag[101] = { 0 };//设置大一点防止溢出,全部标记为0

    scanf("%d %d", &n, &m);//输入n,m

    for (int k = 0; k < n; k++) {
        int i = 0;//若已有人报到m数,则重新回到循环,将i清零。由于s未做变动,所以将接着原位置继续进行
        while (i < m) {  模拟报数过程
                //i:报的数字大小
            s++;
            if (s > n)  循环从头开始
                s = 1;//又回到1
            if (flag[s]==0)   没有出列的人才能有效报数
            //flag[s]==0:没有出列的人
            //如果轮到的是没有出列的人
                i++;//那么报的数字继续每次加1
        }

        printf("%d ", s);    出列并标注已经出列
        flag[s] = 1;       //标注已出列为1
    }
    printf("\n");
    return 0;
}


关键点分析:
1.设置数组,并用1和0来区分出列和未出列的人
2.单独设置变量k来给For循环提供指标,并且k<n,n为总人数,即当所有人都出圈时,for循环结束
3.单独设置变量i来作为报数大小
4.将i初始化为0放在for循环后while循环前,能够让i达到m后及时回到while循环前重新初始化然后再开始报数
5.将初始化的值化为0,能够避免将这一列的第一个同学武断误判
6.if语句内,先判断人数是否超过了总人数,再判断是不是出列的人,再进行i的累加
7.将printf放在while循环外,能够避免每一个s都输出的情况,给s的输出规定了“符合i == m才会输出s”的条件

具有后进先出的特性的线性表:栈
限定仅在表位进行插入或删除操作的线性表
使用情况:先碰到的先不处理,碰到触发点时才一个个弹出来
入栈:push 出栈:pop
头文件:#include<stack>
创建一个栈对象s:stack<类型> s;例stack<char>/stack<int>
把栈顶元素弹出:s.pop();
获取栈顶元素并存放到c2:c2=s.top();
判断是否为空:s.empty();

strlen:返回unsigned类型
在同时处理int和unsigned时,按照unsigned的大小类型进行对比
*
给定一个只包含(,),[,],{,}的字符串,判断字符串是否有效,有效字符串需要满足:
1.左括号必须用相同类型的右括号闭合。
2.左括号必须以正确的顺序闭合;

输入: [()]
输出:true;

输入:{(}
输出:false

#include <iostream>
#include <stack>//strlen函数头文件
#include <string.h>

using namespace std;
int main()
{
    char inStr[100];
    int length;
    cin >> inStr;
    length = strlen(inStr);//把inStr的字符长度赋给length
    stack<char> myStack;//构造一个栈

    for (int i = 0; i < length; i++) {
        if ((inStr[i] == '(') || (inStr[i] == '[') || (inStr[i] == '{')) {
            myStack.push(inStr[i]);//入栈
        }
        else {
            if (inStr[i] == ')') {
                if (myStack.empty()) {   ///因为下一个步骤是取栈顶元素,所以要判断是不是空栈
                    cout << "false" << endl;
                    return -1;//表示返回一个代数值,一般用在子函数结尾。按照程序开发的一般惯例,表示该函数失败;
                }

                char temp = myStack.top();    ///取栈顶元素
                if (temp != '(') {
                    cout << "false" << endl;
                    return -1;
                }
                myStack.pop();   ///出栈
            }
            else if (inStr[i] == ']') {
                if (myStack.empty()) {
                    cout << "false" << endl;
                    return -1;
                }

                char temp = myStack.top();
                if (temp != '[') {
                    cout << "false" << endl;
                    return -1;
                }
                myStack.pop();
            }
            else if (inStr[i] == '}') {
                if (myStack.empty()) {
                    cout << "false" << endl;
                    return -1;
                }

                char temp = myStack.top();
                if (temp != '{') {
                    cout << "false" << endl;
                    return -1;
                }
                myStack.pop();
            }
        }

    }
    cout << "true" << endl;
}

关键点分析
1.一遇到左括号就入栈,等待右括号出现并进行匹配。
2.在遇到右括号时,不入栈,而是与栈顶的字符进行匹配。匹配后也不入栈,并且把栈顶弹出,为下一个右括号出现时的匹配做准备。
例:输入{(时,当输入)时,与栈顶(进行匹配。成立,)不入栈,并且把栈顶(弹出。此时栈里只剩下{,继续等待下一个字符出现。
类似于一种对称图案的对比。

问题:
当只输入左括号时,即使并不是以正确的括号顺序闭合的,也仍然会被判为true。
正在尝试寻找解决方案

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值