Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.12.2015, 09:33   #1
jirtreck
Пользователь
 
Регистрация: 29.06.2011
Сообщений: 56
По умолчанию Сортировка столбцов двумерного массива

Характеристикой столбца целочисленной матрицы назовем сумму модулей его отрицательных нечетных элементов.
Переставляя столбцы заданной матрицы, расположить их в соответствии с ростом характеристик.
Найти сумму элементов в тех столбцах, которые содержат хотя бы один отрицательный элемент.


В своей программе я сделал так, что отыскал характеристику для каждого столбца, сунул их в одномерный массив и отсортировал от меньшего к большему.
Каким образом я могу использовать в программе полученный массив из характеристик? Если продолжение моей программы невозможно, прошу указать как надо было сделать правильно.
С поиском суммы столбцов с отрицательными справлюсь самостоятельно.

По мере исполнения программы я захотел посмотреть как работает сортировка характеристик, поэтому вывел свой массив и массив параметров. Результат - пустой экран.
http://prntscr.com/9fkdqq
Что в моей программе это вызывает?

Код:
#include <stdio.h>
#include <iostream>
const int N=6;
using namespace std;
void main()
{
int M[N][N], i1, i2, i3, i4, i5, i6, n1, n2, n3, a;
for (int i = 0; i < N; i++)
{
	for(int j=0;j<N;j++)	
	M[i][j] = rand() % 199-99;
}

for (int j = 0; j < N; j++)
{
	for (int i = 0; i < N; i++)	
	{
		if (i==0 && M[i][j]<0) n1=abs(M[i][j]); else n1=0;
	        if (i==2 && M[i][j]<0) n2=abs(M[i][j]); else n2=0;
		if (i==4 && M[i][j]<0) n3=abs(M[i][j]); else n3=0;
	}
	if (j==0) i1=n1+n2+n3;
	if (j==1) i2=n1+n2+n3;
	if (j==2) i3=n1+n2+n3;
	if (j==3) i4=n1+n2+n3;
	if (j==4) i5=n1+n2+n3;
	if (j==5) i6=n1+n2+n3;
}   

int I[N]={i1,i2,i3,i4,i5,i6};
for (int i=0;i<N;i+1) {
	for (int j=0;j<N;j+1)
	{
		if (I[j]<I[i]){a=I[i];I[i]=I[j];I[j]=a;
        }
	}
}

for (int i = 0; i < N; i++)
 { 
     for(int j = 0; j < N; j++) cout << M[i][j] << " ";
     cout << endl;
 }

for (int i = 0; i < N; i++)
 {  cout << I[i] << " ";
 }
system("pause");
}

