讲一个2*2的矩阵最大元素放在中心,4个最小元素分别放四个角

img


我在做该编程时打算用指针遍历矩阵,再用指针记住最大最小值的地址,最后将中心的值与最大值交换,四个最小值与四个依次与四个角交换,在编程后,输入了
4 6 5 11 13
2 3 7 16 15
8 1 9 21 23
18 19 25 26 20
24 22 16 14 17
这个矩阵,最小值1没有在左上角,4也没有被交换到1的位置,而其他三个角却是交换正确的。

#include<stdio.h>
int i=0,j=0,k=0;
int main()
{
    void transform(int a[][5]);
    int a[5][5]; 
    for(i=0;i<5;i++)
    {
        for(j=0;j<5;j++)
        {
            scanf("%d",&a[i][j]);//输入 
        }
    }
    transform(a);//调用函数 
}
void transform(int a[][5])
{
    int max=0,min,t=0,mins[4];//max用来存矩阵中的最大值,min用来存临时的每一次遍历矩阵时的最小值  
    int *p,*p_max,*p_min[4];//mins[4]用来依次存每一次遍历矩阵时的最小值,也就是mins中存着原矩阵中最小的4个数 
    p=&a[0][0];//*p为遍历所用指针,*p_max用来存原矩阵最大值的地址,*p_min[4]用来存原矩阵中最小的4个数的地址 
    while(p!=(*a)+25)//寻找矩阵最大值 
    {
        if(*p>max)
        {
            p_max=p;
            max=*p;
        }
        p++;
    }
    *p_max=a[2][2];//将最大值与矩阵中心的值互换 
    a[2][2]=max;
    for(i=0;i<4;i++)//遍历4遍 
    {
        min=max;//先将min变成最大值,方便每次遍历时求最小值 
        p=&a[0][0];//将遍历指针重新指向矩阵首元素地址 
        while(p!=(*a)+25)//遍历寻找最小值 
        {
            if(*p<min)
            {
                p_min[i]=p;//找到后将将地址依次存入p_min 
                min=*p;//将临时最小值也变成当前最小值 
            }
            p++;
        }
        mins[i]=min;//将遍历一遍后的最小值依次存入mins 
        *p_min[i]=max;//防止下一次遍历又找到此位置的值 
    }
    for(i=0;i<5;i++)//将最小值依次与四个角的值交换位置 
    {
        for(j=0;j<5;j++)
        {
            if((i==0||i==4)&&(j==0||j==4))
            {
                *p_min[k]=a[i][j];
                a[i][j]=mins[k];
                k++;
            }
        }
    }
    for(i=0;i<5;i++) 
    {
        printf("\n");
        for(j=0;j<5;j++)
        {
            printf("%d\t",a[i][j]);
        }
    }//结果中a[0][0]与最小值没有交换 
/*    printf("a[0][0]=%d\n*p_min[0]=%o\n&a[2][1]=%o\nmins[0]=%d",a[0][0],*p_min[0],&a[2][1],mins[0]);//debug代码 
    for(i=0;i<5;i++)
    {
        printf("\n");
        for(j=0;j<5;j++)
        {
            printf("&a[%d][%d]=%o\t",i,j,&a[i][j]);
        }
    }
*/
}


img

你的代码有两个问题:
(1)在找4个最小值的时候,逻辑有问题,应该需要判断p是否已经在p_min数组中了,如果在,那么就忽略,继续找;如果不在,就插入
(2)在替换4个角的元素时,你的测试用例正好是一个特殊的用例,4这个值正好是4个最小值中的一个,并且,4在第一个角上,就导致在后面替换的时候,在第一次交换的时候,4已经被换到1所在的位置了,所以,后面再去替换的时候,就导致出错。

修改后的运行结果:

img

修改后的代码:

#include<stdio.h>
int i=0,j=0,k=0;

