感觉这题满有意思的。动手试试看。
可能我写的有点长,尽量加了注释。
因为考虑到一个数组里不只有一个元素是0值的,如果找到0就开始设置数组,恐怕后面的0就分不清是另一个元素的0,还是前面设置下来的0了。
所以,我用递归一层一层向下找,直至数组结尾没有0为止,再返回上一层开始设置0。这样就不会有无法分别哪个0是哪个的问题。因为返回后就代表目前这个0是数组里最后一个0,可以开始设置数组了。
/*
找出数组中元素为 0 的值,并将该元素所在行和列的所有元素都设为 0 ,
请使用原地算法完成。
*/
#include <stdio.h>
#include <string.h>
int zero_element(int *, int, int, int, int);
int main(void)
{
int i, j;
int m, n;
scanf("%d %d", &m, &n); // 输入两个整数 m , n
int a[m][n];// 声明数组大小
for (i=0 ; i<m ; i++)
{
for (j=0; j<n ; j++)
{
scanf("%d", &a[i][j]); // 输入数组元素值
}
}
printf("\n");
i=0,j=0; // m*n 数组初始检查下标 a[0][0]
zero_element(a[0], m, n, i, j); // 调用函数并设置数组
for (i=0 ; i<m ; i++)
{
for (j=0; j<n ; j++)
{
printf("%-2d", a[i][j]); // 输出设置0之后的数组
}
printf("\n");
}
printf("Press ENTER to continue ..");
getchar();
getchar();
return 0;
}
int zero_element(int *a, int m, int n, int row, int col)
{
int i, j, z;
for (i=row; i<m ; i++)
{
for (j=col; j<n ; j++)
{
if (*(a+i*n+j) == 0) // 该元素值为 0 时
{
zero_element(a, m, n, i, j+1); // 自下一个元素起递归调用函数
// 直至数组结尾没有0为止返回,
// 并开始设置数组。
for (z=0 ; z<i ; z++) // 设置元素所在行之前的行
{ *(a+z*n+j) = 0;}
for (z=i+1 ; z<m ; z++)// 设置元素所在行之后的行
{ *(a+z*n+j) = 0;}
for (z=0 ; z<j ; z++) // 设置元素所在列之前的列
{ *(a+i*n+z) = 0;}
for (z=j+1 ; z<n ; z++)// 设置元素所在列之后的列
{ *(a+i*n+z) = 0;}
return 0;
}
}
col = 0;
}
return 0;
}