标签:
编写一个程序,它从标准输入(终端)读取C源代码,并验证所有的花括号都正确的成对出现。
注意:你不必担心注释内部、字符串常量内部和字符常量形式的花括号。
我们先判断左花括号的数量是否相等。
如果左右花括号数量不等,肯定不成对!
如果左右花括号数量相等,一定就成对吗???
好像也不一定。
我们来举例分析一下,左右花括号相等时可能会出现的情况:
1.{{{{{}}}}}(匹配)
2.{}{}{}{}{}(匹配)
...
3.}}}}}{{{{{(不匹配)
4.{{{{}}}}}{(不匹配)
......
第1种情况和第2种情况,属于左右花括号数目相等且匹配的情况,所以我们不用分析。
第3种情况和第4种情况,属于左右花括号数目相等但不匹配的情况,因此我们需要找出它们的共同点.
稍加分析我们就可以得出以下结论:
当右花括号出现时,如果左花括号的数目小于右花括号数目时,左右花括号必然不匹配.
可能有人对以上结论不理解,在此我再来详细解释一下:
(如果你表示已理解结论,请直接跳转算法总结部分)
我们先来分析情况3:
当我们看到第一个右花括号时,发现它前面并没有左花括号.
因此情况3必然属于左右花括号不匹配的情况.
我们再来分析情况4:
我们看第1个右花括号,发现它前面有4个左花括号;
第2个右花括号,前面有4个左花括号
......
直到第5个右花括号,前面只有4个左花括号.
因此情况3也属于左右花括号不匹配的情况.
根据上面的分析,我们得出如下结论:
判断左右花括号是否成对出现需要两个条件:
1.左右花括号数目必须相等.
2.当右花括号出现时,左花括号数目必须大于右花括号.
根据题目要求,首先我们需要从标准输入获得数据。
我们可以用scanf()函数、getchar()函数、gets()函数......
(不清楚这些函数功能的童鞋请直接点击函数名称)
scanf()函数和gets()函数都需要指定一个字符数组来做存储。
如果用这两个函数的话,那就必须得定义一个字符数组。
定义字符数组的话又会面临数组溢出或者浪费空间等问题。
(数组定义小了,可能会溢出;定义大了,又会浪费空间.)
因此,用getchar()函数最合适。
而getchar()函数每次只能从控制台接受一个字符,因此我们需要用循环来操作。
所以,我们用getchar()函数通过循环操作,从标准输入获得数据。
于是便可以完成这样的代码:
//定义一个整型变量用来接收控制台数据 int ch = 0; //提示信息 printf("请输入一段字符以ctrl+z结束:\n"); //从控制台读入字符并判断是否满足循环条件。 while((ch=getchar())!=EOF){ ...//判断左右花括号是否匹配的代码 }
接下来我们开始写分析左右花括号是否匹配的代码。
根据,算法总结,我们可以设置两个int型变量left和right,分别用来记录左花括号的数量和右花括号的数量。
如果遇到左花括号,则left++;
如果如果遇到右花括号,我们首先得判断左花括号的数目是否大于右花括号,right++;否则直接退出。
//定义一个整型变量用来接收控制台数据 int ch = 0; //定义一个整型变量用来计算左花括号数目 int left = 0; //定义一个整型变量用来计算右花括号数目 int right = 0; //提示信息 printf("请输入一段字符以ctrl+z结束:\n"); //从控制台读入字符并判断是否满足循环条件。 while((ch=getchar())!=EOF){ //遇到左花括号,left+1 if(ch==’{’){ left++; } //遇到右花括号 if(ch==’}’){ //左花括号数目大于右花括号数目right+1 if(left>right){ right++; }else{ //否则就是这种情况 //{{{{}}}}}{ //}}}}}{{{{{ //..... //直接退出程序 printf("不匹配!\n"); return 0; } } } //如果程序能走到这里 //就已经排除}}}}{{{{这种特殊情况 //如果左花括号数目等于右花括号数目 if(right==left){ printf("匹配!\n"); }else{ printf("不匹配!\n"); }
最终的完整的代码如下:
#include<stdio.h> int main(){ //定义一个整型变量用来接收控制台数据 int ch = 0; //定义一个整型变量用来计算左花括号数目 int left = 0; //定义一个整型变量用来计算右花括号数目 int right = 0; //提示信息 printf("请输入一段字符以ctrl+z结束:\n"); //从控制台读入字符并判断是否满足循环条件。 while((ch=getchar())!=EOF){ //遇到左花括号,left+1 if(ch==’{’){ left++; } //遇到右花括号 if(ch==’}’){ //左花括号数目大于右花括号数目right+1 if(left>right){ right++; }else{ //否则就是这种情况 //{{{{}}}}}{ //}}}}}{{{{{ //..... //直接退出程序 printf("不匹配!\n"); return 0; } } } //如果程序能走到这里 //就已经排除}}}}{{{{这种特殊情况 //如果左花括号数目等于右花括号数目 if(right==left){ printf("匹配!\n"); }else{ printf("不匹配!\n"); } return 0; }
写到这里,好像就已经结束了?
其实....并没有!
在上述程序中,我们用了两个变量left和right来记录左右花括号数目。
其实,我们并不需要知道left和right具体的值.
因此,我们可以用一个变量来记录左右花括号的状态.
我们定义一个整型变量count.
如果遇到左花括号,count++;
如果遇到右花括号,判断count是否大于0,如果是count--,否则直接退出.
最终代码如下:
#include<stdio.h> int main(){ //定义一个整型变量用来接收控制台数据 int ch = 0; //定义一个整型变量用来记录左右花括号的状态 int count = 0; //提示信息 printf("请输入一段字符以ctrl+z结束:\n"); //从控制台读入字符并判断是否满足循环条件。 while((ch=getchar())!=EOF){ //遇到左花括号,count++ if(ch==’{’){ count++; } //遇到右花括号 if(ch==’}’){ //左花括号数目大于右花括号数目right+1 if(count>0){ count--; }else{ //否则就是这种情况 //{{{{}}}}}{ //}}}}}{{{{{ //..... //直接退出程序 printf("不匹配!\n"); return 0; } } } //如果程序能走到这里 //就已经排除}}}}{{{{这种特殊情况 //如果左花括号数目等于右花括号数目 if(count==0){ printf("匹配!\n"); }else{ printf("不匹配!\n"); } return 0; }
看了本篇文章,如果你还不会如何用C语言来验证花括号是否成对.....
请关注微信公众号gxdydd,在微信公众号下留言,有空我一定会回复的哦!
本文来自于
原文地址:http://gaoxiaodiao.cpm/p/9.html
标签: