用C语言实现“括号匹配“问题

简介: 用C语言实现“括号匹配“问题

题目介绍:

声明:题目来源于力扣.

题目链接:传送门

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。

左括号必须以正确的顺序闭合。

每个右括号都有一个对应的相同类型的左括号。

示例

示例1:

输入:s = “()”
输出:true

例2:

输入:s = “()[]{}”
输出:true

示例3:

输入:s = “(]”
输出:false

解题思路:

此题我们使用’栈’这个结构.

每个左括号都与右边最近的右括号匹配。所以我们可以用栈来保存每个等待匹配的右括号的左括号是什么,只要匹配成功就把元素弹出,当字符串遍历结束时如果栈为空,就说明所有括号都互相匹配了。那么这个字符串就是有效的。

例如:

情况1:(右括号过多或者未匹配)

字符串没有遍历结束,而遇到右括号时,栈已经为NULL,则直接返回false.

当0 ,1 ,2入栈.

3与2匹配成功,则2出栈.

4与1匹配成功,则1出栈.

5与0匹配成功,0出栈.

此时6为右括号,在栈顶并没有等到他想要的人,因为栈已经为NULL了,则返回false.

a1a454fcaf814157a0a82f8fc510c943.png

情况2:

左字符串依次入栈,右字符串依次出栈,最后字符遍历结束,而栈也是空栈,则表示括号匹配成功.

当0 ,1 ,2 ,3入栈.

4与3匹配成功,则3出栈.

5与2匹配成功,则2出栈.

6与1匹配成功,则1出栈.

7与0匹配成功,则0出栈.

此时栈为NULL,且字符串遍历结束.返回true.

dced4424620648b6b4ba0ab56f1117a4.png

情况3:(左括号过多或者未匹配成功)


左括号过多,即使右括号用完(这个例子没用完),字符串遍历结束,栈中仍有元素(左括号未找到匹配).

栈非空返回false.

b39e1ca89ebd4469b00439ad92f481ef.png

骤:

C语言中使用栈的结构,需要自己造轮子,先设计一个栈出来,文章结尾已经写出,其次是一定要记得初始化(InitST).

  1. 计算字符串的长度
  2. 如果字符串是长度为奇数,则直接返回false.
  3. 遇见左括号入栈
  4. 遇见右括号先判断栈是否为NULL,为空则直接返回false.
    不为空,则与栈顶元素比较,如果是匹配成功的则出栈,否则直接返回false
  5. 最后如果栈是NULL栈则返回true,否则返回false

代码实现:

bool isValid(char* s) {
    ST st1;
  InitST(&st1);//这个别忘了
    int sz=strlen(s);
    if (sz % 2 == 1)
  {
    return false;
  }
    for(int i=0;i<sz;i++)
    {
        if(s[i]=='('||s[i]=='['||s[i]=='{')//左括号进栈
        {
            STPush(&st1,s[i]);
        }
        else//右括号
        {
            if(STEmpty(&st1))//如果碰到右括号,且栈是NULl,则返回false
            {
                return false;
            }
            //如果栈顶与右括号匹配,则出栈
            if (STTop(&st1) == '(' && s[i] == ')' || STTop(&st1) == '[' && s[i] == ']' || STTop(&st1) == '{' && s[i] == '}')//如果栈顶元素与右括号匹配,则出栈
      {
        STPop(&st1);
      }
           else{
               return false;
           }
        }
    }
    return STEmpty(&st1);
}

上面的实现方式还有一个内存泄漏的危险,因为栈空间并没有被释放,应当在每个返回结果之前调用栈销毁函数(STDestory).


栈的实现:

//栈的实现
//oj题里面不需要写头文件
typedef  char stacktype;
typedef struct stack
{
  stacktype* data;
  int top;
  int capacaity;
}ST;
void InitST(ST* ps);
void STPush(ST* ps, stacktype x);//压栈
void STPop(ST* ps);//出栈
bool STEmpty(ST* ps);//判断是否为空栈
stacktype STTop(ST* ps);//返回栈顶元素
void STDestory(ST* ps);//栈的销毁
//初始化栈
void InitST(ST* ps)
{
  assert(ps);
  ps->top = -1;
  ps->capacaity = 4;
  ps->data = (stacktype*)malloc(ps->capacaity * sizeof(stacktype));
}
//压栈
void STPush(ST* ps, stacktype x)
{
  assert(ps);
  if (ps->top + 1 == ps->capacaity)
  {
    ps->capacaity *= 2;
    stacktype* tmp = (stacktype*)realloc(ps->data, ps->capacaity * sizeof(stacktype));
    if (tmp == NULL)
    {
      printf("增容失败\n");
    }
    ps->data = tmp;
  }
  ps->top++;
  ps->data[ps->top] = x;
}
//出栈
void STPop(ST* ps)
{
  assert(ps);
  assert(!STEmpty(ps));
  ps->top--;
}
//判断是否为空栈,是空返回真
bool STEmpty(ST* ps)
{
  assert(ps);
  if (ps->top == -1)//如果"栈"为空,则栈顶的下标为-1;
  {
    return true;
  }
  return false;
}
//返回栈顶元素
stacktype STTop(ST* ps)
{
  assert(ps);
  return ps->data[ps->top];//反追栈顶元素
}
//栈的销毁
void STDestory(ST* ps)
{
  assert(ps);
  free(ps->data);//释放栈空间
  ps->data = NULL;
  ps->top = -1;
  ps->capacaity = 0;
}

提交记录:

6d63ad113895427882148f34bed6984e.png

目录
相关文章
|
9月前
|
C语言
C语言栈的括号匹配的检验讲解及相关代码
C语言栈的括号匹配的检验讲解及相关代码
186 0
|
5月前
|
存储 人工智能 C语言
数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值&&特殊矩阵的压缩存储
本文首先介绍了栈的应用之一——括号匹配,利用栈的特性实现左右括号的匹配检测。接着详细描述了南京理工大学的一道编程题,要求判断输入字符串中的括号是否正确匹配,并给出了完整的代码示例。此外,还探讨了栈在表达式求值中的应用,包括中缀、后缀和前缀表达式的转换与计算方法。最后,文章介绍了矩阵的压缩存储技术,涵盖对称矩阵、三角矩阵及稀疏矩阵的不同压缩存储策略,提高存储效率。
545 8
|
9月前
|
C语言
【04】C语言括号匹配问题
【04】C语言括号匹配问题
|
缓存 C语言
【数据结构】C语言实现顺序栈 && OJ题 —— 有效的括号
【数据结构】C语言实现顺序栈 && OJ题 —— 有效的括号
157 0
【数据结构】C语言实现顺序栈 && OJ题 —— 有效的括号
|
C语言
C语言中使用大括号与给函数命名的正确方法(转载)
使用大括号的正确方法: 在C中,使用大括号的方法无所谓对还是错——只要每个开括号后都有一个闭括号,你的程序中就不再会出现与大括号有关的问题。
1700 0
|
1月前
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
62 23
|
1月前
|
算法 C语言
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
本文档介绍了如何编写两个子函数,分别求任意两个整数的最大公约数和最小公倍数。内容涵盖循环控制与跳转语句的使用、最大公约数的求法(包括辗转相除法和更相减损术),以及基于最大公约数求最小公倍数的方法。通过示例代码和测试说明,帮助读者理解和实现相关算法。最终提供了完整的通关代码及测试结果,确保编程任务的成功完成。
66 15
|
1月前
|
C语言
【C语言程序设计——函数】亲密数判定(头歌实践教学平台习题)【合集】
本文介绍了通过编程实现打印3000以内的全部亲密数的任务。主要内容包括: 1. **任务描述**:实现函数打印3000以内的全部亲密数。 2. **相关知识**: - 循环控制和跳转语句(for、while循环,break、continue语句)的使用。 - 亲密数的概念及历史背景。 - 判断亲密数的方法:计算数A的因子和存于B,再计算B的因子和存于sum,最后比较sum与A是否相等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台对代码进行测试,预期输出如220和284是一组亲密数。 5. **通关代码**:提供了完整的C语言代码实现
60 24
|
1月前
|
存储 C语言
【C语言程序设计——函数】递归求斐波那契数列的前n项(头歌实践教学平台习题)【合集】
本关任务是编写递归函数求斐波那契数列的前n项。主要内容包括: 1. **递归的概念**:递归是一种函数直接或间接调用自身的编程技巧,通过“俄罗斯套娃”的方式解决问题。 2. **边界条件的确定**:边界条件是递归停止的条件,确保递归不会无限进行。例如,计算阶乘时,当n为0或1时返回1。 3. **循环控制与跳转语句**:介绍`for`、`while`循环及`break`、`continue`语句的使用方法。 编程要求是在右侧编辑器Begin--End之间补充代码,测试输入分别为3和5,预期输出为斐波那契数列的前几项。通关代码已给出,需确保正确实现递归逻辑并处理好边界条件,以避免栈溢出或结果
63 16
|
1月前
|
存储 编译器 C语言
【C语言程序设计——函数】分数数列求和2(头歌实践教学平台习题)【合集】
函数首部:按照 C 语言语法,函数的定义首部表明这是一个自定义函数,函数名为fun,它接收一个整型参数n,用于指定要求阶乘的那个数,并且函数的返回值类型为float(在实际中如果阶乘结果数值较大,用float可能会有精度损失,也可以考虑使用double等更合适的数据类型,这里以float为例)。例如:// 函数体代码将放在这里函数体内部变量定义:在函数体中,首先需要定义一些变量来辅助完成阶乘的计算。比如需要定义一个变量(通常为float或double类型,这里假设用float。
36 3