Последний раз редактировалось jirtreck; 18.12.2015 в 09:44.
jirtreck вне форума Ответить с цитированием
Старый 18.12.2015, 10:19   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
if (I[j]<I[i]){a=I[i];I[i]=I[j];I[j]=a;
А где перестановки самой таблицы индексации? Где перестановка I?
Цитата:
int I[N]={i1,i2,i3,i4,i5,i6};
А почему заранее не сделал такой массив? Зачем все эти i1, i2, i3, i4, i5, i6 ?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 18.12.2015, 10:29   #3
jirtreck
Пользователь
 
Регистрация: 29.06.2011
Сообщений: 56
По умолчанию

Если под индексацией вы имеете в виду престановку столбов массива M, то я не знаю как это оформить из моей текущей программы, поэтому обратился сюда.
Массив I я отсортировал от меньшего к большему, не понимаю что вы имеете в виду под перестановкой I

Не дошло тогда про массив, захотел переменными, спасибо за корректировку!

Я еще неопытен, потому прошу простить, если не вижу очевидного

Последний раз редактировалось Stilet; 18.12.2015 в 12:24.
jirtreck вне форума Ответить с цитированием
Старый 18.12.2015, 12:31   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Если под индексацией вы имеете в виду престановку столбов массива
Индексация - это массив, который указывает на положение элементов массив данных.
У тебя это массив I.
Короче. Тебе нужно завести два массива: Массив номеров (I) массив характеристик (С)
Массив характеристик ты заполнишь суммой модулей отрицательных нечетных элементов. Массив I соответственно заполнишь номерами колонок
Тогда получится такая перестановка:
Код:
for(int j=0;j<N;j++) I[j]=j;
for (int i=0;i<N;i+1) {
	for (int j=0;j<N;j+1)
	{
		if (С[I[j]]<C[I[i]]){a=I[i];I[i]=I[j];I[j]=a;}
	}
}
Ну и потом делать так:
Код:
for (int i=0;i<N;i+1) {
	for (int j=0;j<N;j+1)
	{
	   cout<<M[i][I[j]];
	}
 cout<<endl;
}
Т.е. ты сортируешь индексный массив I, который содержит порядковые номера столбцов, а потом по этим поядковым номерам столбцы матрицы и выводишь
Понял идею?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 18.12.2015, 15:36   #5
jirtreck
Пользователь
 
Регистрация: 29.06.2011
Сообщений: 56
По умолчанию

Дошло, но мне после 7 часов сидения над программами для универа показалось, что первый цикл, который задает I, вбирает в себя другие циклы. Битый час пытался встегнуться в такую логику.

Нашел свою ошибку и поправил:

Код:
for (int i=0;i<N-1;i++) {
	for (int j=i+1;j<N;j++)
	{
		if (С[I[j]]<C[I[i]]){a=I[i];I[i]=I[j];I[j]=a;}
	}
}
Когда цикл проходит j, то переключается на следующую i, раньше так было, что программа после этого делала выражения с 0м элементом массива, сводя сортировку на нет, на выходе бы получался бред.

Благодарю за подачу методики решения!

Теперь у меня вечный цикл с постоянно вызывающейся -58

Что не так?

Код:
#include <stdio.h>
#include <iostream>
const int N=6;
using namespace std;
void main()
{
int M[N][N], n1, n2, n3, C[N], I[N], a;
for (int i = 0; i < N; i++)
{
	for(int j=0;j<N;j++)	
	M[i][j] = rand() % 199-99;
}

for (int j = 0; j < N; j++)
{
	for (int i = 0; i < N; i++)	
	{
		if (i==0 && M[i][j]<0) n1=abs(M[i][j]); else n1=0;
	    if (i==2 && M[i][j]<0) n2=abs(M[i][j]); else n2=0;
		if (i==4 && M[i][j]<0) n3=abs(M[i][j]); else n3=0;
	}
	if (j==0) C[1]=n1+n2+n3;
	if (j==1) C[2]=n1+n2+n3;
	if (j==2) C[3]=n1+n2+n3;
	if (j==3) C[4]=n1+n2+n3;
	if (j==4) C[5]=n1+n2+n3;
	if (j==5) C[6]=n1+n2+n3;
}   

for (int j=0;j<N;j++) I[j]=j;
for (int i=0;i<N-1;i++)
{
	for (int j=i+1;i<N;i++)
	{
		if (C[I[j]]<C[I[i]]) 
		{
			a=I[i];I[i]=I[j];I[j]=a;
		}
	}
}

for (int i=0;i<N;i+1) {
	for (int j=0;j<N;j+1)
	{
	   cout<<M[i][I[j]];
	}
 cout<<endl;
}

system("pause");
}
Нашел в дебаге, что это I[j] принимает очень больше число.
Но почему оно его принимает?

Одну из ошибок нашел: C выходил за значения N, когда я его заполнял.

Код:
        if (j==0) C[0]=n1+n2+n3;
	if (j==1) C[1]=n1+n2+n3;
	if (j==2) C[2]=n1+n2+n3;
	if (j==3) C[3]=n1+n2+n3;
	if (j==4) C[4]=n1+n2+n3;
	if (j==5) C[5]=n1+n2+n3;
Бесконечный цикл все тот же

Последний раз редактировалось Stilet; 18.12.2015 в 18:21.
jirtreck вне форума Ответить с цитированием
Старый 18.12.2015, 17:35   #6
jirtreck
Пользователь
 
Регистрация: 29.06.2011
Сообщений: 56
По умолчанию

Не знал о настолько жуткой разнице между ++ и +1 в конце итерации цикла...

Заменил все на ++ и поехало

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

Код:
#include <stdio.h>
#include <iostream>
const int N=6;
using namespace std;
void main()
{
int M[N][N], n1, n2, n3, C[N], I[N], a;
for (int i = 0; i < N; i++)
{
	for(int j=0;j<N;j++)	
	M[i][j] = rand() % 199-99;
}

for (int j = 0; j < N; j++)
{
	for (int i = 0; i < N; i++)	
	{
		if (i==0 && M[i][j]<0) n1=abs(M[i][j]); else n1=0;
	    if (i==2 && M[i][j]<0) n2=abs(M[i][j]); else n2=0;
		if (i==4 && M[i][j]<0) n3=abs(M[i][j]); else n3=0;
	}
	if (j==0) C[0]=n1+n2+n3;
	if (j==1) C[1]=n1+n2+n3;
	if (j==2) C[2]=n1+n2+n3;
	if (j==3) C[3]=n1+n2+n3;
	if (j==4) C[4]=n1+n2+n3;
	if (j==5) C[5]=n1+n2+n3;
}   

for (int j=0;j<N;j++) I[j]=j;
for (int i=0;i<N-1;i++)
{
	for (int j=i+1;i<N;i++)
	{
		if (C[I[j]]<C[I[i]]) 
		{
			a=I[i];I[i]=I[j];I[j]=a;
		}
	}
}

for (int i=0;i<N;i++) {
	for (int j=0;j<N;j++)
	{
	   cout<<M[I[j]][i]<<" ";
	}
 cout<<endl;
}

system("pause");
}
То, что у меня выводятся одни и те же, как раз и называется псевдослучайными числами, или у меня еще ошибки?

Последний раз редактировалось Stilet; 18.12.2015 в 18:21.
jirtreck вне форума Ответить с цитированием
Старый 18.12.2015, 17:55   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

генератор псевдослучайных чисел нужно перед использованием иницилизировать.

гуглите srand()
Serge_Bliznykov вне форума Ответить с цитированием
Старый 18.12.2015, 18:22   #8
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Не знал о настолько жуткой разнице между ++ и +1 в конце итерации цикла...
Дык +1 просто выражение которое влияет на результат, а ++ - инкремент, который прежде всего влияет на саму переменную. )
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 18.12.2015, 18:28   #9
jirtreck
Пользователь
 
