On-line: гостей 0. Всего: 0 [подробнее..]
Программисты всех стран, объединяйтесь!

АвторСообщение



ссылка на сообщение  Отправлено: 13.11.18 17:42. Заголовок: Удаление из матрицы (двухмерного массива) строк, удовлетворяющих некоторому условию.


Эта тема создана на основе вопроса на Stackoverflow C 2D Arrays removing certain predetermined rows by shifting the ones below it.

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

Конечно, в буквальном смысле слова из двухмерного массива нельзя удалить строки. Предполагается, что "удаленные" строки будут переписываться теми строками, которые не удовлетворяют заданному условию удаления. Соответственно, нужно хранить число строк в массиве, которые в нем останутся после "удаления" строк, удовлетворяющих условию.

Автору вопроса требуется написать программу на языке C. Но интереснее выполнить задание на языке C++, используя стандартные алгоритмы.

Подход автора к решению данного задания слишком усложнен. Он собирается объявить еще один вспомогательный одномерный массив, который будет хранить индексы удаляемых строк. На самом деле в этом нет никакой необходимости.

Ниже приведена демонстрационная программа на C++, которая показывает, как можно выполнить поставленную задачу. В этой программе используется конструкция предложения if, появившееся в стандарте C++ 17.

 
#include <iostream>
#include <iterator>
#include <algorithm>
#include <numeric>

int main()
{
const size_t N = 3;
int a[N][N] =
{
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};

std::cout << "The original matrix:\n";
for ( const auto &row : a )
{
for ( const auto &x : row ) std::cout << x << ' ';
std::cout << '\n';
}

std::cout << '\n';

double total_average = std::accumulate( std::begin( reinterpret_cast<int ( & )[N * N]>( a ) ),
std::end( reinterpret_cast<int ( & )[N * N]>( a ) ),
0.0 ) / ( N * N );

std::cout << "total_average: " << total_average << '\n';

size_t n = 0;

for ( size_t i = 0; i < N; i++ )
{
if ( double row_average = std::accumulate( std::begin( a[ i ] ), std::end( a[ i ] ), 0.0 ) / N; not ( total_average < row_average ) )
{
std::cout << "retained row #" << i << " with the average " << row_average << '\n';
if ( i != n )
{
std::copy( std::begin( a[ i ] ), std::end( a[ i ] ), std::begin( a[ n ] ) );
}

++n;
}
else
{
std::cout << "deleted row #" << i << " with the average " << row_average << '\n';
}
}

std::cout << "\nThe result matrix:\n";
for ( size_t i = 0; i < n; i++ )
{
for ( const auto &x : a[ i ] ) std::cout << x << ' ';
std::cout << '\n';
}

std::cout << '\n';
}

Вывод этой демонстрационной программы на консоль следующий:
 
The original matrix:
1 2 3
4 5 6
7 8 9

total_average: 5
retained row #0 with the average 2
retained row #1 with the average 5
deleted row #2 with the average 8

The result matrix:
1 2 3
4 5 6

Если ваш компилятор еще не поддерживает данную конструкцию предложения if, то придется заменить ее на следующие предложения
 
double row_average = std::accumulate( std::begin( a[ i ] ), std::end( a[ i ] ), 0.0 ) / N;
if ( not ( total_average < row_average ) )


Спасибо: 0 
ПрофильЦитата Ответить
Новых ответов нет


Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 5
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет