Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.50/107: Рейтинг темы: голосов - 107, средняя оценка - 4.50
1 / 1 / 0
Регистрация: 25.10.2012
Сообщений: 13
1

Удаление колонки (столбца) из динамического двумерного массива

25.10.2012, 00:49. Показов 21082. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Сколько ни пытался, не смог понять/придумать как удалить столбец. Строка удаляется элементарно, но как это сделать со столбцом? 30 строка.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
int n;
do {cout << "Array size: "; cin >> n; system("cls");}
while (n<2);
 
//îáúÿâëåíèå äâóìåðíîãî ìàññèâà
int ** m = new int*[n];
for (int i=0; i<n; i++) m[i] = new int[n];
 
//çàïîëíåíèå è âûâîä
for (int i=0;i<n; i++) 
{
    for (int I=0;I<n;I++) 
    {
        m[i][I]=rand()%99;
        cout.width (3); cout << m[i][I];
    }
    cout << "\n";
}
 
int k;
do {cout << "\n" << "Delete column #"; cin >> k;} while (k>n);
k--; //ïîïðàâêà íà íà÷àëî îòñ÷åòà ñ 0
 
//óäàëåíèå ñòîëáöà
for(int i=0;i<n;i++) 
{
        m[i][k]=0;
        //ÊÀÊ?
  /*  for (int I=0;I<n;I++) 
    if (m[i][I]==0) delete[] m[i];   */
}   
 
//âûâîä ìàññèâà áåç óäàëåííîãî ñòîëáöà
for (int i=0;i<n; i++) 
{
    for (int I=0;I<n;I++) 
    {
        if (I==k) I++;
        cout.width (3);
        cout << m[i][I];
    }
    cout << "\n";
}
 
system("pause");
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.10.2012, 00:49
Ответы с готовыми решениями:

Корректное удаление двумерного динамического массива
Доброго времени суток. В программе имеется двумерный динамический массив. Особенность его в том,...

Правильное удаление динамического двумерного массива
Доброго времени суток форумчани. Ну в общем перейду сразу к делу. О себе: сам пишу на JAVA...

Удаление двумерного динамического массива MSVS
Здравия желаю. При работе с двумерными динамическими массивами столкнулся со странной ошибкой....

Удаление двумерного динамического массива (матрицы)
Вот так я создаю двумерный динамический массив. bool **gameFieldArray; gameFieldArray = new...

