顺序栈的应用--括号匹配

括号匹配是一个在计算机科学和编程中常见的问题,通常涉及到检查一个字符串中的括号是否正确地配对。这通常意味着每一个开括号(如 {([)都必须有一个对应的闭括号(如 })]),并且它们的顺序必须是正确的。

下面是一个简单的括号匹配的算法:

  1. 初始化一个空栈,将栈底设为“#”。
  2. 遍历字符串中的每一个字符。
  3. 如果当前字符是一个开括号({([),则将其压入栈中。
  4. 如果当前字符是一个闭括号(})]),则检查栈顶元素是否是一个对应的开括号。如果是,则从栈中弹出该开括号;如果不是,或者栈为空,则字符串中的括号不匹配。
  5. 遍历完字符串后,检查弹出是否为“#”。如果为“#”,则字符串中的括号匹配;否则,不匹配。

这个算法的时间复杂度是 O(n),其中 n 是字符串的长度。它只需要一次遍历字符串,并且每个字符的处理时间都是常数。

下面是实现代码:

首先是创建一个栈以及实现压栈出栈功能:

#include<iostream>
using namespace std;

const int STACK_MAX_SIZE = 10;

typedef struct CharStack {
    int top;

    char data[STACK_MAX_SIZE];
} *CharStackPtr;

void outputStack(CharStackPtr paraStack) {
    for (int i = 0; i <= paraStack->top; i++) {
        printf("%c ", paraStack->data[i]);
    }
    printf("\r\n");
}

CharStackPtr charStackInit() {
    CharStackPtr resultPtr = (CharStackPtr)malloc(sizeof(struct CharStack));
    resultPtr -> top = -1;

    return resultPtr;
}

void push(CharStackPtr paraStackPtr, int paraValue) {

    if (paraStackPtr->top >= STACK_MAX_SIZE - 1) {
        printf("Cannot push element: stack full.\r\n");
        return;
    }

    paraStackPtr->top++;

    paraStackPtr->data[paraStackPtr->top] = paraValue;
}

char pop(CharStackPtr paraStackPtr) {
    if (paraStackPtr->top < 0) {
        printf("Cannot pop element: stack empty.\r\n");
        return '\0';
    }

    paraStackPtr->top--;

        return paraStackPtr->data[paraStackPtr->top + 1];
}

void pushPopTest() {
    printf("---- pushPopTest begins. ----\r\n");
    char ch;

    CharStackPtr tempStack = charStackInit();
    printf("After initialization, the stack is: ");
    outputStack(tempStack);

    for (ch = 'a'; ch < 'm'; ch++) {
        printf("Pushing %c.\r\n", ch);
        push(tempStack, ch);
        outputStack(tempStack);
    }

    for (int i = 0; i < 3; i++) {
        ch = pop(tempStack);
        printf("Pop %c.\r\n", ch);
        outputStack(tempStack);
    }
    printf("---- pushPopTest ends. ----\r\n");
}

然后是实现括号匹配算法以及测试函数:

#include<iostream>
using namespace std;

bool bracketMatching(char* paraString, int paraLength) {
    CharStackPtr tempStack = charStackInit();
    push(tempStack, '#');
    char tempChar, tempPopedChar;

    for (int i = 0; i < paraLength; i++) {
        tempChar = paraString[i];

        switch (tempChar) {
        case'(':
        case'[':
        case'{':
            push(tempStack, tempChar);
            break;
        case')':
            tempPopedChar = pop(tempStack);
            if (tempPopedChar != '(') {
                return false;
            }
            break;
        case']':
            tempPopedChar = pop(tempStack);
            if (tempPopedChar != '[') {
                return false;
            }
            break;
        case'}':
            tempPopedChar = pop(tempStack);
            if (tempPopedChar != '{') {
                return false;
            }
            break;
        default:
            break;
        }
    }
    tempPopedChar = pop(tempStack);
    if (tempPopedChar != '#') {
        return false;
    }
    return true;
}
void bracketMatchingTest() {
    char* tempExpression = "[2 + (1 - 3)] * 4";
    bool tempMatch = bracketMatching(tempExpression, 17);
    printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);


    tempExpression = "( )  )";
    tempMatch = bracketMatching(tempExpression, 6);
    printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);

    tempExpression = "()()(())";
    tempMatch = bracketMatching(tempExpression, 8);
    printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);

    tempExpression = "({}[])";
    tempMatch = bracketMatching(tempExpression, 6);
    printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);


    tempExpression = ")(";
    tempMatch = bracketMatching(tempExpression, 2);
    printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);
}

