自定义类中的自排序数组C++排序函数

Self sorting array's sort function in C++ custom class

本文关键字:排序 数组 函数 C++ 自定义      更新时间:2023-10-16

所以我试图创建一个数组类,让你添加一个数字,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 calledn";
    }
    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)

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

将数组当作一个维度来处理,并对整个数组进行排序可能是最简单的。

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

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这样的函数隐式地对该全局数据进行操作,但我希望基本思想仍然能够实现。

看看我在下面写的片段。

我同意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

输出应始终水平和垂直排序(甚至对角线!)