int main()
{
    void transform(int a[][5]);
    int a[5][5]; 
    for(i=0;i<5;i++)
    {
        for(j=0;j<5;j++)
        {
            scanf("%d",&a[i][j]);//输入 
        }
    }
    transform(a);//调用函数 
}
void transform(int a[][5])
{
    int max=0,min,t=0,mins[4];//max用来存矩阵中的最大值,min用来存临时的每一次遍历矩阵时的最小值  
    int *p,*p_max,*p_min[4];//mins[4]用来依次存每一次遍历矩阵时的最小值,也就是mins中存着原矩阵中最小的4个数 

    int nn = 0;
    int *core[4]={&a[0][0],&a[0][4],&a[4][0],&a[4][4]};


    p=&a[0][0];//*p为遍历所用指针,*p_max用来存原矩阵最大值的地址,*p_min[4]用来存原矩阵中最小的4个数的地址 
    while(p!=(*a)+25)//寻找矩阵最大值 
    {
        if(*p>max)
        {
            p_max=p;
            max=*p;
        }
        p++;
    }
    *p_max=a[2][2];//将最大值与矩阵中心的值互换 
    a[2][2]=max;
    for(i=0;i<4;i++)//遍历4遍 
    {
        min=max;//先将min变成最大值,方便每次遍历时求最小值 
        p=&a[0][0];//将遍历指针重新指向矩阵首元素地址 
        while(p!=(*a)+25)//遍历寻找最小值 
        {
            if(*p<min)
            {
                for(j=0;j<i;j++) //这里判断是否已经在最小数数组中了
                {
                    if(p_min[j]==p)
                        break;
                }
                if(j==i)
                {
                    p_min[i]=p;//找到后将将地址依次存入p_min 
                    min=*p;//将临时最小值也变成当前最小值
                    mins[i]=*p;
                }
                
            }
            p++;
        }
        //mins[i]=min;//将遍历一遍后的最小值依次存入mins 
        //*p_min[i]=max;//防止下一次遍历又找到此位置的值 
    }

    k = 0;
    for(i=0;i<5;i++)//将最小值依次与四个角的值交换位置 
    {
        for(j=0;j<5;j++)
        {
            if((i==0||i==4)&&(j==0||j==4))
            {
                //判断是否已经被占用
                for(nn = 0;nn<k;nn++)
                {
                    if(p_min[k] == core[nn])
                        break;
                }
                if(nn == k)
                {
                    *p_min[k]=a[i][j];
                    a[i][j]=mins[k];
                }else
                {
                    *p_min[nn] = a[i][j];
                    a[i][j]=mins[k];
                }
                
                k++;
            }
        }
    }

    




    for(i=0;i<5;i++) 
    {
        printf("\n");
        for(j=0;j<5;j++)
        {
            printf("%d\t",a[i][j]);
        }
    }
}
 
 

#include <stdio.h>
int main()
{void change(int *p);
 int a[5][5],*p,i,j;
 printf("input matrix:\n");
 for (i=0;i<5;i++)
   for (j=0;j<5;j++)
     scanf("%d",&a[i][j]);
 p=&a[0][0];
 change(p);
 printf("Now,matrix:\n");
 for (i=0;i<5;i++)
  {for (j=0;j<5;j++)
     printf("%d ",a[i][j]);
   printf("\n");
  }
 return 0;
}
 
void change(int *p)          //交换函数
 {int i,j,temp;
  int *pmax,*pmin;
  pmax=p;
  pmin=p;
  for (i=0;i<5;i++)          //找最大值和最小值的地址,并赋给 pmax,pmin
    for (j=0;j<5;j++)
     {if (*pmax<*(p+5*i+j)) pmax=p+5*i+j;
      if (*pmin>*(p+5*i+j)) pmin=p+5*i+j;
     }
  temp=*(p+12);              //将最大值与中心元素互换
  *(p+12)=*pmax;
  *pmax=temp;
 
  temp=*p;                   //将最小值与左上角元素互换
  *p=*pmin;
  *pmin=temp;
 
        
                         //将a[0][1]的地址赋给pmin,从该位置开始找最小的元素
  for (i=0;i<5;i++)         //找第二最小值的地址赋给 pmin 
    for (j=0;j<5;j++)
    {if(i==0 && j==0) continue;
     if  (*pmin > *(p+5*i+j)) pmin=p+5*i+j;
    }
  temp=*pmin;               //将第二最小值与右上角元素互换 
  *pmin=*(p+4);
  *(p+4)=temp;
 
  for (i=0;i<5;i++)        //找第三最小值的地址赋给pmin 
    for (j=0;j<5;j++)
    {if((i==0  && j==0) ||(i==0  && j==4)) continue;
     if(*pmin>*(p+5*i+j)) pmin=p+5*i+j;
    }
  temp=*pmin;              // 将第三最小值与左下角元素互换
  *pmin=*(p+20);
  *(p+20)=temp;
 
 
  for (i=0;i<5;i++)       // 找第四最小值的地址赋给pmin 
     for (j=0;j<5;j++)
     {if ((i==0  && j==0) ||(i==0  && j==4)||(i==4  && j==0)) continue;
      if (*pmin>*(p+5*i+j)) pmin=p+5*i+j;
     }
  temp=*pmin;             //将第四最小值与右下角元素互换
  *pmin=*(p+24);
  *(p+24)=temp;
 }