сопоставление скобок с использованием двусвязного списка в c ++ - PullRequest
0 голосов
/ 21 мая 2018

Я пытаюсь создать программу сопоставления скобок, используя двусвязный список в c ++. Я подтвердил, что мой класс Dlink работает, когда я пробую один класс Dlink.однако, когда я делаю объект Dlink внутри моего класса с круглыми скобками, персонаж, похоже, не попадает в двусвязный список.Я не могу найти, где я испортил код.

вот код:

#include "stdafx.h"
#include <iostream> 
#include <cstdlib>
using namespace std;

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


class Dlink {
private:
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();
    int n;
private:
    DNode * head;
    DNode *tail;
};


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() {
    cout << front() << endl;
}

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

parenthesis::parenthesis(char str[], int size) {
    str = str;
    i = size;
}

parenthesis::~parenthesis() {}

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

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

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

bool parenthesis::domatch() {
    if (isclose(str[j])) {
        return false;
    }
    else if (isopen(str[j])) {
        d.addfront(str[j]);
        flag = 1;
        j++;
    }
    if (flag == 1) {
        for (j; j < i; j++)
        {
            if (isopen(str[j])) {
                d.addfront(str[j]);
            }                     
            else if (isclose(str[j])) {                                     
                if (type(d.front()) == type(str[j])) d.removefront();   
                else {
                    return false;
                }
            }
        }
        if (!d.empty()) return false;
        else return true;
    }
}

int main() {
    char str[20];
    cout << "enter string" << endl;
    cin >> str;
    parenthesis p1 = parenthesis(str, strlen(str));
    return p1.domatch();
}

1 Ответ

0 голосов
/ 21 мая 2018

Ваш класс DLink испытывает нарушение правила 3 ​​.Он получил повторяемость для цепочки узлов.

 parenthesis p1 = parenthesis(str, strlen(str));

Эта инициализация не будет работать, потому что DLink не имеет надлежащего конструктора копирования. Указатели останутся висящими после временных экземпляров parenthesis и * 1007.* внутри него уничтожено.

Простое решение - использовать умный указатель в DLink, который будет следовать правилу всего или ничего, тогда как умный указатель уничтожит список только тогда, когда он больше не используется.Или создайте конструктор копирования или перемещения, если назначение не позволяет использовать библиотечные классы.

Просто для назначения вы можете вообще избежать использования временного объекта, но вы должны знать об этой ловушке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...