【问题标题】:Self sorting array's sort function in C++ custom classC++自定义类中自排序数组的排序功能
【发布时间】:2013-11-20 21:12:20
【问题描述】:

所以我正在尝试创建一个数组类,让您可以添加一个数字,并且 add 函数将把该数字放入一个数组中,该位置具有以下条件:数组的行和列必须按数字升序排列.所以

1 2
3 4

没问题,而

1 3
4 2

失败,因为 4 > 2 和 3 > 2 但是

1 3
2 4

可以接受

赋值是模糊的,只要满足约束条件,它是否使数组像第一个或第三个并不重要。我通过简单地写出一个案例列表并尝试处理每个案例来完成我的添加功能。初始化数组时,它会将 INTEGER_MAX 放在每个点中,用于占位和评估目的。我不确定这是评估顺序还是什么,但有时它会放置一个我在 INTEGER_MAX 下添加的数字,或者以其他方式无序。我已经为此工作了一段时间,并且在寻求帮助时犹豫不决,但我认为用一双新的眼睛可能会更容易。我要为函数和类添加代码,我不知道是否/如何包含依赖类以允许其他人编译代码?我是 SO 新手,有点不舒服,所以请耐心等待,我会提供任何需要的信息来提供帮助。谢谢!

这是 add() 函数本身:

void add(int i) {

    //THIS NEEDS TO BE FIXED ITS GOING TO THE WRONG PLACES

    if (matrix[row - 1][col - 1] != INT_MAX){ //if the last element in the VNT is full 
        cout<<"VNT is full!"<<endl; 
    }
    else {
        matrix[row - 1][col - 1] = i;
        //cout << "matrix["<<row-1<<"]["<<col-1<<"] = " <<matrix[row - 1][col - 1]<<endl;
        int r = row - 1;
        int c = col - 1;
        while (true) {
            if (r == 0 && c == 0) //no neighbor left, no neighbor above, correct position
                break;
            else if (c == 0) { //no neighbor left
                if (matrix[c][r-1] > i) { //if above is larger, swap
                    swap (r, c, r-1, c);
                    r--; //decrement row to go through stability check again
                }
                else        //above is smaller, break
                    break;
            }
            else if (r == 0) { //no neighbor above
                if (matrix[c-1][r] > i) { //if left is larger, swap
                    swap (r, c, r, c-1);
                    c--; //decrement column to go through stability check again
                }
                else        //left is smaller, break
                    break;
            }

            else if (matrix[r][c-1] < i && matrix[r-1][c] < i) //left and above are both smaller, right position
                break;

            else if (matrix[r][c-1] > i && matrix[r-1][c] > i) { //both left and above are potential candidates for switch
                if (matrix[r][c-1] >= matrix[c][r-1]) { //if left candidate is larger than top candidate, swap with that to preserve column
                    swap (r, c, r, c-1);
                    cout << "Swapping a["<<r<<"]["<<c<<"] with a["<<r<<"]["<<c-1<<"]"<<endl;
                    c--; //decrement column to go through stability check again
                }
                else { //otherwise swap with neighbor above
                    swap (r, c, r-1, c);
                    cout << "Swapping a["<<r<<"]["<<c<<"] with a["<<r-1<<"]["<<c<<"]"<<endl;
                    r--; //decrement row to go through stability check again
                }
            }
            else if (matrix[r][c-1] > i) { //only left neighbor is larger, swap left
                swap (r, c, r, c-1);
                cout << "Swapping a["<<r<<"]["<<c<<"] with a["<<r<<"]["<<c-1<<"]"<<endl;
                r--;
            }
            else if (matrix[r-1][c] > i) { //only the above neighbor is larger, switch with that
                swap (r, c, r-1, c);
                cout << "Swapping a["<<r<<"]["<<c<<"] with a["<<r-1<<"]["<<c<<"]"<<endl;
                c--;
            }

        } 
    }
}

然后是更大的上下文类文件(如果需要,请告诉我):

    #include <cmath>
#include <climits>
#define main poop
#include "SA.cpp"
#include "safeMatrix.cpp"
using namespace std;
#undef main

//friend ostream& operator<< (ostream& os, VNT v);

class VNT {

private:
    SafeMatrix <int> matrix;
    int row;
    int col;

public:

