Я пытался решить следующую проблему:
Подсчитайте вхождения в каждой строке требуемого входного значения в матрице 4x4.
Затем измените вхождение на значение 0 только в тех строках, где это значение встречается два или более раз.
На первом этапе у меня не было никаких проблем, но второй доставляет мне много хлопот.
После нескольких попыток мне удалось добраться до этой точки:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define N 4
int main() {
int mat[N][N] = { {6, 75, 45, 6}, {30, 6, 77, 64}, {15, 35, 6, 43}, {6, 95, 47, 6} };
int val;
int i, j;
int count_occ = 0;
srand(time(NULL));
/* for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
mat[i][j] = (rand() % 99 + 1);
}
} */
printf("Matrix original: \n");
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
printf("%3d", mat[i][j]);
}
printf("\n");
}
puts("");
printf("Insert a value to search for: ");
scanf("%d", &val);
puts("");
// Counting occurrencies of a value in each row
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (mat[i][j] == val) {
count_occ++;
if (count_occ >= 2) {
mat[i][j] = 0;
}
}
}
printf("There are %d occurrencies of value %d in row %d. \n", count_occ, val, i);
count_occ = 0;
}
puts("");
printf("Matrix modified: \n");
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
printf("%3d", mat[i][j]);
}
printf("\n");
}
puts("");
}
Со следующим выводом:
Matrix original:
6 75 45 6
30 6 77 64
15 35 6 43
6 95 47 6
Insert a value to search for: 6
There are 2 occurrencies of value 6 in row 0.
There are 1 occurrencies of value 6 in row 1.
There are 1 occurrencies of value 6 in row 2.
There are 2 occurrencies of value 6 in row 3.
Matrix modified:
6 75 45 0
30 6 77 64
15 35 6 43
6 95 47 0
Как видите, модифицируются только некоторые значения рассматриваемых строк, а не все необходимые.
Может ли кто-нибудь дать мне несколько советов о том, как это сделать? я волнуюсь
Ваш текущий алгоритм следующий:
Для каждого числа в матрице, если число является входным значением и входное значение уже встречалось в этой строке, установите число на
0
.
Этот алгоритм неверен, так как он никогда не установит первое вхождение входного значения в строке как 0
.
Один простой правильный алгоритм будет следующим:
Для каждой строки в матрице сначала определите, встречается ли входное значение хотя бы дважды в этой строке. Если это не произойдет хотя бы дважды, то ничего не делайте. В противном случае вернитесь к началу строки и замените все вхождения входного значения на
0
.
Вот демонстрационная программа:
#include <stdio.h>
#define N 4
void print_matrix( int matrix[N][N] );
int main( void )
{
int mat[N][N] =
{
{ 6, 75, 45, 6 },
{ 30, 6, 77, 64 },
{ 15, 35, 6, 43 },
{ 6, 95, 47, 6 }
};
int val;
//print original matrix
printf( "Matrix original:\n" );
print_matrix( mat );
//add spacing
puts( "" );
//get input from user
printf( "Insert a value to search for: " );
scanf( "%d", &val );
//add spacing
puts( "" );
//process one row per loop iteration
for ( int i = 0; i < N; i++ )
{
int count_occ = 0;
//count number of occurrences in the current row
for ( int j = 0; j < N; j++ )
{
if ( mat[i][j] == val )
{
count_occ++;
}
}
//print information about number of occurrences
printf(
"There are %d occurrences of value %d in row %d.\n",
count_occ, val, i
);
//determine whether number of occurrences on the
//current line is at least two
if ( count_occ >= 2 )
{
//replace all occurrences on the current line
//with zero
for ( int j = 0; j < N; j++ )
{
if ( mat[i][j] == val )
{
mat[i][j] = 0;
}
}
}
}
//add spacing
puts( "" );
//print modified matrix
printf( "Matrix modified:\n" );
print_matrix( mat );
//add spacing
puts( "" );
}
void print_matrix( int matrix[N][N] )
{
for ( int i = 0; i < N; i++ )
{
for ( int j = 0; j < N; j++ )
{
printf( "%3d", matrix[i][j] );
}
printf( "\n" );
}
}
Эта программа имеет следующее поведение:
Matrix original:
6 75 45 6
30 6 77 64
15 35 6 43
6 95 47 6
Insert a value to search for: 6
There are 2 occurrences of value 6 in row 0.
There are 1 occurrences of value 6 in row 1.
There are 1 occurrences of value 6 in row 2.
There are 2 occurrences of value 6 in row 3.
Matrix modified:
0 75 45 0
30 6 77 64
15 35 6 43
0 95 47 0
Этот алгоритм можно сделать более эффективным, если запомнить индекс первого вхождения, чтобы вам не приходилось возвращаться к началу строки. Однако это также усложнило бы алгоритм, поэтому такая оптимизация будет полезна только для больших матриц.
хорошо, может быть, я понял концепцию, но я не знаю, как реализовать ее в моем коде, не могли бы вы дать мне подсказку? может быть, с частью вашего кода?
@pluggedmxrigh: я добавил к своему ответу демонстрационную программу.
Самый простой (и во многом неэффективный) способ — сделать вторую пару петель.
Первая пара циклов (на основе ваших) теперь только подсчитывает вхождения и сохраняет их в массиве row_occ[N]
. Вторая пара циклов только заменяет значения. Это неэффективно, но довольно просто.
int row_occ[N]; // ADDED
// This loop will only count
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
if (mat[i][j] == val)
{
count_occ++;
}
}
printf("There are %d occurrencies of value %d in row %d. \n", count_occ, val, i);
row_occ[i] = count_occ; // ADDED
count_occ = 0;
}
// This loop will only replace
for (i = 0; i < N; i++)
{
if (row_occ[i] < 2)
continue; // we will replace only if value occurs 2 or more times.
for (j = 0; j < N; j++)
{
if (mat[i][j] == val)
{
mat[i][j] = 0; //replacing
}
}
}
Лучший подход (и тот, который вы пытаетесь реализовать) - просто добавить одну переменную, которая будет помнить индекс последнего вхождения значения. Когда у вас есть этот индекс, вы можете заменить не только текущее вхождение, но и предыдущее.
for (i = 0; i < N; i++)
{
int prev_occ;
for (j = 0; j < N; j++)
{
if (mat[i][j] == val)
{
count_occ++;
if (count_occ >= 2)
{
mat[i][prev_occ] = 0;
mat[i][j] = 0;
}
prev_occ = j;
}
}
printf("There are %d occurrencies of value %d in row %d. \n", count_occ, val, i);
count_occ = 0;
}
Первый подход не так глуп, как кажется. Представьте себе огромный массив и условие замены «100 и более вхождений». ИМХО вполне нормально будет реализовать это в первом способе. Наконец, до тех пор, пока это не задача наиболее оптимизированного кода, а скорее самого простого для написания, понимания и обслуживания.
Конечно, вы начинаете изменять значения до нуля после того, как обнаружили, что количество больше двух, тогда предыдущие значения в строке должны оставаться неизменными.