Функция сортировки массива самосортировки в пользовательском классе C ++

0

поэтому я пытаюсь сделать класс массива, который позволяет добавить число, а функция добавления поместит это число в массив в позиции со следующими критериями: строки массива И столбцы должны быть в порядке возрастания. Так

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)

Надеюсь, я отформатировал это правильно, спасибо заранее!

Теги:
sorting
variable-assignment

2 ответа

0

Взгляните на фрагмент, который я написал ниже.

Я согласен с Джерри, что его проще просто использовать и сортировать одномерный массив и просто проецировать его в нужную вам форму. Я использовал ту же процедуру сортировки, что и Джерри, за исключением того, что это выведет ваши цифры на квадратную матрицу нужной вам ширины.

#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

Выход всегда должен быть отсортирован по горизонтали и по вертикали (даже по диагонали!)

0

Вероятно, проще всего работать с массивом, как если бы это было одно измерение, и сохранить все это в порядке.

Затем, когда вы показываете его, вы можете распечатывать его как по столбцам, так и по строкам, и это гарантирует соответствие вашим ограничениям. Из двух, печатать его по ряду, почти наверняка будет (совсем немного) проще.

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

Разумеется, для любого реального использования вы, несомненно, не хотите, чтобы данные были глобальными, а также не имели таких функций, как insert или print которые неявно работают на этом глобальном уровне, но я надеюсь, что основная идея приходит, тем не менее.

  • 0
    Спасибо за понимание! Я даже не думал об этом, но это гораздо, гораздо более доступно, чем множество дел, в которые я пытался обменяться.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню