繁体   English   中英

C ++-将析构函数用于导致奇怪行为的类

[英]C++ - Using destructor for a class leading to weird behavior [duplicate]

我使用联合查找编写了一个用于渗滤的程序( 有关详细信息,请参见此处

联合查找:

#include<iostream>

class UF {
    protected:
        int N;
        int *connections;
        int *sz;
        int *maxObj;
        int numComponents;

        int _getRoot(int p) {
            while(p != connections[p]) {
                // Path compression
                connections[p] = connections[connections[p]];
                p = connections[p];
            }
            return p;
        }

    public:
        UF() {}

        // Parametrized constructor
        UF(int n) {
            N = numComponents = n;
            connections = new int[n];
            maxObj = new int[n];
            sz = new int[n];
            for(int i = 0; i<n; i++) {
                connections[i] = i;
                sz[i] = 1;
                maxObj[i] = i;
            } 
        }

        // ~UF() {
        //     delete [] connections;
        //     delete [] sz;
        //     delete [] maxObj;
        // }

        int findMax(int i) {
            int root = _getRoot(i);
            return maxObj[root];
        }

        int isConnectedGraph() {
            std::cout << "No of components: " << numComponents << std::endl;
            return numComponents == 1;
        }

        bool isConnected(int p, int q) {
            return connections[p] == connections[q];
        }

        bool find(int p, int q) {
            return _getRoot(p) == _getRoot(q);
        }

        void quickFind(int p, int q) {
            // Eager algorithm
            int label_p = connections[p];
            int label_q = connections[q];
            for(int i=0; i<N; i++) {
                if(connections[i] == label_p || connections [i] == label_q) {
                    connections[i] = label_q;
                }
            }
        }

        void quickUnion(int p, int q) {
            // Lazy approach
            if(!isConnected(p, q)) {
                int p_root = _getRoot(p); 
                int q_root = _getRoot(q);
                int max = p_root > q_root ? p_root : q_root;
                // Weighted quick union
                if(sz[p_root] < sz[q_root]) {
                    connections[p_root] = q_root;
                    sz[q_root] += sz[p_root];
                    maxObj[q_root] = max;
                } else {
                    connections[q_root] = p_root;
                    sz[p_root] += sz[q_root];
                    maxObj[p_root] = max;
                }
                numComponents -= 1;
            }
        }

        void printConnectedComponents() {
            std::cout << "Indices:" << std::endl;
            for (int i = 0; i < N; i++) {
                std::cout << i << " ";
            }
            std::cout << std::endl;
            std::cout << "Connections:" << std::endl;
            for (int i = 0; i < N; i++) {
                std::cout << connections[i] << " ";
            }
            std::cout << std::endl;
            std::cout << "Sizes:" << std::endl;
            for (int i = 0; i < N; i++) {
                std::cout << sz[i] << " ";
            }
            std::cout << std::endl;
        }
};

渗滤:

#include "../union-find.h"

class Percolation {
    private:
        int **grid;
        int N;
        UF uf;
        int totalOpenSites;
        int site(int row, int col) {
            if(row == 0) {
                return 0;
            }
            if(row == N-1) {
                return (N*N)-(2*N)+1;
            }
            return ((row-1)*N)+col+1;
        }
    public:
        Percolation(int n) {
            N = n;
            grid = new int*[n];
            for (int i=0; i < n; i++) {
                grid[i] = new int[n];
                for(int j=0; j<n; j++) {
                    grid[i][j] = 0;               
                }
            }
            uf = UF((n*n)-(2*n)+2);
            totalOpenSites=0;
        }

        ~Percolation() {
            for (int i=0; i<N; i++) {
                delete [] grid[i];
            }
            delete [] grid;
        }

        void open(int row, int col) {
            if(!isOpen(row, col)) {
                int center = site(row, col);
                // std::cout << "Center site: " << center << std::endl;
                grid[row][col]=1;
                if(row-1 >= 0 && grid[row-1][col]) {
                    int north = site(row-1, col);
                    // std::cout << "North site: " << north << std::endl;
                    uf.quickUnion(center, north);
                }
                if(row+1 < N && grid[row+1][col]) {
                    int south = site(row+1, col);
                    // std::cout << "South site: " << south << std::endl;
                    uf.quickUnion(south, center);
                }
                if(col-1 >= 0 && grid[row][col-1]) {
                    int west = site(row, col-1);
                    // std::cout << "West site: " << west << std::endl;
                    uf.quickUnion(center, west);
                }
                if(col+1 < N &&grid[row][col+1]) {
                    int east = site(row, col+1);
                    // std::cout << "East site: " << east << std::endl;
                    uf.quickUnion(east, center);
                }
                totalOpenSites += 1;
            }
        }

        bool isOpen(int row, int col) {
            return grid[row][col] == 1;
        }

        bool isFull(int row, int col) {
            return uf.find(0, site(row, col));
        }

        int numberOfOpenSites() {
            return totalOpenSites;
        }

        bool percolates() {
            return uf.find(0, (N*N)-2*N+1);
        }

        void printGrid() {
            for(int i=0; i<N; i++) {
                for(int j=0; j<N; j++) {
                    std::cout << grid[i][j] << " ";                
                }
                std::cout << std::endl;
            }
        }

        void printUF() {
            uf.printConnectedComponents();
        }
};

渗滤

#include "percolation.h"

int main() {
    Percolation p = Percolation(3);
    std::cout << "Initiate..." << std::endl;
    p.printGrid();
    p.printUF();
    std::cout << std::endl;

    std::cout << "Open (0, 1):" << std::endl;
    p.open(0, 1);
    p.printGrid();
    p.printUF();
    std::cout << std::endl;

    std::cout << "Open (0, 2):" << std::endl;
    p.open(0, 2);
    p.printGrid();
    p.printUF();
    std::cout << std::endl;

    std::cout << "Open (1, 0):" << std::endl;
    p.open(1, 0);
    p.printGrid();
    p.printUF();
    std::cout << std::endl;

    std::cout << "Open (1, 1):" << std::endl;
    p.open(1, 1);
    p.printGrid();
    p.printUF();
    std::cout << std::endl;

    std::cout << "Open (2, 2):" << std::endl;
    p.open(2, 2);
    p.printGrid();
    p.printUF();
    std::cout << std::endl;

    std::cout << "Open (1, 2):" << std::endl;
    p.open(1, 2);
    p.printGrid();
    p.printUF();
    std::cout << std::endl;

    std::cout << "No of open sites: " << p.numberOfOpenSites() << std::endl;

    bool percolates = p.percolates();
    std::cout << "Percolates???" << "";
    if(percolates) {
        std::cout<<"YESSS!! :)";
    } else {
        std::cout<<"NO... :(";
    }
    return 0;
}

当我向联合添加析构函数时,找到类并运行percolation.cpp 我在类成员connections, sz, maxObj联合查找类的connections, sz, maxObj中得到带有垃圾值的奇怪结果。 当我删除析构函数时,它工作正常。

没有析构函数的输出:

Initiate...
0 0 0
0 0 0
0 0 0
Indices:
0 1 2 3 4
Connections:
0 1 2 3 4
Sizes:
1 1 1 1 1

Open (0, 1):
0 1 0
0 0 0
0 0 0
Indices:
0 1 2 3 4
Connections:
0 1 2 3 4
Sizes:
1 1 1 1 1

Open (0, 2):
0 1 1
0 0 0
0 0 0
Indices:
0 1 2 3 4
Connections:
0 1 2 3 4
Sizes:
1 1 1 1 1

Open (1, 0):
0 1 1
1 0 0
0 0 0
Indices:
0 1 2 3 4
Connections:
0 1 2 3 4
Sizes:
1 1 1 1 1

Open (1, 1):
0 1 1
1 1 0
0 0 0
Indices:
0 1 2 3 4
Connections:
2 2 2 3 4
Sizes:
1 1 3 1 1

Open (2, 2):
0 1 1
1 1 0
0 0 1
Indices:
0 1 2 3 4
Connections:
2 2 2 3 4
Sizes:
1 1 3 1 1

Open (1, 2):
0 1 1
1 1 1
0 0 1
Indices:
0 1 2 3 4
Connections:
2 2 2 2 2
Sizes:
1 1 5 1 1

No of open sites: 6
Percolates???YESSS!! :)

带析构函数的输出:

Initiate...
0 0 0
0 0 0
0 0 0
Indices:
0 1 2 3 4
Connections:
7502560 7503664 2 3 4
Sizes:
7474272 7503808 1 1 1

Open (0, 1):
0 1 0
0 0 0
0 0 0
Indices:
0 1 2 3 4
Connections:
7502560 7503664 2 3 4
Sizes:
7474272 7503808 1 1 1

Open (0, 2):
0 1 1
0 0 0
0 0 0
Indices:
0 1 2 3 4
Connections:
7502560 7503664 2 3 4
Sizes:
7474272 7503808 1 1 1

Open (1, 0):
0 1 1
1 0 0
0 0 0
Indices:
0 1 2 3 4
Connections:
7502560 7503664 2 3 4
Sizes:
7474272 7503808 1 1 1

Open (1, 1):

当我将析构函数添加到联合查找类时,该程序甚至无法完全运行。 为什么会这样呢?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM