相同但又不同

来源:互联网 发布:解压软件 os x 编辑:程序博客网 时间:2024/04/29 18:21
写这篇文章的冲动,源于刚才做的一道百度笔试题,因为我以前一直都没有注意到这个现象,想不到当深入去研究的时候,居然还有所发现。作为读者的你,可能已经跃跃欲试,“什么题啊,快给出来”,但是,为了不转移我们的注意力。我先来问一个问题:如何在一个函数中,分配一个其大小由函数参数决定的二维数组?
例如,要分配一个二维数组A[m][n],而mn为函数的传入参数。该怎么实现?我的第一个错误反应,就是:
                            Int **p = new A[m][n]
而事实上,事情并不是那么简单,正确的方法应该是这样的:   
/****************************************
这个函数告诉你,怎样去动态分配一个下标为
传入参数的二维数组,
举一反三,你也应该从中学会,动态分配n维数
组的方法。
****************************************
*/
int DynArray(int m, int n)
{
    
int **= new int*[m]; //整形指针数组

    
for (int i=0; i<m; i++)
    {
        p[i] 
= new int[n];
    }


    
//........................
    
//........................


    
//注意,释放内存,不再像一维那么简单
    for (int i=0; i<m; i++)
    {
        delete[] p[i];    
//p[i]指向int[n]
    }
    delete[] p;
    
    
return 0;
}
上面这种情况,离我想讨论的问题,又显得太远了一点,现在我把问题弄简单些,如果要分配一个二维数组A[m][2]m为函数的传入参数,那么怎样实现:
简单而又正确的方法是: int  (*p)[2] = new int[m][2];
于是,问题来了, new int[m][2]返回的是什么东西?有人可能会立即回答“指向int[m][2]的物理地址”。对,这个回答,绝对是正确的。但是,如果仅仅看到这一点,我这篇文章,就没有写的必要了。为了使这个问题,显得更浅显一些,我再举一个例子,假设已经作了这个的定义:
                            Int A[3][4] =
{
                            {1, 2, 3, 4},
                            {5, 6, 7, 8},
                            {9, 10, 11, 12}
};
那么,&A[0][0]&A[0]A[0]的值是多少?现在怎样?你的结论是什么?他们的值是一样的!他们值都是同一个物理地址。
但是,关键点在于,他们确实是相同的吗?&A[0][0]A[0]是完全等同的,但&A[0]代表什么?
                            Int *ptrA= &A[0][0]; int *p = A[0];
                            Int (*ptrB)[3] = &A[0];
上面是正确的赋值,你已经注意到了,&A[0]代表着,指向int[3]数组的物理地址,而A[0]&A[0][0],则代表着指向int变量的物理地址,虽然,&A[0]A[0]的值一样,但在编译器的眼里,它们的逻辑含义是不一样的!正是有了这些不一样,虽然给我们理解上带来一些困难,但也给我们编程带来了方便,例如,我们可以这样去使用ptrBptrB[2][1],但ptrA是不能这样使用的。
 
下面给出百度的这道题,并给出我的解法,其实刚才做了四道百度笔试题,感觉有些题在考场上,还是会让人冒点汗的。
题目: 

写一段程序,找出数组中第k大小的数,输出数所在的位置。例如{24347}中,第一大的数是7,位置在4。第二大、第三大的数都是4,位置在13随便输出哪一个均可。函数接口为:

int find_orderk(const int* narry,const int n,const int k)

本人解法:

int find_orderk(const int* narry,const int n,const int k)
{
    
/*
***********************************
    采用空间换时间策略,
    用A[i][0]记录narry的值,
    用A[i][1]记录该值在narry中的位置。
    ************************************
*/

    
int (*A)[2= new int[n][2];  
    
for (int i=0; i<n; ++
i)
    {
        A[i][
0=
 narry[i];
        A[i][
1=
 i;
    }

    
//
对A数组进行从小到大排序
    
//
可以考虑快速排序,但考虑到笔试的时间有限,
    
//而且只在一个函数内实现,用插入排序吧

    for (int i=1; i<n; ++i)
        
for (int j=i; (j>0 && A[j]>A[j-1]); --
j)
        {
            
int val = A[j][0
];
            
int pos = A[j][1
];

            
//swap A[j] and A[j-1]

            A[j][0= A[j-1][0];
            A[j][
1= A[j-1][1
];
            A[j
-1][0=
 val;
            A[j
-1][1=
 pos;
        }

    
//第k大的值的位置

    int pos = A[k-1][1];

    delete[] A;
    
return
 pos;

}
原创粉丝点击