【问题标题】:Checking balanced parentheses in a string with stacks in c用c中的堆栈检查字符串中的平衡括号
【发布时间】:2020-11-23 19:11:46
【问题描述】:

我正在尝试编写一个程序,在其中我使用数组实现堆栈并使用它们来检查给定字符串是否具有平衡括号。

例如。如果输入 '(()){}[()]' ,程序会输出 'Balanced',否则如果输入 '({})[' 程序会输出 'Notbalanced'。

这部分是栈的数组实现。

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

#define MAX 50

int stack[MAX];
int top=-1;

void push(char val){
    if(top==MAX-1){
        printf("stack is already full,error\n");
    
    }else{
        top++;
        stack[top]=val;
    }
}

char pop(){
    if(top==-1){
        printf("not enough elements,error\n");
        exit(1);
    }else{
        top--;
        return stack[top];
    }
}

这部分是解决问题的常用方法的实现。

int isMatching(char c1, char c2){ 
    if(c1=='{' && c2=='}') 
        return 1; 
        
    else if(c1 =='(' && c2==')') 
        return 1; 
        
    else if(c1=='[' && c2==']') 
        return 1; 
    
    return 0; 
} 

int isBalanced(char str[]){
    int i=0;
    
    while(str[i]!='\0'){
        if(str[i]=='{' || str[i]=='[' || str[i]=='('){
            push(str[i]);
        }
        if(str[i]==')' || str[i] == ']' || str[i]=='}'){ 
            if(stack==NULL){
                return 0; 
            }
            if(!isMatching(pop(), str[i])){
                return 0;
            }
        } 
        i++; 

    }
    
    if(stack==NULL){
        return 1; // balanced parenthesis
    }else{
        return 0; // not balanced parenthesis
    }
}

这是用户输入字符串并测试它是否“平衡”的主要功能。

int main(){
    char str[MAX];
    int flag;
    printf("Enter the string with the brackets and etc.\n");
    fgets(str, sizeof(str),stdin); 
    flag=isBalanced(str);
    if(flag==1){
        printf("Balanced\n");
    }
    else{
        printf("Not balanced\n"); 
    }
    
    return 0;
}

当我输入一个非常简单的例子时,我得到一个错误的答案,例如

Enter the string with the brackets and etc.
()
Not balanced

这应该输出“平衡”。我不明白这是怎么发生的。

【问题讨论】:

  • 如果你在 top==0 时调用 pop 那么你将返回 stack[-1] - 这对我来说看起来不对。
  • ...还有if(stack==NULL)...
  • @jmq 为什么会出错?
  • @user5329483 我应该使用不同的条件来检查堆栈是否为空吗?
  • stack[-1] 是错误的,因为使用负数组索引会导致未定义的行为。数组的有效索引是 0-49。

标签: c stack


【解决方案1】:

在 pop() 中,您在返回顶部元素之前递减。变化:

    top--;
    return stack[top];

    return stack[top--];

另外,在 isBalanced() 中,堆栈永远不会为空,所以删除:

        if(stack==NULL){
            return 0; 
        }

并更改平衡检查以从以下位置查找空堆栈:

if(stack==NULL){
    return 1; // balanced parenthesis
}else{
    return 0; // not balanced parenthesis
}

收件人:

if(top==-1){
    return 1; // balanced parenthesis
}else{
    return 0; // not balanced parenthesis
}

进行这些更改后,您的代码似乎可以在我的盒子上运行。这不是我的编码方式,但这是使其工作的最小更改集。

【讨论】:

    【解决方案2】:

    if (stack==NULL) 是这里的问题,堆栈永远不会为 NULL。 您需要通过验证 top &gt; 0

    来检查堆栈中是否还有元素

    【讨论】:

      【解决方案3】:

      您错误地实现了 push/pop 组合。如果你推一个字符top 变成0。如果你立即弹出它,它最终会执行top--; return stack[top],它的计算结果是stack[-1]。

      试试这个推送/弹出:

      int top=-1; //idx to be popped next; <0 -> invalid
      
      void push(char val)
      {
          if(top==MAX-2)
              printf("stack is already full,error\n");
          else
              stack[++top]=val;
      }
      
      char pop()
      {
          if(top<0) return '\0'; //no abort, just return invalid char
          return stack[top--];
      }
      

      【讨论】:

        【解决方案4】:

        您的问题的答案已经得到令人满意的回答,但作为不同方法的建议,请考虑以下内容。

        由于在 C 源代码中只使用了极少数常见的封装,因此您可以使用递增-递减计数器轻松跟踪它们的对。下面使用一个结构体,typedefed 到balanced_s,它被封装到一个函数中以简化评估。以下是一个示例实现:

        typedef struct {
            int paren;
            int curly;
            int square;
            bool bBal
        }balanced_s;
        
        balanced_s * balanced_enclosures(const char *source);
        
        int main(void)
        {
            char in[5000] = {0};//you could improve this by reading file size 
                                //first then creating array sized accordingly
            
            FILE *fp = fopen("C:\\play\\source.c", "r");//using copy of this source to test
            if(fp)
            {
                size_t bytes = fread(in, 1, sizeof(in), fp);
            }
            
            balanced_s * b = balanced_enclosures(in);
            
            bool balanced = b->bBal;//If not true, inspect the rest of the
                                    //members to see where the imbalance has occurred.
            
            free(b);
            
            return 0;
        }
        
        balanced_s * balanced_enclosures(const char *source)
        {
            balanced_s *pBal = malloc(sizeof(*pBal));
            memset(pBal, 0, sizeof(*pBal));
            
            while(*source)
            {
                switch(*source) {
                    case '(':
                        pBal->paren++;
                        break;
                    case ')':
                        pBal->paren--;
                        break;
                    case '{':
                        pBal->curly++;
                        break;
                    case '}':
                        pBal->curly--;
                        break;
                    case '[':
                        pBal->square++;
                        break;
                    case ']':
                        pBal->square--;
                        break;
                }
                source++;
                pBal->bBal = (!pBal->paren && !pBal->curly && !pBal->square);
            }
            return pBal;
        }
        

        【讨论】:

          猜你喜欢
          • 2021-11-30
          • 2016-06-26
          • 2017-06-10
          • 2016-09-06
          • 2021-03-06
          • 2021-06-05
          • 2018-06-23
          • 1970-01-01
          • 2018-04-23
          相关资源
          最近更新 更多