    VNT (int r, int c) : matrix (r, c) {  //2 param constructor
        //cout << "r = " << r << " c = " << c << endl;
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                //cout << "i = " << i << " j = " << j;
                matrix[i][j] = INT_MAX;
            }
            cout << endl;
        }
        row = r; //initialize the rows and cols vars to hold the SIZE of the array !POSSIBLE OFF BY 1 ERRORS!
        col = c;
    }

    ~VNT() { //destructor
        cout << "VNT Destructor called\n";
    }

    void add(int i) {

        //THIS NEEDS TO BE FIXED ITS GOING TO THE WRONG PLACES

        if (matrix[row - 1][col - 1] != INT_MAX){ //if the last element in the VNT is full 
            cout<<"VNT is full!"<<endl; 
        }
        else {
            matrix[row - 1][col - 1] = i;
            //cout << "matrix["<<row-1<<"]["<<col-1<<"] = " <<matrix[row - 1][col - 1]<<endl;
            int r = row - 1;
            int c = col - 1;
            while (true) {
                if (r == 0 && c == 0) //no neighbor left, no neighbor above, correct position
                    break;
                else if (c == 0) { //no neighbor left
                    if (matrix[c][r-1] > i) { //if above is larger, swap
                        swap (r, c, r-1, c);
                        r--; //decrement row to go through stability check again
                    }
                    else        //above is smaller, break
                        break;
                }
                else if (r == 0) { //no neighbor above
                    if (matrix[c-1][r] > i) { //if left is larger, swap
                        swap (r, c, r, c-1);
                        c--; //decrement column to go through stability check again
                    }
                    else        //left is smaller, break
                        break;
                }

                else if (matrix[r][c-1] < i && matrix[r-1][c] < i) //left and above are both smaller, right position
                    break;

                else if (matrix[r][c-1] > i && matrix[r-1][c] > i) { //both left and above are potential candidates for switch
                    if (matrix[r][c-1] >= matrix[c][r-1]) { //if left candidate is larger than top candidate, swap with that to preserve column
                        swap (r, c, r, c-1);
                        cout << "Swapping a["<<r<<"]["<<c<<"] with a["<<r<<"]["<<c-1<<"]"<<endl;
                        c--; //decrement column to go through stability check again
                    }
                    else { //otherwise swap with neighbor above
                        swap (r, c, r-1, c);
                        cout << "Swapping a["<<r<<"]["<<c<<"] with a["<<r-1<<"]["<<c<<"]"<<endl;
                        r--; //decrement row to go through stability check again
                    }
                }
                else if (matrix[r][c-1] > i) { //only left neighbor is larger, swap left
                    swap (r, c, r, c-1);
                    cout << "Swapping a["<<r<<"]["<<c<<"] with a["<<r<<"]["<<c-1<<"]"<<endl;
                    r--;
                }
                else if (matrix[r-1][c] > i) { //only the above neighbor is larger, switch with that
                    swap (r, c, r-1, c);
                    cout << "Swapping a["<<r<<"]["<<c<<"] with a["<<r-1<<"]["<<c<<"]"<<endl;
                    c--;
                }

            } 
        }
    }

    int getMin() { //removes the first element and then resort the matrix
        int value;
        if (matrix[0][0] == INT_MAX){ // if the VNT is empty  it will output this message but 
            cout<<"VNT is empty"<<endl;
            return -1; 
        }
        else { 
            value = matrix[0][0]; // value to be returned 
            matrix[0][0] = INT_MAX; // set the first element to INT_MAX 
            int r = 0;
            int c = 0;
            while (r < row || c < col) {
                if (matrix[r][c] > matrix[r+1][c] && matrix[r][c] > matrix[r][c+1]) { //if both the element to the right and below are candidates
                    if (matrix[r][c+1] < matrix[r+1][c]) { //if swapping with left wont invalidate the column, do that
                        swap(r, c, r, c+1);
                        c++;
                    }
                    else { //otherwise swap with bottom
                        swap(r, c, r+1, c);
                        r++;
                    }           
                }
                else if (matrix[r][c] > matrix[r][c+1]) {
                    swap(r, c, r, c+1);
                    c++;
                }
                else if (matrix[r][c] > matrix[r+1][c]) {
                    swap(r, c, r+1, c);
                    r++;
                }
                else
                    break;
            }
        }
        return value; //scope?!?        
    }

    void sort(int k[], int size) {
        if (size > row*col)
            cout << "Too many elements for the VNT"<< endl;
        else {
            for (int i = 0; i < row; i++){ 
                for(int j = 0; j < col; j++){ 
                    matrix[i][j] = INT_MAX; //set every element in the VNT to INT_MAX 
                }
            }  
            for(int i = 0; i < size; i++){ 
                add(k[i]); // will use the member function to add each element to the VNT 
            }
        }   
    }

    void swap (int r1, int c1, int r2, int c2) {
        int temp = matrix[r1][c1];
        matrix[r1][c1] = matrix[r2][c2];
        matrix [r2][c2] = temp;
    }

    bool find (int i) {
        for (int r = 0; r < row; r++) {
            for (int c = 0; c < col; c++) {
                if (matrix[r][c] == i)
                    return true;
                // else if (matrix[r][c] > i)
                    // return false;
            }
        }
        return false;
    }

    friend ostream& operator<< (ostream& os, VNT v);
};

