在矩阵中更改一个值的出现次数

huangapple go评论63阅读模式
英文:

Change the occurrences of a value in a matrix

问题

以下是您提供的翻译:

我尝试解决以下问题:

- 统计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("原始矩阵:\n");
for (i = 0; i < N; i++) {
    for (j = 0; j < N; j++) {
        printf("%3d", mat[i][j]);
    }
    printf("\n");
}
    
puts("");

printf("输入要搜索的值:");
scanf("%d", &val);

puts("");

// 统计每行中值的出现次数
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("第%d行中值%d出现%d次。\n", count_occ, val, i);
    count_occ = 0;
}

puts("");

printf("修改后的矩阵:\n");
for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
        printf("%3d", mat[i][j]);
    }
    printf("\n");
}

puts("");

}

输出如下:

原始矩阵:
6 75 45 6
30 6 77 64
15 35 6 43
6 95 47 6

输入要搜索的值:6

第0行中值6出现2次。
第1行中值6出现1次。
第2行中值6出现1次。
第3行中值6出现2次。

修改后的矩阵:
6 75 45 0
30 6 77 64
15 35 0 43
6 95 47 0

如您所见,只有一些行中的值被修改,而不是所有必要的行。

英文:

I was trying to solve the following problem:

  • Count the occurrences in each row of a required input value in a 4x4 matrix

  • Then, change the occurrence to the value 0 only in the lines where the value appears two or more times

For the first step I didn't have any problems, but the second is giving me a lot of trouble.

After several attempts I managed to get to this point:

#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("");
}

With the following output:

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

As you can see, only some values ​​of the rows in question are modified, but not all the necessary ones.

Could anyone give me some advice on how to do this? I'm freaking out

答案1

得分: 0

以下是您要翻译的内容:

Your current algorithm is the following:

For every number in the matrix, if the number is the input value and the input value has already been encountered on that line, then set the number to 0.

This algorithm is incorrect, as it will never set the first occurrence of the input value on a line to 0.

One simple correct algorithm would be the following:

For every line in the matrix, first determine whether the input value occurs at least twice on that line. If it does not occur at least twice, then do nothing. Otherwise, go back to the start of the line and replace all occurrences of the input value to 0.

Here is a demonstration program:

#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");
    }
}

This program has the following behavior:

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

This algorithm could be made more efficient by remembering the index of the first occurrence, so that you don't have to go back to the start of the line. However, this would make the algorithm also more complicated, so this optimization would only be worthwhile for larger matrices.

英文:

Your current algorithm is the following:

> For every number in the matrix, if the number is the input value and the input value has already been encountered on that line, then set the number to 0.

This algorithm is incorrect, as it will never set the first occurrence of the input value on a line to 0.

One simple correct algorithm would be the following:

> For every line in the matrix, first determine whether the input value occurs at least twice on that line. If it does not occur at least twice, then do nothing. Otherwise, go back to the start of the line and replace all occurrences of the input value to 0.

Here is a demonstration program:

#include &lt;stdio.h&gt;
#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( &quot;Matrix original:\n&quot; );
print_matrix( mat );
//add spacing
puts( &quot;&quot; );
//get input from user
printf( &quot;Insert a value to search for: &quot; );
scanf( &quot;%d&quot;, &amp;val );
//add spacing
puts( &quot;&quot; );
//process one row per loop iteration
for ( int i = 0; i &lt; N; i++ )
{
int count_occ = 0;
//count number of occurrences in the current row
for ( int j = 0; j &lt; N; j++ )
{
if ( mat[i][j] == val )
{
count_occ++;
}
}
//print information about number of occurrences
printf(
&quot;There are %d occurrences of value %d in row %d.\n&quot;,
count_occ, val, i
);
//determine whether number of occurrences on the
//current line is at least two
if ( count_occ &gt;= 2 )
{
//replace all occurrences on the current line
//with zero
for ( int j = 0; j &lt; N; j++ )
{
if ( mat[i][j] == val )
{
mat[i][j] = 0;
}
}
}
}
//add spacing
puts( &quot;&quot; );
//print modified matrix
printf( &quot;Matrix modified:\n&quot; );
print_matrix( mat );
//add spacing
puts( &quot;&quot; );
}
void print_matrix( int matrix[N][N] )
{
for ( int i = 0; i &lt; N; i++ )
{
for ( int j = 0; j &lt; N; j++ )
{
printf( &quot;%3d&quot;, matrix[i][j] );
}
printf( &quot;\n&quot; );
}
}