Регистрация: 29.06.2011
Сообщений: 56
По умолчанию

Теперь сортировка не работает по-хорошему:

Код:
#include <stdio.h>
#include <iostream>
#include <time.h>
 
const int N=6;
using namespace std;
void main()
{
    srand (time(NULL));
int M[N][N], n1, n2, n3, C[N], I[N], a;
for (int i = 0; i < N; i++)
{
    for(int j=0;j<N;j++){ 
    
    M[i][j] = rand() % 199-99;
}
}
 
for (int j = 0; j < N; j++)
{
    for (int i = 0; i < N; i++) 
    {
        if (i==0 && M[i][j]<0) n1=abs(M[i][j]); else n1=0;
        if (i==2 && M[i][j]<0) n2=abs(M[i][j]); else n2=0;
        if (i==4 && M[i][j]<0) n3=abs(M[i][j]); else n3=0;
    }
    if (j==0) C[0]=n1+n2+n3;
    if (j==1) C[1]=n1+n2+n3;
    if (j==2) C[2]=n1+n2+n3;
    if (j==3) C[3]=n1+n2+n3;
    if (j==4) C[4]=n1+n2+n3;
    if (j==5) C[5]=n1+n2+n3;
}   
 
for (int j=0;j<N;j++) I[j]=j;
for (int i=0;i<N-1;i++)
{
    for (int j=i+1;i<N;i++)
    {
        if (C[I[j]]<C[I[i]]) 
        {
            a=I[i];I[i]=I[j];I[j]=a;
        }
    }
}
 
for (int i=0;i<N;i++) {
    for (int j=0;j<N;j++)
    {
       cout<<M[i][I[j]]<<"\t";
    }
 cout<<endl;
}
 
system("pause");
}

Считаю модули выведенных чисел, - значения вразброс.
jirtreck вне форума Ответить с цитированием
Старый 18.12.2015, 18:52   #10
jirtreck
Пользователь
 
Регистрация: 29.06.2011
Сообщений: 56
По умолчанию

Вывожу до сортировки по номерам

Код:
for (int i=0;i<N;i++) {
    for (int j=0;j<N;j++)
    {
       cout<<M[i][j]<<"\t";
    }
 cout<<endl;
}
И меняю последний вывод на

Код:
cout<<M[I[j]][i]<<"\t";
Получил транспонирование, забавно...
http://prntscr.com/9fpkxj

Последний раз редактировалось jirtreck; 18.12.2015 в 19:12.
jirtreck вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сдвиг строк/столбцов двумерного массива (судоку) Ilyard C# (си шарп) 3 17.01.2014 16:53
Удаление строк и столбцов двумерного массива Павел Шилин Паскаль, Turbo Pascal, PascalABC.NET 1 20.05.2012 21:07
Сортировка двумерного массива shadowfiend C++ Builder 0 21.04.2011 19:29
Сортировка двумерного массива AlexXXX12389 Помощь студентам 0 17.10.2010 10:32
Сортироука столбцов двумерного массива Гамбит Помощь студентам 10 05.05.2010 19:27