ostream& operator<< (ostream& os, VNT v) {
        for (int i = 0; i < v.row; i++) {
            for (int j = 0; j < v.col; j++) {
                if (v.matrix[i][j] == INT_MAX)
                    os << "*" << " ";
                else 
                    os << v.matrix[i][j] << " ";
            }
            os << endl;
        }
        return os;
    }

int main(){
    VNT a(5,5);
    cout << a;
    VNT b(3,3);
    cout << b;
    b.add(1);   
    b.add(5);
    //cout << a.getMin();
    //a.add(1);
    //cout << b;
    //b.add(10);
    cout << b;
    b.add(2);
    b.add(3);
    cout << b;

    b.add(10);
    b.add(7);
    b.add(11);
    cout << b;
    cout << b.find(1)<<endl;
    VNT m(3,5);
    cout << m;
    //cout << c;

};

现在,对我来说,矩阵 b 的代码输出是:

1 3 *
2 7 11
5 10 *

(* 代表 INTEGER_MAX)

希望我的格式正确,提前谢谢!

【问题讨论】:

    标签: c++ sorting variable-assignment


    【解决方案1】:

    将数组当作单维处理可能是最简单的方法,并保持整个事物的排序。

    然后,当您显示它时,您可以按列或按行打印出来,并且保证满足您的约束。在这两者中,按行打印几乎肯定会(相当)容易。

    std::vector<int> data;
    
    void insert(int d) { 
        auto pos = std::upper_bound(data.begin(), data.end(), d);
        data.insert(pos, d);
    }
    
    void print(int columns) { 
        for (int i=0; i<data.size(); i++) {
           if (i % columns == 0)
               std::cout << "\n";
           std::cout << data[i];
        }
    }
    

    快速测试驱动程序:

    int main(){
        insert(4);
        insert(2);
        print(2);
        std::cout << "\n";
        insert(3);
        insert(1);
        print(2);
    }
    

    结果:

    24
    
    12
    34
    

    当然,对于任何实际用途,您无疑想让数据成为全局数据,也没有像 insertprint 这样隐式操作该全局数据的函数,但是尽管如此,我还是希望基本的想法能够实现。

    【讨论】:

    • 感谢您的洞察!我什至没有这样想过,但这比我试图将它换成的无数案例更容易接近。
    【解决方案2】:

    看看我下面写的sn-p。

    我同意 Jerry 的观点,它更易于使用和排序一维数组并将其投影到您需要的形式中。我使用了与 Jerry 相同的排序例程,只是这会将您的数字排列在所需宽度的方阵上。

    #define DIMENSION_SIZE 10
    
    int matrix[DIMENSION_SIZE+1][DIMENSION_SIZE+1];
    
    std::vector<int> data;
    
    void insert(int d) { 
        auto pos = std::upper_bound(data.begin(), data.end(), d);
        data.insert(pos, d);
    }
    
    int main()
    {
        for (int ctr=0;ctr<DIMENSION_SIZE*DIMENSION_SIZE;++ctr) {
            insert(rand());
        }
    
        int level = 0;
        int levelsub = 0;
    
        for (int ctr=0;ctr<DIMENSION_SIZE*DIMENSION_SIZE;++ctr) {
            matrix[level-levelsub][levelsub] = data.at(ctr);
    
            if (++levelsub >  (level >= DIMENSION_SIZE ? DIMENSION_SIZE -1 : level)) {
                ++level;
                levelsub= 0;
                if (level >= DIMENSION_SIZE) {
                    levelsub+=level - DIMENSION_SIZE+1;
                }
            }
        }
    
        for (int ctr_y=0;ctr_y<DIMENSION_SIZE;++ctr_y) { 
            for (int ctr_x=0;ctr_x<DIMENSION_SIZE;++ctr_x) {
                std::cout << matrix[ctr_x][ctr_y] << "\t";
            }
            std::cout << "\n";
        }
    
        return 0;
    }
    

    这是我机器上的输出:

    41      153     292     1842    3035    4966    6729    9741    12316   15350
    
    288     491     1869    3548    5436    6868    9894    12382   15724   18467
    
    778     2082    3902    5447    7376    9961    12623   15890   18716   19954
    
    2995    4664    5537    7711    11323   12859   16118   18756   20037   23805
    
    4827    5705    8723    11478   13931   16541   19169   21538   23811   25547
    
    6334    8942    11538   14604   16827   19264   21726   24084   25667   27446
    
    9040    11840   14771   16944   19629   22190   24370   26299   27529   28703
    
    11942   15006   17035   19718   22648   24393   26308   27644   29358   31101
    
    15141   17421   19895   22929   24464   26500   28145   30106   31322   32439
    
    17673   19912   23281   24626   26962   28253   30333   32391   32662   32757
    

    输出应该总是水平和垂直排序(甚至是对角线!)

    【讨论】:

      猜你喜欢
      • 2011-11-01
      • 1970-01-01
      • 2010-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多