This program has the following behavior:

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

This algorithm could be made more efficient by remembering the index of the first occurrence, so that you don't have to go back to the start of the line. However, this would make the algorithm also more complicated, so this optimization would only be worthwhile for larger matrixes.

答案2

得分: 0

以下是翻译好的部分:

第一个方法(在许多方面效率低下)是制作第二对循环。
第一对循环(基于您的循环)现在仅计算出现次数并将其保存到row_occ[N]数组中。第二对循环仅替换值。它效率低下,但相当简单。

int row_occ[N]; // 添加
// 此循环仅计数
for (i = 0; i &lt; N; i++)
{
for (j = 0; j &lt; N; j++)
{
if (mat[i][j] == val)
{
count_occ++;
}
}
printf("在第 %d 行中值为 %d 的出现次数为 %d。 \n", count_occ, val, i);
row_occ[i] = count_occ; // 添加
count_occ = 0;
}
// 此循环仅替换
for (i = 0; i &lt; N; i++)
{
if (row_occ[i] &lt; 2)
continue; // 仅当值出现2次或更多时才替换。
for (j = 0; j &lt; N; j++)
{
if (mat[i][j] == val)
{
mat[i][j] = 0; //替换
}
}
}

更好的方法(您正在尝试实现的方法)是只添加一个单一的变量,它将记住值的最后出现位置的索引。当您拥有这个索引时,您不仅可以替换当前出现,还可以替换前一个出现。

for (i = 0; i &lt; N; i++)
{
int prev_occ;
for (j = 0; j &lt; N; j++)
{
if (mat[i][j] == val)
{
count_occ++;
if (count_occ &gt;= 2)
{
mat[i][prev_occ] = 0;
mat[i][j] = 0;
}
prev_occ = j;
}
}
printf("在第 %d 行中值为 %d 的出现次数为 %d。 \n", count_occ, val, i);
count_occ = 0;
}

第一个方法并不像看起来那么没有意义。想象一下巨大的数组和替换条件“100次或更多次出现”。在我看来,使用第一种方法来实现它将是相当可以接受的。至少只要它不是最优化代码的挑战,而更多是最容易编写、理解和维护的代码。

英文:

The simplest (and inefficient in many ways) method is to make second pair of loops.
The first pair of loops (based on yours) is now only counting occurrences and saving it to the row_occ[N] array. The second pair of loops is only replacing values. It's inefficient, but quite simple.

int row_occ[N]; // ADDED
// This loop will only count
for (i = 0; i &lt; N; i++)
{
for (j = 0; j &lt; N; j++)
{
if (mat[i][j] == val)
{
count_occ++;
}
}
printf(&quot;There are %d occurrencies of value %d in row %d. \n&quot;, count_occ, val, i);
row_occ[i] = count_occ; // ADDED
count_occ = 0;
}
// This loop will only replace
for (i = 0; i &lt; N; i++)
{
if (row_occ[i] &lt; 2)
continue; // we will replace only if value occurs 2 or more times.
for (j = 0; j &lt; N; j++)
{
if (mat[i][j] == val)
{
mat[i][j] = 0; //replacing
}
}
}

Better approach (and the one you are trying to implement) is to just add a single variable that will remember index of last occurrence of the value. When you have this index, you can replace not only current occurrence, but also the previous.

for (i = 0; i &lt; N; i++)
{
int prev_occ;
for (j = 0; j &lt; N; j++)
{
if (mat[i][j] == val)
{
count_occ++;
if (count_occ &gt;= 2)
{
mat[i][prev_occ] = 0;
mat[i][j] = 0;
}
prev_occ = j;
}
}
printf(&quot;There are %d occurrencies of value %d in row %d. \n&quot;, count_occ, val, i);
count_occ = 0;
}

The first approach is not as nonsense as it looks like. Imagine huge array and condition of replacement "100 or more occurrences". IMHO it will be quite ok to implement it in the first method. At last as long as it is not the challenge of the most optimized code, but rather the easiest to write, understand and maintain.

huangapple
  • 本文由 发表于 2023年2月14日 20:22:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75447765.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定