编写程序来检查给定的输入字符串是否有平衡括号

时间:2015-05-25 21:11:46

标签: c arrays string character

给定一串括号,写一个程序来查找它是否有效。

Examples-

input : {{{}}}
output: Valid

input : }{}{}{}}
output: Invalid

我在C中编写了以下代码并测试了输出是否正确。

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

int main()
{   
  char str[20];
  int i=0;

  printf("Enter String: ");
  gets(str);

  int count = 0;
  while (str[i] != '\0')
  {
    if (str[i] == '}')
        count--;
    if (str[i] == '{')
        count++;
    if (count < 0)
    {
        printf("\nInvalid");
        break;
    }   
    i++;        
  }
  if (count == 0)
      printf("\nValid");
  return 0;
 }

这个程序不适用于输入为{{{}}的情况,我错过了什么条件?

5 个答案:

答案 0 :(得分:2)

代码应说明最终结果是否为0,如if (count == 0) { printf("Valid\n"); } else { printf("Invalid\n"); } return 0;

的情况
if (count < 0) {
  // printf("\nInvalid");
  break;
}   

也简单地突破了循环。

gets()

C自C99以来已被弃用,并已从fgets()(C11)中删除,请使用char str[20]; fgets(str, sizeof str, stdin);

char

无需读取整个字符串。代码可以使用1 int ch; while ((ch = fgetc(stdin)) != '\n' && ch != EOF) { if (str[i] == '}') count--; if (count < 0) { break; } else if (str[i] == '{') count++; } } 一次。

{{1}}

答案 1 :(得分:1)

您并不需要立即输入整个字符串,因为您只是按顺序处理字符。因此,您可以避免使用gets()之类的不安全方法,甚至是fgets()等安全但复杂的方法。

相反,只需使用getchar()来阅读和处理每个角色 - 这将大大简化您需要做的事情。

至于逻辑,你基本上是正确的。保持括号级别,最初设置为零的值。然后阅读每个字符并按如下方式操作:

  • 如果是{,只需在该级别添加一个。
  • 如果是},则从级别中减去一个,然后检查以确保级别为非负级别。如果没有,那么你的关闭括号太多了,你可以退出。
  • 如果它的行尾或文件结尾,请停止处理字符。检查以确保最终级别为零。如果没有,您还没有关闭所有括号,因此它无效。如果等级为零,则一切都是平衡的。
  • 任何其他字符都可被视为错误。

请参阅下面有关如何实现此目的的一个示例:

#include <stdio.h>

int main (void) {
    int debug = 0;       // for debugging purposes.
    int ch, level = 0;   // character and current level.

    // Output prompt, read characters while valid.

    printf("Enter string: ");
    while (((ch = getchar()) == '{') && (ch == '}')) {
        // Select based on '{' or '}'.

        if (ch == '{') {
            // Open bracket, just add one.

            ++level;
            if (debug) printf("DEBUG: {:%d\n",level);
        } else {
            // Close bracket, subtract one and check.

            if (--level < 0) {
                puts ("Level has gone below zero.");
                return 1;
            }
            if (debug) printf("DEbug: }:%d ",level);
        }
    }

    // If not endline/endfile, we have invalid character.

    if ((ch != '\n') && (ch != EOF)) {
        puts ("Invalid character in input.");
        return 1;
    }

    // Level should be zero.

    if (level != 0) {
        puts ("Level still positive at end of line.");
        return 1;
    }

    // All checks now passed okay.

    puts ("Input was fine.");
    return 0;
}

答案 2 :(得分:0)

你永远不应该使用gets() gcc 编译器甚至会警告它是危险的,因为没有办法阻止缓冲区溢出,例如

char str[6];
gets(str);

使用以下输入

iharob

是一个问题,因为'\0'终结者或'\n'没有空间,而是

fgets(str, sizeof(str), stdin);

对任何输入都是安全的,虽然输入字符串会被修剪以适应缓冲区,但不会发生缓冲区溢出。

答案 3 :(得分:0)

以前的答案已经涵盖了避免缓冲区溢出和无法工作的潜在情况 - 提高性能我会修改while循环以避免检查我们知道永远是错误的条件。例如没有必要检查计数是否小于0除非我们只是减少了计数;如果角色是一个紧密的括号,那么检查一个空心支架是没有意义的:

while (str[i] != '\0')
{
    if (str[i] == '}')
    {
        count--;

        if (count < 0)
        {
            printf("\nInvalid");
            break;
        }
    }
    else if (str[i] == '{')
        count++;

    i++;        
}

答案 4 :(得分:0)

我希望您发现这个有用且简单的^-^

    #include<iostream>
    #include<string.h>

    using namespace std;

    {
    string mathEx ;

    cout<<"Please Enter math Expression contain ')' , '(' to                                 
    check balance \n"<<"MathExpression = ";
    cin>>mathEx ;
    int i =0 , count = 0 ;
    while (mathEx [i] != '\0'){
    if(mathEx[i]=='('){
        count++;
     }
    if(mathEx[i]==')'){
        count--;
     }
     if(count<0){
        break ;
     }
     i++;
     }
     if(count==0){
      cout<<"True !";
     }
     else {
     cout<<"Invalid !"<<endl;
     }
        return 0;
     }