20
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
25.10.2012, 01:38 2
Цитата Сообщение от n3L Посмотреть сообщение
C++
1
2
3
4
//удаление столбца
for(int i=0;i<n;i++)
{
    m[i][k]=0; //КАК? /* for (int I=0;I<n;I++) if (m[i][I]==0) delete[] m[i]; */ }
C++
1
2
3
4
5
6
7
#include <algorithm>
 
// ...
 
for (std::size_t i = 0; i != n; ++i) {
   std::copy(&m[i][k + 1], &m[i][n], &m[i][k]);
}
1
1 / 1 / 0
Регистрация: 25.10.2012
Сообщений: 13
25.10.2012, 11:31  [ТС] 3
gray_fox, но это ведь только копирует все элементы, следующие за указанным столбцом, перенося их на столбец-1. Последний столбец остается в памяти. Как осуществить очистку памяти, выделенной под эти столбцы, используя операцию delete? Только скопировав данные в меньший массив, и удалив старый? Или все-таки есть другой способ?

Не по теме:

Признаюсь, этот вариант лучше моей организации получаемого массива, потому что номера элементов идут по порядку, без пропуска на k столбце.

0
178 / 161 / 38
Регистрация: 08.10.2012
Сообщений: 423
25.10.2012, 12:39 4
Цитата Сообщение от n3L Посмотреть сообщение
Или все-таки есть другой способ?
нету, дело в том что функция new выделяет ровно столько памяти сколько нужно под тип данных и их количество. Получается своеобразная страница. Очень похоже на память на жестком диске. В NTFS память разбита на кластеры или стеки (точно не помню) по 4 байта. В итоге даже если в этом кластере/стэке информация занимает 1 байт или даже 1 бит, все равно занимаемый стэк/кластер будет равен 4 байтам. Так и тут невозможно просто так затереть последние биты/бафты
1
1 / 1 / 0
Регистрация: 25.10.2012
Сообщений: 13
25.10.2012, 16:26  [ТС] 5
MrGrig, понятно, спасибо.

Раз только так, то перебросить данные между массивами вышло, а очистка памяти под старый массив почему-то останавливается на 2 строке. Из-за чего это происходит?
50-ая строка
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
using namespace std;
int main()
{
int n;
do {cout << "Array size: "; cin >> n; system("cls");}
while (n<2);
 
//îáúÿâëåíèå äâóìåðíîãî ìàññèâà
int ** m = new int*[n];
for (int i=0; i<n; i++) m[i] = new int[n];
 
//çàïîëíåíèå è âûâîä
for (int i=0;i<n; i++) 
{
    for (int I=0;I<n;I++) 
    {
        m[i][I]=rand()%99; 
        cout.width (3);
        cout << m[i][I];
    }
    cout << "\n";
}
 
int k;
do {cout << "\n" << "Delete column #"; cin >> k;} while (k>n);
k--; //ïîïðàâêà íà íà÷àëî îòñ÷åòà ñ 0
 
//îáúÿâëåíèå âòîðîãî ìàññèâà
int ** M = new int*[n-1];
for (int i=0; i<n; i++) M[i] = new int[n];
 
//ïåðåáðîñ äàííûõ ìåæäó ìàññèâàìè, âûâîä âòîðîãî ìàññèâà
int I=0;
for (int i=0;i<n; i++) 
{
        copy (&m[i][I], &m[i][k], &M[i][0]);
        copy (&m[i][k + 1], &m[i][n], &M[i][k]); 
          for (int I=0;I<n-1;I++)
    {
           cout.width (3);
        cout << M[i][I];
    }
        cout << "\n";
}
 
 
//óäàëåíèå ïåðâîãî ìàññèâà
for (int i=0; i<n;i++)
delete m[i];
delete [] m;
 
 
cout << "\n deleted: \n";
for (int i=0;i<n; i++) 
{
    for (int I=0;I<n;I++)  
    {
          cout.width (9);
          cout << m[i][I];
    }
        cout << "\n";
}
 
system("pause");
}
0
178 / 161 / 38
Регистрация: 08.10.2012
Сообщений: 423
25.10.2012, 19:37 6
Цитата Сообщение от n3L Посмотреть сообщение
C++
1
2
3
for (int i=0; i<n;i++)
delete m[i];
delete [] m;
попробуйте так
C++
1
2
3
for (int i=0; i<n;i++)
    delete[] m[i];
delete [] m;
1
1 / 1 / 0
Регистрация: 25.10.2012
Сообщений: 13
25.10.2012, 23:11  [ТС] 7
MrGrig, нет, то же самое, я пробовал.
Так же и с
C++
1
2
3
for (int i=0; i<n;i++)
delete m[i];
delete m;
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
25.10.2012, 23:15 8
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <iostream>
#include <cstdlib>
#include <random>
using std::cout;
 
int ** DeleleCol(int *** Array, int &x, int nDelCol);
int ** DeleleRow(int *** Array, int x, int &y, int nDelRow);
 
int main()
{
    int n=5,m=4;
    int ** Array;
    Array=new int*[n];
    for(int i=0;i<n;++i)
        Array[i]=new int[m];
 
 
    for(int i=0;i<m;++i){
        for(int j=0;j<n;++j)
            cout<<(Array[j][i]=rand()%100)<<"\t";
        cout<<"\n";
    }
 
    cout<<"\n\n\n";
    Array=DeleleRow(&Array,n,m,m-1);
    for(int i=0;i<m;++i){
        for(int j=0;j<n;++j)
            cout<<Array[j][i]<<"\t";
        cout<<"\n";
    }
 
    cout<<"\n\n\n";
    Array=DeleleCol(&Array,n,n-1);
    for(int i=0;i<m;++i){
        for(int j=0;j<n;++j)
            cout<<Array[j][i]<<"\t";
        cout<<"\n";
    }
    
 
 
    for(int i=0;i<n;++i)
        delete [] Array[i];
    delete [] Array;
system("pause");
}
 
 
 
 
int ** DeleleCol(int *** Array, int &x, int nDelCol){
    int ** tempArray=new int*[--x];
 
    bool bFlag;
    for(int i=0, bFlag=false;i<x;++i){
        if(nDelCol==i) {bFlag=true; delete [] (*Array)[i];}
        tempArray[i]=(bFlag)?(*Array)[i+1]:(*Array)[i];
    }
    delete [] (*Array);
    return (*Array=tempArray);
}
 
int ** DeleleRow(int *** Array, int x, int &y, int nDelRow){
    int * tempArray;
    bool bFlag=false; --y;
    for (int i=0;i<x;++i,bFlag=false){
        tempArray=new int[y];
        for(int j=0;j<y;++j){
            if (nDelRow==j) {bFlag=true;}
            tempArray[j]=(bFlag)?(*Array)[i][j+1]:(*Array)[i][j];
        }
        delete [] (*Array)[i];
        (*Array)[i]=tempArray;
    }
    return *Array;
}
конечно, не идеал, но как основа пойдет =)
1
1 / 1 / 0
Регистрация: 25.10.2012
Сообщений: 13
27.10.2012, 12:45  [ТС] 9
Croessmah, может, я не туда вписал, но попытавшись вывести удаленный массив, оно так же вывело рандомные числа в первых двух столбцах (или строках, не помню), а остальные - те, что были.

