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

C++中基于双向链表的括号匹配程序代码问题求助

问题分析与修正方案

我帮你排查了代码里的几个关键问题,这些问题直接导致了括号匹配类里的双向链表无法正确存储字符,咱们一个个拆解来看:

1. 构造函数中字符串拷贝完全无效

你的parenthesis类构造函数里写的str = str;是典型的无效操作——这里只是把参数的指针赋值给了成员数组名(数组名退化为指针后,这样的赋值并不会拷贝字符串内容),导致成员变量str根本没拿到用户输入的括号字符串。后面domatch函数访问str[j]时,拿到的都是未初始化的垃圾值,自然没法把正确的括号存入链表。

修正方法:用strcpy(需要额外包含<cstring>头文件)把传入的字符串拷贝到成员数组里:

parenthesis::parenthesis(char str[], int size) {
    strcpy(this->str, str); // 替换原来的str = str;
    i = size;
    flag = 0; // 顺便初始化flag,避免随机值干扰逻辑
    j = 0;
}

2. 未初始化的成员变量引发逻辑混乱

parenthesis类里的flag没有初始化,默认是随机值,会导致domatch函数的分支判断混乱(比如可能直接跳过核心的匹配循环)。必须在构造函数里把它初始化为0。

3. 右括号匹配时的边界检查缺失

当遇到右括号时,你没有先检查链表是否为空。如果链表为空(比如前面没有对应的左括号),直接调用d.front()会访问tail节点的data(空链表时head->next指向tail),而tail的data从未被赋值,这会导致程序崩溃或者错误结果。

修正方法:处理右括号前先判断链表是否为空:

else if (isclose(str[j])) {
    if (d.empty()) { // 新增:链表为空,说明没有对应的左括号
        return false;
    }
    if (type(d.front()) == type(str[j])) 
        d.removefront();
    else {
        return false;
    }
}

4. type函数缺少默认返回值

如果传入的字符不是括号,type函数没有返回值,会返回随机值,可能导致匹配逻辑错误。需要添加默认返回值:

int parenthesis::type(char a) {
    if (a == ')' || a == '(') return 1;
    else if (a == '}' || a == '{') return 2;
    else if (a == ']' || a == '[') return 3;
    return 0; // 新增:默认返回值,处理非括号字符
}

5. 辅助函数的调试优化

你的Dlink::print函数只输出第一个元素,不利于调试。可以修改为遍历整个链表输出所有元素:

void Dlink::print() {
    DNode* current = head->next;
    while (current != tail) {
        cout << current->data << " ";
        current = current->next;
    }
    cout << endl;
}

6. main函数的输出与返回值优化

main函数直接返回domatch()的bool值虽然可以,但不如直接输出匹配结果更直观:

int main() {
    char str[20];
    cout << "enter string" << endl;
    cin >> str;
    parenthesis p1(str, strlen(str)); // 这里不需要用赋值构造,直接初始化即可
    if (p1.domatch()) {
        cout << "括号匹配成功!" << endl;
    } else {
        cout << "括号匹配失败!" << endl;
    }
    return 0;
}

修正后的完整代码

#include "stdafx.h" 
#include <iostream> 
#include <cstdlib>
#include <cstring> // 新增:用于strcpy
using namespace std; 

class DNode {
private:
    char data;
    DNode *next;
    DNode *prev;
    friend class Dlink;
};

class Dlink {
private:
    DNode * head;
    DNode *tail;
    int n;
public:
    Dlink();
    ~Dlink();
    bool empty() const;
    void addfront(char);
    void removefront();
    void addback(char);
    void removeback();
    void add(DNode*, const char);
    void remove(DNode *);
    const char& front() const;
    const char& back() const;
    int size();
    void print();
};

Dlink::Dlink() {
    head = new DNode;
    tail = new DNode;
    head->next = tail;
    tail->prev = head;
    n = 0;
}

Dlink::~Dlink() {
    while (!empty()) removefront();
    delete head;
    delete tail;
}

void Dlink::add(DNode *v, const char e) {
    DNode *u = new DNode;
    u->data = e;
    u->next = v;
    u->prev = v->prev;
    v->prev->next = u;
    v->prev = u;
    n++;
}

void Dlink::addfront(const char e) {
    add(head->next, e);
}

void Dlink::addback(const char e) {
    add(tail, e);
}

void Dlink::remove(DNode *v) {
    DNode *u = v->prev;
    DNode *w = v->next;
    u->next = w;
    w->prev = u;
    delete v;
    n--;
}

void Dlink::removefront() {
    remove(head->next);
}

void Dlink::removeback() {
    remove(tail->prev);
}

bool Dlink::empty() const {
    return (head->next == tail);
}

const char& Dlink::front() const {
    return head->next->data;
}

const char& Dlink::back() const {
    return tail->prev->data;
}

int Dlink::size() {
    return n;
}

void Dlink::print() {
    DNode* current = head->next;
    while (current != tail) {
        cout << current->data << " ";
        current = current->next;
    }
    cout << endl;
}

class parenthesis {
private:
    Dlink d;
    char str[20];
    int i;
    int flag;
    int j;
public:
    parenthesis(char[], int);
    ~parenthesis();
    bool domatch();
    bool isopen(char);
    bool isclose(char);
    int type(char);
};

parenthesis::parenthesis(char str[], int size) {
    strcpy(this->str, str);
    i = size;
    flag = 0;
    j = 0;
}

parenthesis::~parenthesis() {}

bool parenthesis::isopen(char a) {
    return (a == '(' || a == '{' || a == '[');
}

bool parenthesis::isclose(char a) {
    return (a == ')' || a == '}' || a == ']');
}

int parenthesis::type(char a) {
    if (a == ')' || a == '(') return 1;
    else if (a == '}' || a == '{') return 2;
    else if (a == ']' || a == '[') return 3;
    return 0;
}

bool parenthesis::domatch() {
    // 处理第一个字符是右括号的情况
    if (j < i && isclose(str[j])) {
        return false;
    }
    // 遍历所有字符
    while (j < i) {
        if (isopen(str[j])) {
            d.addfront(str[j]);
        } else if (isclose(str[j])) {
            if (d.empty()) {
                return false;
            }
            if (type(d.front()) == type(str[j])) {
                d.removefront();
            } else {
                return false;
            }
        }
        j++;
    }
    // 最后检查链表是否为空
    return d.empty();
}

int main() {
    char str[20];
    cout << "enter string" << endl;
    cin >> str;
    parenthesis p1(str, strlen(str));
    if (p1.domatch()) {
        cout << "括号匹配成功!" << endl;
    } else {
        cout << "括号匹配失败!" << endl;
    }
    return 0;
}

现在测试这个代码,输入{[()]}会输出匹配成功,输入{[(])}会输出失败,输入(()也会失败,完全符合预期。

内容的提问来源于stack exchange,提问作者鞙れ頃�,c++;doubly-linked-list;parentheses"

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:30:05