使用栈的括号配对问题

本人数据结构初学者,刚学到堆栈,对这个括号匹配问题没有足够的了解,希望大家能帮我解答一下
我在编写isemtpy push pop这三个函数的时候没有思路,希望得到大家的帮助
以下是代码:

stack.h文件

#ifndef __ANTTI_STACK_H
#define __ANTTI_STACK_H

#include <stdbool.h> // Defines bool type for C.

// Can only put 100 items in stack.
//static const int MAX_SIZE = 100;
#define MAX_SIZE 100
// Values for errors, do not use magic numbers in code.
static const int ERR_STACK_FULL = -1;
static const char ERR_STACK_EMPTY = '!';

// Definition of a stack structure with static size.
typedef struct stack_s {
   char elements[MAX_SIZE];
   int count;
} stack;

/**
 Initializes the stack passed as a parameter.
 @param aStack The stack struct to initialize.
 */
void init(stack * aStack);
/**
 Checks if a stack is empty.
 @param aStack The stack to check.
 @return Returns true if the stack is empty.
 */
bool is_empty(const stack * aStack);
/**
 Pushes an item to the stack.
 @param aStack The stack to push the item into.
 @param aSymbol The thing to put into the stack.
 @return Returns the count of items in the stack or ERR_STACK_FULL if no room for new items.
 */
int push(stack * aStack, char aSymbol);
/**
 Pops an item out of the stack.
 @param aStack The stack from where an item is popped out.
 @return Returns the item that was popped out from the top, or ERR_STACK_EMPTY if stack has no items.
 */
char pop(stack * aStack);
/**
 For debugging and studying what is in the stack.
 @param aStack The contenst of this stack are printed out.
 */
void print(const stack * aStack);

#endif // __ANTTI_STACK_H

stack.c文件

#include <stdio.h>
#include "stack.h"

// Implementation of stack functions

// It would not be necessary to fill the stack array with
// zeroes in init() nor in pop() for the removed item,
// since values outside of indexes 0..<stack.count
// are not considered anyways. Just being overly cautious.

void init(stack * aStack) {
   aStack->count = 0;
}

/**
 Checks if a stack is empty.
 @param aStack The stack to check.
 @return Returns true if the stack is empty.
 TODO: Implement function is_empty so that it reutrns true
       if the aStack is empty.
 HINT: What is current count if stack is empty?
 */
bool is_empty(const stack * aStack) {
   
}

/**
 Pushes an item to the stack.
 @param aStack The stack to push the item into.
 @param aSymbol The thing to put into the stack.
 @return Returns the count of items in the stack or ERR_STACK_FULL if no room for new items.
 TODO: Implement push fucntion so that it pushes the character aSymbol to stack it there is
       room in the stack and returns the new count. If there is no more room,
       it should return ERR_STACK_FULL
 HINT: What is the maximum size of the stack?
 */
int push(stack * aStack, char aSymbol) {

}

/**
 Pops an item out of the stack.
 @param aStack The stack from where an item is popped out.
 @return Returns the item that was popped out from the top, or ERR_STACK_EMPTY if stack has no items.
 TODO: Implement pop function so that it returns the top most character of the stack.
 HINT1: Remember count.
 Hint2: You might need to store the character to return it.
 */
char pop(stack * aStack) {

}

void print(const stack * aStack) {
   printf("Stack has %d items: ", aStack->count);
   for (int index = 0; index < aStack->count; index++) {
      printf("%c ", aStack->elements[index]);
   }
   printf("\n");
}

stack_main.c文件

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

#include "stack.h"

// Max string length we will handle is 255 chars.
const int MAX_STRING_LENGTH = 256;

// For usage of startup params, see the instruction printouts below.
int main(int argc, char * argv[]) {
   if (argc < 2 || argc > 3) {
      printf("Usage: %s [-v] <string>\n", argv[0]);
      printf("  Checks the string in quotation marks for matching parentheses. String max len is 255 chars.\n");
      printf("  Use option -v tool to print out more detailed logs.\n");
      printf("  Example run: %s -v \"int main() { for (int x = 0; x < 10\"\n", argv[0]);
      return EXIT_FAILURE;
   }
   char toCheck[MAX_STRING_LENGTH];  // Here we will put the string to check
   bool verbose = false;             // If option -v is there, will printout more stuff.
   int indexOfStringToCheck = 1;
   switch (argc) {                   // Check how many params we got.
      case 3:
         if (strcmp(argv[1], "-v") == 0) {
            verbose = true;
         }
         indexOfStringToCheck = 2;
         // Intentional fallthrough, no break!
      case 2:
         strncpy(toCheck, argv[indexOfStringToCheck], sizeof(toCheck));
         break;
   }
   printf("Analyzing string:\n");
   printf("%s\n", toCheck);
   for (int index = 0; index < strlen(toCheck); index++) {
      printf("%d", index % 10);
   }
   printf("\n");

   // Prepare the stack for work.
   stack aStack;
   init(&aStack);

   // Go through each char in the string. Note that this is not unicode friendly,
   // so special chars in input may cause issues...
   for (int index = 0; index < strlen(toCheck); index++) {
      // If we found opening char, push the item into the stack.
      char current = toCheck[index];
      if (current == '(' || current == '{' || current == '[') {
         if (push(&aStack, current) == ERR_STACK_FULL) {
            printf("! ERROR: Stack is full, too complicated text to analyse.\n");
            return EXIT_FAILURE;
         } else {
            if (verbose) printf("Pushed %c to stack.\n", current);
         }
      // We found closing ) so we pop up the index of previous opening char from the stack.
      } else if (current == ')' || current == '}' || current == ']') {
         char fromStack = pop(&aStack);
         if (fromStack == ERR_STACK_EMPTY) {
            printf("! ERROR: Mismatching parentheses (too many closing parentheses at index %d\n", index);
            return EXIT_FAILURE;
         } else {
            if (verbose) printf("Popped %c from stack.\n", fromStack);
            bool wrongKindOfItemPopped = false;
            switch (current) {
            case ')':
               if (fromStack != '(') wrongKindOfItemPopped = true;
               break;
            case '}':
               if (fromStack != '{') wrongKindOfItemPopped = true;
               break;
            case ']':
               if (fromStack != '[') wrongKindOfItemPopped = true;
               break;
            }
            if (wrongKindOfItemPopped) {
               printf("! ERROR, met mismatching parenthesis %c at index %d\n", current, index);
               return EXIT_FAILURE;
            }
         }
      }
      if (verbose) print(&aStack);
   }
   if (verbose) print(&aStack);
   // Stack should be empty if matching parentheses were found.
   if (!is_empty(&aStack)) {
      printf("! ERROR: Not enough closing parentheses, %d missing.\n", aStack.count);
      return EXIT_FAILURE;
   }
   printf(" >> Text has correct use of parentheses.\n");
   return EXIT_SUCCESS;
}

首先,你要知道栈是怎样的数据结构, 在栈顶进行插入,或者取栈顶的值。
然后使用栈处理括号匹配的问题:
括号匹配刚好有个特性,'('和')'的个数是一一对应,并且先有'(',在有')',那字符串匹配问题,是不是可以转换为:
===》往栈中放数据,如果遇到'('就放进栈中,如果遇到')'就取出,中间有异常情况就是不匹配,或者最后有剩余是不匹配。

你这里是用数组以及数组的下标(同时也可以说明当前数组中元素的个数),模拟栈(放数据都是从数组下标零开始放,取从最大取)。
isempty() 是判断栈中是否有元素的函数,你只需要判断个数(count)等不等于0,为0说明是空的
push() 模拟的是往栈中放数据,你给count对应数组下标下标下放数据,并且count表示以及放了多少个。
pop() 取栈顶数据,也就是刚放进去的数据,也就是count-1对应的下标的数据,取出去后,count-1下次在这个位置放数据。

这是思路,代码你可以参考网上有现成的。。。

img

望采纳
stack.c


#include <stdio.h>
#include "stack.h"

// Implementation of stack functions

// It would not be necessary to fill the stack array with
// zeroes in init() nor in pop() for the removed item,
// since values outside of indexes 0..<stack.count
// are not considered anyways. Just being overly cautious.

void init(stack *aStack)
{
    aStack->count = 0;
}

/**
 Checks if a stack is empty.
 @param aStack The stack to check.
 @return Returns true if the stack is empty.
  Implement function is_empty so that it reutrns true
       if the aStack is empty.
 HINT: What is current count if stack is empty?
 */
bool is_empty(const stack *aStack)
{
    return aStack->count == 0;
}

/**
 Pushes an item to the stack.
 @param aStack The stack to push the item into.
 @param aSymbol The thing to put into the stack.
 @return Returns the count of items in the stack or ERR_STACK_FULL if no room for new items.
  Implement push fucntion so that it pushes the character aSymbol to stack it there is
       room in the stack and returns the new count. If there is no more room,
       it should return ERR_STACK_FULL
 HINT: What is the maximum size of the stack?
 */
int push(stack *aStack, char aSymbol)
{
    if (aStack->count < MAX_SIZE)
    {
        aStack->elements[aStack->count] = aSymbol;
        aStack->count++;
        return aStack->count;
    }
    else
    {
        return ERR_STACK_FULL;
    }
}

/**
 Pops an item out of the stack.
 @param aStack The stack from where an item is popped out.
 @return Returns the item that was popped out from the top, or ERR_STACK_EMPTY if stack has no items.
 Implement pop function so that it returns the top most character of the stack.
 HINT1: Remember count.
 Hint2: You might need to store the character to return it.
 */
char pop(stack *aStack)
{
    if (aStack->count > 0)
    {
        char popped = aStack->elements[aStack->count - 1];
        aStack->count--;
        return popped;
    }
    else
    {
        return ERR_STACK_EMPTY;
    }
}

void print(const stack *aStack)
{
    printf("Stack has %d items: ", aStack->count);
    for (int index = 0; index < aStack->count; index++)
    {
        printf("%c ", aStack->elements[index]);
    }
    printf("\n");
}