За что оно вот так удаляет? Как уже только не пробовал. Это из-за 64-битной системы что ли?
Миниатюры
Удаление колонки (столбца) из динамического двумерного массива  
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
27.10.2012, 12:48 10
код можно посмотреть?
1
1 / 1 / 0
Регистрация: 25.10.2012
Сообщений: 13
27.10.2012, 17:51  [ТС] 11
Да все тот же, я логику не сильно изменил.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream.h>
#include <conio.h>
using namespace std;
int main()
{
int n;
do {cout << "Array size: "; cin >> n; system("cls");}
while (n<2);
 
cout << "Original array: \n";
int ** m = new int*[n];
for (int i=0;i<n; i++) 
{
     m[i] = new int[n];
    for (int I=0;I<n;I++) 
    {
        m[i][I]=rand()%99; 
        cout.width (3);
        cout << m[i][I];
    }
    cout << "\n";
}
 
int k;
do {cout << "\nDelete column #"; cin >> k;} while (k>n || k<1);
k--; //поправка на начало отсчета с 0
 
 
cout << "Array without deleted column: \n";
int ** M = new int*[n-1];
 
int I=0;
for (int i=0;i<n; i++) 
{
    M[i] = new int[n];
    copy (&m[i][I], &m[i][k], &M[i][0]);
    copy (&m[i][k + 1], &m[i][n], &M[i][k]); 
    for (int I=0;I<n-1;I++)
    {
        cout.width (3);
        cout << M[i][I];
    }
    cout << "\n";
}
 
 
/* for (int i=0; i<n;i++)
{
delete m[i];
delete [] m;
}*/
for (int i=n; i>0;i--)
{
delete m[i];
delete [] m;
}
 
 
cout << "\n deleted: \n";
for (int i=0;i<n; i++) 
{
    for (int I=0;I<n;I++)  
    {
        cout.width (8);
        cout << m[i][I];
    }
    cout << "\n";    
}
 
system("pause");
}
0
178 / 161 / 38
Регистрация: 08.10.2012
Сообщений: 423
27.10.2012, 18:31 12
Цитата Сообщение от n3L Посмотреть сообщение
За что оно вот так удаляет? Как уже только не пробовал. Это из-за 64-битной системы что ли?
поясните пожалуйста?

если честно я так и не понял что вы еще хотите, ведь вроде уже разобрались что просто так память подтереь нельзя? оО
1
1 / 1 / 0
Регистрация: 25.10.2012
Сообщений: 13
27.10.2012, 19:27  [ТС] 13
MrGrig, я уже осуществил копирование данных во второй массив, хочу целиком удалить первый, а он только некоторые элементы стирает.
0
178 / 161 / 38
Регистрация: 08.10.2012
Сообщений: 423
27.10.2012, 20:11 14
я же вам показывал удаление 2 мерного массива =/
Цитата Сообщение от MrGrig Посмотреть сообщение
C++
1
2
3
for (int i=0; i<n;i++)
    delete[] m[i];
delete [] m;
1
1 / 1 / 0
Регистрация: 25.10.2012
Сообщений: 13
28.10.2012, 03:27  [ТС] 15
Цитата Сообщение от MrGrig Посмотреть сообщение
for (int i=0; i<n;i++)
* * delete[] m[i];
delete [] m;
Идентичный кусок кода, а также с обратным циклом присутствуют в коде 11-ого сообщения. Ни вместе, ни по отдельности (они ж одинаковые, какая может быть разница) не сработали нормально. Результат показан на скриншоте 9-ого сообщения.
0
178 / 161 / 38
Регистрация: 08.10.2012
Сообщений: 423
28.10.2012, 09:24 16
Цитата Сообщение от n3L Посмотреть сообщение
Идентичный кусок кода, а также с обратным циклом присутствуют в коде 11-ого сообщения. Ни вместе, ни по отдельности (они ж одинаковые, какая может быть разница) не сработали нормально. Результат показан на скриншоте 9-ого сообщения.
я уж и не знаю вас носом ткнуть чтоли?
во первых удаление ячеек идет в цикле а удаление массива идет после цикла раз!!!!
во вторых ВЫ СКОБОЧКИ ПОСЛЕ ОПЕРАТОРА delete ВИДИТЕ?!?!?!!!!

delete[] m[i];
1
1 / 1 / 0
Регистрация: 25.10.2012
Сообщений: 13
29.10.2012, 03:44  [ТС] 17
MrGrig, в тексте записана всего-навсего последняя попытка перед закрытием программы.
И без, и с квадратными, и с разными циклами пробовал, и сейчас еще раз перепроверил с [], но результат почти одинаковый всегда: то первые две строки, то первые два столбца удаляет, и то, в некоторых вариантах делает это частично.
Не думаю, что есть какое-то объяснение и его опишут тут. Зато из темы 2 новых вещи узнал.
0
178 / 161 / 38
Регистрация: 08.10.2012
Сообщений: 423
29.10.2012, 05:49 18
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    int **buf=new int*[n];
    for(int i=0;i<n;i++)
        buf[i]=new int [n-1];
    for(int i=0,i1=0;i<n;i++,i1++)
        for(int j=0,j1=0;j<n;j++)
            if(j!=k)
                buf[i1][j1++]=m[i][j];
    for(int i=0;i<n;i++)
        delete[] m[i];
    delete[] m;
    m=buf;
    for (int i=0;i<n; i++){
        for (int I=0;I<n-1;I++){
            cout.width (3);
            cout <<m[i][I];
        }
        cout << "\n";
    }
    system("pause");
правильное удаление столбца
1
1 / 1 / 0
Регистрация: 25.10.2012
Сообщений: 13
29.10.2012, 23:57  [ТС] 19
С каждым новым сообщением в теме, код становится все компактнее и с еще меньшим количеством подключенных библиотек. И это радует.
Цитата Сообщение от MrGrig Посмотреть сообщение
C++
1
    m=buf;
это лучше,чем copy будет, даже std не нужно использовать.

Вставил дополнительный вывод сразу после очистки m, перед присвоением новых значений элементам массива - результат (на прикрепленном скриншоте) заставляет меня думать, что это все из-за Dev C++, x64 или незнания какой-то вещи, объясняющей нормальность всего этого.

Впрочем, задача решена, хотя я так и не понял причину "сломанного" delete.
Миниатюры
Удаление колонки (столбца) из динамического двумерного массива  
0
178 / 161 / 38
Регистрация: 08.10.2012
Сообщений: 423
30.10.2012, 08:08 20
Цитата Сообщение от n3L Посмотреть сообщение
Впрочем, задача решена, хотя я так и не понял причину "сломанного" delete.
у меня была одна небольшая проблема, которую я решил немного подумав, я выделял под массив массивов память n-1 а под сами массивы наоборот n в итоге программа постоянно вылетала с ошибкой попытки записи в левую память и вывод пустого пространства. Но в отладчике довольно быстро нашел эту проблему и вуаля
Цитата Сообщение от MrGrig Посмотреть сообщение
C++
1
2
3
int **buf=new int*[n];
    for(int i=0;i<n;i++)
        buf[i]=new int [n-1];
с самим переносом тоже пришлось по колдовать немного
Цитата Сообщение от MrGrig Посмотреть сообщение
C++
1
2
3
4
for(int i=0,i1=0;i<n;i++,i1++)
    for(int j=0,j1=0;j<n;j++)
        if(j!=k)
            buf[i1][j1++]=m[i][j];
1
30.10.2012, 08:08
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.10.2012, 08:08
Помогаю со студенческими работами здесь

Удаление двумерного динамического массива из памяти
Допустим дан двумерный динамический массив (созданный с помощью new). Как правильно удалить его из...

Удаление двумерного динамического массива символов
Программа разбивает строку на слова и записывает каждое слово по отдельности в двумерный...

Правильное удаление двумерного динамического массива ( нужен ли delete[] array )
В одном из постов форума Увидев код одного из участников форума: Я пришел в замешательство,...

Удаление строки или столбца из двумерного массива
Собственно сабж. Как это сделать? Есть какие то методы? Например удалить из массива строку...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru