(C ++) Удаление строк с дубликатами в матричной ошибке - PullRequest
0 голосов
/ 27 января 2019

Удалить строки, где значение встречается дважды из матрицы.Где ошибка в моем коде, который я уже написал, так что я делаю это без использования какой-либо функции или чего-либо, что могло бы облегчить это?Мой код:

#include <iostream>

using namespace std;

int main()
{
    int v[99][99], m, n, i, j, k, vlinie[99], a=0;

    cout<<"m="; cin>>m;
    cout<<"n="; cin>>n;
    for(i=1; i<=m; i++)
        for(j=1; j<=n; j++)
            cin>>v[i][j];

    //finding out each row that has doubles and remembering its index in an array called vlinie
    for(i=1; i<=m; i++)
        for(j=1; j<=n-1; j++)
            for(k=j+1; k<=n; k++)
                if(v[i][j]==v[i][k])
                    {
                        a++; //a is the number of numbers in vlinie
                        vlinie[a]=i;
                    }

    //removing duplicates from vlinie, in case there are any
    for(i=1; i<=a-1; i++)
        for(j=i+1; j<=a; j++)
            if(vlinie[i]==vlinie[j])
                for(k=i; k<=m; k++)
                {
                    vlinie[k]=vlinie[k+1];
                    a--;
                }

    //this is where we move the rows around, and supposedly the line where i got it wrong, so what do i change in this line?
    for(i=1; i<=a; i++)
        for(j=1; j<=n; j++)
            for(k=vlinie[i]; k<=m; k++)
                v[vlinie[i]+k][j]=v[vlinie[i]+k+1][j];

    for(i=1; i<=m; i++)
        {
            cout<<endl;
            for(j=1; j<=n; j++)
                cout<<v[i][j]<<" ";
        }

    return 0;
}

Пример:

1 2 2 3
4 5 6 7
7 7 8 9
7 6 5 4

Что должно быть выведено:

4 5 6 7
7 6 5 4
0 0 0 0 0 0 0 0 (без теоретических нулей, но то, как я это написал, оставляет так,на данный момент)

Что он выводит вместо:

1 2 2 3
7 7 8 9
5 4 3 2 (он не удалил строки, которые должен удалитьи вместо этого удалил какую-то строку, которую он должен сохранить)

Как это исправить?

PS: да, я знаю, что не следовало начинать индексирование с 1 вместо 0, нет необходимости напоминать мне об этом снова

1 Ответ

0 голосов
/ 27 января 2019

Ваша проблема была в следующих строках:

   for(i=1; i<=a; i++)
        for(j=1; j<=n; j++)
            for(k=vlinie[i]; k<=m; k++)
                v[vlinie[i]+k][j]=v[vlinie[i]+k+1][j];

Существует первая проблема с индексами: мы должны скопировать v[k+1][] в v[k][].
Вторая проблема заключается в том, что один раз первыйперемещение выполнено, таблица vlinie больше не действительна.
Этот последний пункт не так легко исправить.

Более того, для каждой подавленной строки вы реализуете смещение нескольких строк, что приводит к низкой эффективности.

Проще и эффективнее запомнить, какие строки подавлены (suppress[]) и из этой таблицы определить, какая строка входной матрицы будет заканчиваться на i-й строке конечной матрицы (таблица posi[]).

Далее приведен пример реализации.

#include <iostream>
int main()
{
    int v[99][99], m, n, i, j, k, posi[99];
    bool suppress[99];

    std::cout << "m = "; std::cin >> m;
    std::cout << "n = "; std::cin >> n;
    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
            std::cin >> v[i][j];

    //finding out each row that has doubles
    for (i = 0; i < m; i++) {
        suppress[i] = false;
        for (j = 0; (j < n-1) && !suppress[i]; j++)
            for (k = j+1; (k < n) && !suppress[i]; k++)
                suppress[i] =  (v[i][j] == v[i][k]);
    }

    // determination of the moves to be performed
    int n_keep = 0;
    for (i = 0; i < m; i++) {
        if (!suppress[i])
            posi[n_keep++] = i;
    }

    //this is where we move the rows around
    for (i = 0; i < n_keep; i++)
        for (j = 0; j < n; j++)
                v[i][j] = v[posi[i]][j];

    // Set to 0 remaining rows
    for (i = n_keep; i < m; i++)
        for (j = 0; j < n; j++)
            v[i][j] = 0;

    for(i = 0; i < m; i++)
    {
        std::cout << "\n";
        for(j = 0; j < n; j++)
            std::cout << v[i][j] << " ";
    }
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...