Форум программистов, компьютерный форум CyberForum.ru

сортировка массива стуктур посредством указателей - C++

Восстановить пароль Регистрация
 
GrimSpirit
0 / 0 / 0
Регистрация: 19.12.2012
Сообщений: 6
24.12.2013, 16:03     сортировка массива стуктур посредством указателей #1
Доброго времени суток.
Есть у меня 1 задачка:
/*Дана целочисленная матрица А = {aij}, где 1<=i<=n; 1<=j<=m;
Выбрать строки матрицы, не содержащие нулевых элементов, и отсортировать выбранные строки
пытаюсь её решить:
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
#include<iostream>
#include<fstream>
 
using namespace std;
const int N=10;
 
struct arr
{
    bool good; int a[N]; int max;
};
 
int main()
{
    int n,m,i,j,count=0;    //размерности; count для подсчета строк с нулями, если count == m, то выведем сообщение.
    ifstream fin("data.txt");
    if(fin.fail()) 
        cout<<"cant open data file"<<endl;
    fin>>n>>m;      //читаем размер матрицы
    
    arr *matr = new arr[N];
    for(i=0;i<n;i++)
        {matr[i].good=true;//по умолчанию присвоим всем bool-элементам true
        matr[i].max=-(1<<32);}//присвоим всем элементам поля max начальное значение
 
        for(i=0;i<n;i++)    //заполняем массив
            for(j=0;j<m;j++)
            {fin>>matr[i].a[j];
                if(matr[i].a[j]==0) count++; matr[i].good=false;//если в строке есть 0, то good=0, 
                
            }                                           //чтобы пропустить эту строку при сортировке
            fin.close();
    for(i=0;i<n;i++)    //выводим изначальный массив на экран
    {
        for(j=0;j<m;j++)
    cout<<matr[i].a[j]<<" ";
    cout<<endl;
        }
if(count==n)cout<<"All str have 0"<<endl;
system("pause");
return 0;
}
на этом вдохновение иссякло =( .
в полях max будут значения максимальных элементов в каждой строке.
Поле bool отображает, учавствует ли эта строка в сортировке
У меня 2 вопроса:
1)как объявить массив указателей и привязать их к моему массиву структур?
2)сортировка через указатели с проверкой matr[i].good==true.

Добавлено через 15 минут
поправка. после закрытия файла идёт
C++
1
2
3
4
5
6
7
8
9
if(count==n)cout<<"All str have 0"<<endl;
    else
if((n-count)==1)cout<<"Only 1 string without 0"<<endl;
    for(i=0;i<n;i++)    //выводим изначальный массив на экран
        {
            for(j=0;j<m;j++)
        cout<<matr[i].a[j]<<" ";
        cout<<endl;
        }
Добавлено через 18 минут
возможно, есть более простой алгоритм. если да, то какой?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.12.2013, 16:03     сортировка массива стуктур посредством указателей
Посмотрите здесь:

Заполнение массива стуктур C++
C++ Сортировка массива указателей на абстрактный базовый класс
Сортировка указателей в массиве C++
Сортировка указателей C++
C++ Сортировка массива указателей на char
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Alex5
883 / 618 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
24.12.2013, 16:17     сортировка массива стуктур посредством указателей #2
Цитата Сообщение от GrimSpirit Посмотреть сообщение
C++
1
2
3
4
for(j=0;j<m;j++)
 {fin>>matr[i].a[j];
 if(matr[i].a[j]==0) count++; matr[i].good=false;//если в строке есть 0, то good=0, 
}
У Вас значение false устанавливается для каждой строки. count: Вам нужно "число строк, содержащих ноль" или "число нулей в матрице"
Начальное значение max:
C++
1
2
3
    matr[i].max= INT_MIN;
    //matr[i].max= (1<<31);  100000...000
    //matr[i].max=-(1<<32); // это значение равно нулю
GrimSpirit
0 / 0 / 0
Регистрация: 19.12.2012
Сообщений: 6
24.12.2013, 17:19  [ТС]     сортировка массива стуктур посредством указателей #3
count считает количество строк, содержащих 0.
нужен для вывода сообщений в случаях, когда либо во всех строках нули,
либо когда лишь 1 строка - ненулевая и сортировать не с чем.

Добавлено через 32 минуты
в min -32768.
c count и полем bool тоже разобрался.
C++
1
2
3
4
{fin>>matr[i].a[j];
        if(matr[i].a[j]==0) {count++; matr[i].good=false; continue;}
            }
            fin.close();
проверил-всё как надо выставляет

Добавлено через 9 минут
мне главное- отсортировать через указатели -_-

Добавлено через 12 минут
ладно, через указатели, кажется, слишком муторно.
как еще можно поменять строчки местами для сортировки?
Alex5
883 / 618 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
24.12.2013, 18:06     сортировка массива стуктур посредством указателей #4
Цитата Сообщение от GrimSpirit Посмотреть сообщение
1)как объявить массив указателей и привязать их к моему массиву структур?
C++
1
2
3
arr * p[N] = {}; 
// для 0<= i < n задаём значения 
// p[i] = &matr[i]; // p[i] - указатель на структуру matr[i]
Алгоритмы сортировок
При сортировке массива p[] учитываем только "хорошие" строки
C++
1
2
3
4
5
6
// ...
// if( p[i]->good && p[j]->good && ( сравниваем соответствующие строки  ) )
// {
//     // если надо поменять местами, строки(структуры) не трогаем, 
//     // меняем местами p[i] и p[j]
// }
GrimSpirit
0 / 0 / 0
Регистрация: 19.12.2012
Сообщений: 6
24.12.2013, 19:05  [ТС]     сортировка массива стуктур посредством указателей #5
в функцию сортировки передавать не массив, а указатель на него, получается?
void bubbleSort(arr *p, int n)?

Добавлено через 3 минуты
пузырьковую сортировку напрямую с массивом я знаю.
(знаю, что метод не ахти, но для понимания-то,что нужно)
а вот как её реальзовать через указатели? не могу найти инфу
dimcoder
Полярный
 Аватар для dimcoder
449 / 422 / 66
Регистрация: 11.09.2011
Сообщений: 1,108
24.12.2013, 19:10     сортировка массива стуктур посредством указателей #6
Цитата Сообщение от GrimSpirit Посмотреть сообщение
в функцию сортировки передавать не массив, а указатель на него, получается?
void bubbleSort(arr *p, int n)?
Имя массива и есть указатель на него.
GrimSpirit
0 / 0 / 0
Регистрация: 19.12.2012
Сообщений: 6
24.12.2013, 21:12  [ТС]     сортировка массива стуктур посредством указателей #7
прошу помочь с реализацией моей задачи, все мозги уже прокипятил себе

Добавлено через 13 минут
извиняюсь, мозги чуток подостыли, стал понимать.

C++
1
// if( p[i]->good && p[j]->good && ( сравниваем соответствующие строки  ) )
а вот как тут сравнивать соответствующие строки?
как в обычной сортировке, я правильно понял?

Добавлено через 35 минут
фуф. вроде бы похоже на правду.
гляньте пожалуйста на это:
C++
1
2
3
4
5
6
7
8
9
10
11
for(i=0;i<n;i++)//а вот здесь начинается сортировка -_-*
            {for(j=0;j<n;j++)
                {if( p[i]->good && p[j]->good &&
                    p[j+1]->max < p[j]->max)
                    {
                        for(int k=0;k<n;k++)
                        {tmp->a[k] = p[j+1]->a[k];} tmp->good = p[j+1]->good; tmp->max = p[j+1]->max;
                         for(int k=0;k<n;k++)
                        {p[j+1]->a[k] = p[j]->a[k];} p[j+1]->good = p[j]->good; p[j+1]->max = p[j]->max;
                         for(int k=0;k<n;k++)
                        {p[j]->a[k] = tmp->a[k];} p[j]->good = tmp->good; p[j]->max = tmp->max;
Добавлено через 15 минут
где-то ошибка, выводит неотсортированную матрицу
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
/*Дана целочисленная матрица А = {aij}, где 1<=i<=n; 1<=j<=m; 
Выбрать строки матрицы, не содержащие нулевых элементов, и отсортировать выбранные строки 
по возрастанию максимальных элементов таких строк. Если таких строк в матрице нет, выдать сообщение.*/
#include<iostream>
#include<fstream>
 
using namespace std;
const int N=10;
 
struct arr
{
    bool good; int a[N]; int max;
};
 
 
int main()
{
    int n,m,i,j,count=0;    //размерности; count для подсчета строк с нулями, если count == m, то выведем сообщение.
    ifstream fin("data.txt");
    if(fin.fail()) 
        cout<<"can't open data file"<<endl;
    fin>>n>>m;      //читаем размер матрицы
    
    arr *matr = new arr[N];
    for(i=0;i<n;i++)
        {matr[i].good=true;//по умолчанию присвоим всем bool-элементам значение true
        matr[i].max=-32768;}//присвоим всем элементам поля max начальное значение
                
        for(i=0;i<n;i++)    //заполняем массив
            for(j=0;j<m;j++)
            {fin>>matr[i].a[j];
        if(matr[i].a[j]==0) {count++; matr[i].good=false; continue;}//если в строке есть 0, то good=0, 
                
            }                                           //чтобы пропустить эту строку при сортировке
            fin.close();
            
    for(i=0;i<n;i++)    //выводим изначальный массив на экран
    {
        for(j=0;j<m;j++)
    cout<<matr[i].a[j]<<" ";
    cout<<endl;
    }cout<<endl;
 
        arr *p[N];//объявляем масив указателей
            for(i=0;i<n;i++) 
        p[i] = &matr[i]; //p[i] - указатель на массив структур matr[i]
                
        arr *tmp;
        for(i=0;i<n;i++)//а вот здесь начинается сортировка -_-*
            {for(j=0;j<n;j++)
                {if( p[i]->good && p[j]->good &&
                    p[j+1]->max < p[j]->max)
                    {
                        for(int k=0;k<n;k++)
                        {tmp->a[k] = p[j+1]->a[k];} tmp->good = p[j+1]->good; tmp->max = p[j+1]->max;//из j+1 во временную структуру
                         for(int k=0;k<n;k++)
                        {p[j+1]->a[k] = p[j]->a[k];} p[j+1]->good = p[j]->good; p[j+1]->max = p[j]->max;//из j+1 в j
                         for(int k=0;k<n;k++)
                        {p[j]->a[k] = tmp->a[k];} p[j]->good = tmp->good; p[j]->max = tmp->max;//из временной структуры в j
                    }
                }
            }
if(count==n)cout<<"All str have 0"<<endl;
    
 
if((n-count)>1) 
    for(i=0;i<n;i++)    //выводим полученный массив на экран
    {
        for(j=0;j<m;j++)
    cout<<p[i]->a[j]<<" ";
    cout<<endl;
    };
cout<<
system("pause");
return 0;
}
Добавлено через 43 минуты
не получается инициализировать структуру tmp.
dimcoder
Полярный
 Аватар для dimcoder
449 / 422 / 66
Регистрация: 11.09.2011
Сообщений: 1,108
24.12.2013, 21:15     сортировка массива стуктур посредством указателей #8
В код не вникал но
C++
1
arr *tmp;
доверия не внушает
C++
1
arr *tmp = new arr;
попробуйте.
Alex5
883 / 618 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
24.12.2013, 21:39     сортировка массива стуктур посредством указателей #9
Указатели здесь для того применяются, чтобы не нужно было копировать сами структуры.
C++
1
2
3
4
5
6
7
8
9
10
11
12
        for(i=0;i<n;i++)//а вот здесь начинается сортировка -_-*
            {for(j=0;j<n;j++)
                {if( p[i]->good && p[j]->good &&
                    p[j+1]->max < p[j]->max)
                    {
                        /* меняем местами значения в массиве p[] */
                        arr* tmp = p[j+1];
                        p[j+1] = p[j];
                        p[j] = tmp;
                    }
                }
            }
Добавлено через 4 минуты
Цитата Сообщение от GrimSpirit Посмотреть сообщение
где-то ошибка, выводит неотсортированную матрицу
Давайте использовать более подробный вывод. Не только a[], но и good, max. Правильно ли вычисляются good, max?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void print( arr* p[], int n, int m)   //выводим на экран, используя массив указателей p[]
{
    for( int i=0;i<n;i++)
    {
        for( int j=0;j<m;j++)
            cout<< p[i]->a[j]<<" ";
 
        cout << "     good: " << p[i]->good;
        cout << "     max: " << p[i]->max;
        cout<<endl;
    }
    cout<<endl;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.12.2013, 19:24     сортировка массива стуктур посредством указателей
Еще ссылки по теме:

Простая сортировка выбором с использованием указателей C++
Сортировка элементов массивов указателей на char C++
C++ Сортировка посредством слияния списков

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

Или воспользуйтесь поиском по форуму:
GrimSpirit
0 / 0 / 0
Регистрация: 19.12.2012
Сообщений: 6
25.12.2013, 19:24  [ТС]     сортировка массива стуктур посредством указателей #10
в if в сортировке какой-то ужас во время дебага:
p = 0x002af654 {0x0037d4c0 {good=true a=0x0037d4c4 {2, 3, 4, 5, 2, -842150451, -842150451, -842150451, -842150451, ...} ...}, ...} arr *[10]

и еще: в цикле сичтывания из файла я сразу выставляю max:
C++
1
2
3
4
5
6
7
for(i=0;i<n;i++)    //заполняем массив
            for(j=0;j<m;j++)
            {fin>>matr[i].a[j];
            if(matr[i].a[j]>matr[i].max) matr[i].max=matr[i].a[j];//надо бы выставить значения max
            if(matr[i].a[j]==0) {count++; matr[i].good=false; continue;}//если в строке есть 0, то good=0, 
            }                                           //чтобы пропустить эту строку при сортировке
            fin.close();
Добавлено через 21 час 15 минут
доделал программу, надеюсь и другим поможет:

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*Дана целочисленная матрица А = {aij}, где 1<=i<=n; 1<=j<=m; 
Выбрать строки матрицы, не содержащие нулевых элементов, и отсортировать выбранные строки 
по возрастанию максимальных элементов таких строк. Если таких строк в матрице нет, выдать сообщение.*/
#include<iostream>
#include<fstream>
 
using namespace std;
const int N=10;
 
struct arr
{
    bool good; int a[N]; int max;
};
 
 
int main()
{
    int n,m,i,j,count=0;    //размерности; count для подсчета строк с нулями, если count == m, то выведем сообщение.
    ifstream fin("data.txt");
    if(fin.fail()) 
        cout<<"can't open data file"<<endl;
    fin>>m>>n;      //читаем размер матрицы
    
    arr *matr = new arr[n];
    for(i=0;i<n;i++)
        for(j=m;j<N;j++)
        {
        matr[i].a[j]=0;//обнулим все элементы в полях а
        }
 
        for(i=0;i<n;i++)
        {
            matr[i].good=true;//по умолчанию присвоим всем bool-элементам значение true
                matr[i].max=-32768;//присвоим всем элементам поля max начальное значение
        }
 
        
        
        for(i=0;i<n;i++)    //заполняем массив
            for(j=0;j<m;j++)
            {fin>>matr[i].a[j];
                if(matr[i].a[j]>matr[i].max) matr[i].max=matr[i].a[j];//надо бы выставить значения max
                if(matr[i].a[j]==0) {count++; matr[i].good=false; continue;}//если в строке есть 0, то good=0, 
            }                                           //чтобы пропустить эту строку при сортировке
            fin.close();
            
 
    for(i=0;i<n;i++)    //выводим изначальный массив на экран
    {
        for(j=0;j<m;j++)
    cout<<matr[i].a[j]<<" ";
    cout<<endl;
    }cout<<endl;
                
        arr *p[N];//объявляем масив указателей
        for(i=0;i<n;i++)
        {p[i] = &matr[i];} //p[i] - указатель на массив структур matr[i]
        
        arr *tmp= new arr;//пытаемся инициализировать структуру -_-
            tmp = p[0];
            
            for(int k=0;k<m;k++)//а вот здесь начинается сортировка -_-*
            {
                for(i=1;i<n;)
                for(j=0;j<n;)
                {
                    while(p[j]->good && p[i]->good==0){i++;}
                    
                    if( p[j]->good && p[i]->good &&
                         p[j]->max > p[i]->max)
                         {
                            tmp = p[j];
                            p[j] = p[i];
                            p[i] = tmp;
                        }
                    j+=2;i=j+1;             
                }
            }
        if(count==n)cout<<"All str have 0"<<endl;
    
if((n-count)>1) 
    for(i=0;i<n;i++)    //выводим полученный массив на экран
    {
        for(j=0;j<m;j++)
    cout<<p[i]->a[j]<<" ";
    cout<<endl;
    };
system("pause");
return 0;
}
Yandex
Объявления
25.12.2013, 19:24     сортировка массива стуктур посредством указателей
Ответ Создать тему
Опции темы

Текущее время: 04:47. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru