Эта тема создана на основе вопроса на 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 ) )