int main() {
    bracketMatchingTest();
}

 

 下面为流程图:

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: C语言中可以使用顺序表来实现数组,也可以使用链表来实现动态分配内存的数据结构。如果想要实现哈希表,可以使用结构体数组和链表结合的方式来实现。 对于顺序表实现数组,可以通过定义一个固定长度的数组来存储数据,并且可以通过下标索引来访问数组中的元素。例如: ``` #define MAXSIZE 100 int array[MAXSIZE]; ``` 对于链表实现动态分配内存的数据结构,可以使用结构体来定义每一个节点,并且节点中包含一个指向下一个节点的指针。例如: ``` struct Node { int data; struct Node *next; }; ``` 对于哈希表的实现,可以使用结构体数组来表示哈希表中的每一个元素,每个元素可以包含一个链表,用来存储具有相同哈希值的元素。例如: ``` #define HASHSIZE 100 struct Node { int data; struct Node *next; }; struct HashTable { struct Node *list; }; struct HashTable hashtable[HASHSIZE]; ``` 在使用哈希表时,可以通过计算每个元素的哈希值,将元素存储到对应的链表中。当需要查找元素时,只需要计算出元素的哈希值,然后在对应的链表中查找即可。 ### 回答2: C语言中可以使用顺序栈来实现括号匹配。 首先,我们需要定义一个结构体来表示顺序栈,包括栈的最大容量和当前的栈顶指针。可以使用一个一维数组来实现栈的存储。 然后,我们需要实现两个基本的操作:入栈和出栈。入栈操作将一个元素添加到栈的顶部,出栈操作将栈顶的元素移除。 在进行括号匹配时,我们可以遍历输入的字符串中的每个字符。当遇到左括号时,我们将其入栈;当遇到右括号时,我们将其与栈顶元素进行匹配。如果栈顶元素为对应的左括号,则将栈顶元素出栈;否则,表示括号不匹配。 当遍历完所有字符后,如果栈为空,说明所有的括号都匹配成功。如果栈不为空,说明还有未匹配的括号。 以下是一个用C语言实现括号匹配的示例代码: ```c #include <stdio.h> #define MAX_SIZE 100 // 定义顺序栈结构体 typedef struct { char data[MAX_SIZE]; int top; } Stack; // 初始化栈 void init(Stack *stack) { stack->top = -1; } // 判断栈是否为空 int isEmpty(Stack *stack) { return stack->top == -1; } // 入栈 void push(Stack *stack, char c) { if (stack->top == MAX_SIZE - 1) { printf("Stack is full\n"); return; } stack->data[++(stack->top)] = c; } // 出栈 char pop(Stack *stack) { if (isEmpty(stack)) { printf("Stack is empty\n"); return '\0'; } return stack->data[(stack->top)--]; } // 括号匹配 int matchBrackets(char *str) { Stack stack; init(&stack); int i = 0; while (str[i] != '\0') { if (str[i] == '(' || str[i] == '[' || str[i] == '{') { push(&stack, str[i]); } else if (str[i] == ')' || str[i] == ']' || str[i] == '}') { if (isEmpty(&stack)) { return 0; } char topChar = pop(&stack); if ((str[i] == ')' && topChar != '(') || (str[i] == ']' && topChar != '[') || (str[i] == '}' && topChar != '{')) { return 0; } } i++; } return isEmpty(&stack); } int main() { char *str = "[()]{}{[()()]()}"; if (matchBrackets(str)) { printf("括号匹配成功\n"); } else { printf("括号匹配失败\n"); } return 0; } ``` 以上示例中,我们使用了一个字符数组来表示输入的字符串,并定义了一个`Stack`结构体来实现顺序栈。在`matchBrackets`函数中,我们遍历输入字符串的每个字符,并根据字符的类型进行相应的操作。最后,根据栈是否为空来判断括号是否匹配成功,并输出结果。 注意,在实际应用中,我们可能还需要处理其他的情况,如字符不是括号或者存在其他字符等。这里的示例只是简单地实现了括号匹配的基本逻辑。 ### 回答3: C语言可以用顺序栈实现括号匹配。首先,我们需要定义一个存储括号的顺序栈结构,其中包含一个数组用来存放括号元素,以及一个指针top来指示栈顶位置。 当开始遍历表达式时,我们遇到左括号时,将其入栈,当遇到右括号时,我们将比较栈顶元素与当前括号是否匹配。如果匹配,则弹出栈顶元素,继续遍历;如果不匹配,表明括号不匹配,直接返回不匹配的结果。 在遍历完成后,如果栈为空,则说明所有括号都匹配成功,如果栈不为空,则说明有括号没有匹配成功,返回括号不匹配的结果。 以下是用C语言实现括号匹配的代码: ```c #include <stdio.h> #include <stdbool.h> #define MAX_SIZE 50 typedef struct { char data[MAX_SIZE]; int top; } Stack; void init(Stack *stack) { stack->top = -1; } bool isEmpty(Stack *stack) { return stack->top == -1; } void push(Stack *stack, char c) { if(stack->top == MAX_SIZE - 1) { printf("Stack overflow!\n"); return; } stack->data[++(stack->top)] = c; } char pop(Stack *stack) { if(isEmpty(stack)) { printf("Stack underflow!\n"); return '\0'; } return stack->data[(stack->top)--]; } bool isMatching(char left, char right) { if(left == '(' && right == ')') return true; else if(left == '[' && right == ']') return true; else if(left == '{' && right == '}') return true; else return false; } bool isBalanced(char expression[]) { Stack stack; init(&stack); for(int i = 0; expression[i] != '\0'; i++) { if(expression[i] == '(' || expression[i] == '[' || expression[i] == '{') { push(&stack, expression[i]); } else if(expression[i] == ')' || expression[i] == ']' || expression[i] == '}') { if(isEmpty(&stack) || !isMatching(pop(&stack), expression[i])) { return false; } } } return isEmpty(&stack); } int main() { char expression[MAX_SIZE]; printf("请输入一个表达式:"); scanf("%s", expression); if(isBalanced(expression)) { printf("括号匹配成功!\n"); } else { printf("括号匹配失败!\n"); } return 0; } ``` 在这个实现中,我们用init()函数初始化了栈,用isEmpty()函数判断栈是否为空,用push()函数将元素入栈,用pop()函数弹出栈顶元素。isMatching()函数用来判断两个括号是否匹配。isBalanced()函数用来检查整个表达式的括号是否匹配。在主函数中,我们首先输入一个表达式,然后调用isBalanced()函数判断括号是否匹配,并输出结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值