You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归+栈生成有效括号仅输出首个结果的问题排查

生成n对有效括号组合的问题排查

问题描述

给定n对括号,编写函数生成所有有效括号组合。

实现方案(C语言)

我采用递归方式实现了gen_para函数,通过栈构建有效括号序列,当序列完整时打印,再通过递归弹出栈元素探索其他可能序列:

void gen_para(Stack* s, int n, int opened, int closed) { // recursive
    if (n == opened && n == closed) {
        print_s(s);
        // clear_s(s);
    }
    else if (opened < n) {
        push(s, '(');
        gen_para(s, n, opened + 1, closed);
        pop(s);
    }
    else if (closed < opened) {
        push(s, ')');
        gen_para(s, n, opened, closed + 1);
        pop(s);
    }
}

以下是完整的栈实现代码:

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

typedef struct Node {
    char data;
    struct Node* next;
} Node;

typedef struct Stack {
    char size;
    Node* head;
    Node* tail;
} Stack;

const Stack stack_init = { .size = 0, .head = NULL, .tail = NULL };

Node* create_node(char elm) {
    Node* node = malloc(sizeof * node);
    if (!node) return node;
    node->data = elm;
    node->next = NULL;
    return node;
}

Stack* create_stack() {
    Stack* s = malloc(sizeof * s);
    s->size = 0;
    s->head = NULL;
    s->tail = NULL;
    return s;
}

int is_empty_s(Stack *s) {
    return s->tail == NULL;
}

void push(Stack *s, char elm) {
    Node* updated_head = create_node(elm);
    if (!s->head) {
        s->head = updated_head;
        s->tail = s->head;
    } else {
        updated_head->next = s->head;
        s->head = updated_head;
    }
    s->size++;
}

char pop(Stack *s) {
    if (!is_empty_s(s)) {
        Node* node = s->head;
        char elm = node->data;
        s->head = s->head->next;
        if (!s->head)
            s->tail = NULL;
        s->size--;
        free(node);
        return elm;
    }
    return 'N';
    
}

char top(Stack *s) {
    char top;
    if (s->head)
        top = s->head->data;
    else
        top = 'N';
    return top;
}

void clear_s(Stack *s) {
    while (s->tail)
        pop(s);
}

Stack* reverse_it(Stack *s) {
    Stack *s2 = malloc(sizeof *s2);
    if (!s2) return s2;
    *s2 = stack_init;

    while (s->tail)
        push(s2, pop(s));
    s->head = s2->head;
    return s;
}

void print_s(Stack *s) { 
    if (!is_empty_s(s)) {
        char data = pop(s);
        // or place here instead printf("%c", data); if you want to print the other way
        print_s(s);
        printf("%c", data);
        push(s, data);
    }
}

int main() {
    Stack s1 = stack_init;
    int n = 2;
    gen_para(&s1, n, 0, 0);
    return 0;
}

遇到的问题

当n=2时,预期输出为(())和()(),但实际仅输出第一个结果。排查发现生成第二个序列的递归调用前栈是空的,无法定位问题。

问题原因与解决方法

问题核心在gen_para的分支判断逻辑:你用else if处理closed < opened的情况,这导致只有当opened < n不成立时,才会进入添加右括号的分支。但实际上,即使opened < n成立,只要closed < opened,我们也需要尝试添加右括号——这才是遍历所有有效路径的关键。

举个具体场景:当n=2,栈内已有一个((此时opened=1,closed=0),opened < n条件成立,原代码只会进入添加左括号的分支,完全漏掉了添加右括号生成()()的路径。

修改方式很简单,把两个else if改成独立的if,让两个分支可以并行判断:

void gen_para(Stack* s, int n, int opened, int closed) { // recursive
    if (n == opened && n == closed) {
        print_s(s);
        printf("\n"); // 可选:添加换行让输出更清晰
        // clear_s(s);
    }
    if (opened < n) { // 去掉else,改为独立if
        push(s, '(');
        gen_para(s, n, opened + 1, closed);
        pop(s);
    }
    if (closed < opened) { // 去掉else,改为独立if
        push(s, ')');
        gen_para(s, n, opened, closed + 1);
        pop(s);
    }
}

另外,原print_s函数打印时没有换行,两个结果会连在一起,建议添加换行来区分不同序列。

修改后程序即可正确生成所有有效括号组合。

内容的提问来源于stack exchange,提问作者v_head

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 12:40:14