2015-04-04 75 views
1

下面的代码被用来以升序或降序的顺序int数组排序请解释该功能

//codes borrowed from learncpp.com 
#include<iostream> 
#include<algorithm> 
using namespace std; 
void SelectionSort(int *anArray, int nSize, bool(*pComparison)(int, int)) { 
    for(int iii=0; iii<nSize; iii++) { 
     int nCurrent = iii; 
     for(int jjj=iii+1; jjj<nSize; jjj++) { 
      if(pComparison(anArray[nCurrent], anArray[jjj])) 
       nCurrent = jjj; 
      } 
     swap(anArray[nCurrent], anArray[iii]); 
    } 
} 
bool Ascending(int nX, int nY) { 
    return nY>nX; 
} 
bool Descending(int nX, int nY) { 
    return nY<nX; 
} 
bool EvensFirst(int nX, int nY) { 
    if((nX%2)&&!(nY%2)) 
     return false; 
    if(!(nX%2)&&(nY%2)) 
     return true; 
    return Ascending(nX, nY); 
} 
void PrintArray(int *pArray, int nSize) { 
    for(int kkk=0; kkk<nSize; kkk++) 
     cout << pArray[kkk] << " "; 
    cout << endl; 
} 
int main() { 
    int anArray[9] = {3, 5, 1, 8, 9, 4, 6, 2, 7}; 
    SelectionSort(anArray, 9, EvensFirst); 
    PrintArray(anArray, 9); 
    return 0; 
} 

打印结果是9 7 5 3 1 8 6 4 2而不是2 4 6 8 1 3 5 7 9

任何人都可以在这里请解释bool函数EvensFirst是如何工作的?

+1

你是否熟悉'nX%2'的作用?或者更具体地说,如果它的值为零或不为零,它在每种情况下意味着什么? – lurker 2015-04-04 01:42:40

+0

不是,我感到困惑于((nX%2)&&!(nY%2)) – 2015-04-04 01:59:59

+0

'%'是模。 “%2”是模块2(如果将数字除以2,则可以得到其余的结果)。如果'nX%2'为零,那么'nX'就是偶数。如果'nX%2'非零(1),那么'nX'是奇数。所以'(nX%2)&&! (nY%2)'如果'nX'为奇数且'nY'为偶数,则为真,因为零有一个假值,并且1具有真值。 – lurker 2015-04-04 02:01:43

回答

1

从标准报价:

里边反二元%运营收益第一个表达除以第二个表达式的余数。如果/或%的第二个操作数为零,则行为未定义;否则(a/b)* b + a%b等于a。 如果两个操作数都是非负的,那么余数是非负的;如果没有,剩余的符号是实现定义的(74)

(74)根据正在进行的修改ISO C的工作,优选的整数除法算法遵循ISO Fortran标准ISO/IEC 1539:1991,其中商总是趋于零。

实施例:

11 % 3 = 2,因为11 = 3*3 + 2

现在,操作模2可以给我们只有两个可能的结果:0或1。另外:

1)对于任何给定偶数N,N % 2将始终为0。这是因为偶数的定义乘法为2.

2)对于任何给定奇数MM % 2总会给1.这是因为任何偶数可以被定义为2K + 1,其中KN0(自然数或零)。由于上述原因,我们可以使用x % 2表达式作为逻辑条件,因为在C/C++中“0为false,其他都为真”。

所以:

if(x%2) 
{ 
    //x%2 != 0, which means x%2 = 1, which means x is an odd number 
} 
else 
{ 
    //x%2 == 0, which means x is an even number 
} 

现在,让我们回到你EvensFirst功能:

bool EvensFirst(int nX, int nY) 
{ 
    if((nX%2)&&!(nY%2)) 
     return false; 
    if(!(nX%2)&&(nY%2)) 
     return true; 
    return Ascending(nX, nY); 
} 

这个函数接受两个参数:nXnY并返回true,如果nXnY前放置(否则为false)。首先,它检查条件(nX%2)&&!(nY%2)。这种情况本质上是指:

“检查,如果nX是一个奇数,nY是一个偶数。

如果它的计算结果为true,函数返回false - 平均首先被采用,所以nY应放在nX之前)。

然后,它检查第二个条件:!(nX%2)&&(nY%2),这意味着:

“检查,如果nX是偶数和nY是奇数”。

如果它的计算结果为真,则函数返回true - 平均首先被采用,因此nX应放置在nY之前。

如果这两个条件评估为false,则意味着它们都是奇数,或者都是均等的。在这种情况下,函数使用“升序”比较来比较它们 - 将首先采用较小的数字。

1

运算符模%返回其操作数的除法的其余部分。它可以用来检查数字是偶数还是奇数,因为如果x/2的剩余部分是0这意味着x是偶数。 这意味着如果x%2=0比x是偶数,否则它是奇数。


这里的EvensFirst如何工作

bool EvensFirst(int nX, int nY) { 
    if((nX%2)&&!(nY%2)) //if nX is even and nY is odd 
     return false; //returns false 
    if(!(nX%2)&&(nY%2)) //if nX is odd and nY is even 
     return true; //returns true 
    //if they are both odd or even returns the result of ascending 
    return Ascending(nX, nY); //true if nY > nX 
} 

这里的你如何使用EvensFirst

void SelectionSort(int *anArray, int nSize, bool(*pComparison)(int, int) { 
    for(int iii=0; iii<nSize; iii++) { //for each number in the array 
     int nCurrent = iii; 
     for(int jjj=iii+1; jjj<nSize; jjj++) { //for each following elemnt 
      if(pComparison(anArray[nCurrent], anArray[jjj])) //compare the two elements 
       nCurrent = jjj; 
      } 
     swap(anArray[nCurrent], anArray[jjj]); //and switch their positions if they are in the wrong order 
    } 
} 
+0

雅,我只是现在修好了,thx提醒 – 2015-04-04 01:50:43

+0

我再次编辑。告诉我,如果你需要别的东西:) – 2015-04-04 02:07:35

3

该计划最主要的是利用funtion的指针。 bool(*pComparison)(int, int)是一个指向函数的指针,该函数返回bool类型值并将其作为参数2 int值。您可以检查不同的输出SelectionSort(anArray, 9, Ascending);SelectionSort(anArray, 9, Descending);(如果您已正确编码选择排序功能)。

注意:基于不同的函数指针,这个一般的排序例程会给出不同的输出。例程的其余部分是基本排序例程,将minmax的值替换为当前元素。

bool EvensFirst(int nX, int nY) { 
    if((nX%2)&&!(nY%2)) //if nX is odd and nY is even the 
//nY should be in first position. So to change the order return false 
     return false; 
    if(!(nX%2)&&(nY%2))//if nX is even and nY is odd the 
//nX should be in first position. So to retain the order return true 
     return true; 
    return Ascending(nX, nY);// both even or both odd return the ascending function's output. 
} 

如果nx为甚至如果我们把它由2它会给0 例如剩余部分,12 12%2 = 0

34%2 = 0

9%2 = 1 ---->这就是为什么这很奇怪。

,每一个奇数号可在形式2m+1写现在,如果我们除以2这个数字,我们将获得1个为第1部分的其余部分给余0

偶数的解释是相同的偶数表示通过2m。因此,当除以2时,将给出余数0。

if((nX%2)&&!(nY%2)) 
     return false; 
if nX is even it nX%2=0 and if nY is odd then ny%2=1 
So expressin becomes 
if(0 && 1)-->which evaluates to false and go to next condition. 

很少wxamples澄清你idea--

检查x是偶数

if(x%2==0) 
    //x is even. 

Also can be written as 
if(!x%2) 
    //x is even. 

检查,如果x是奇数

if(x%2==1) 
     // x is odd 
    Also can be written as 

    if(x%2) 
     // x is odd. 

检查x和y均为甚至

if(!x%2 && !y%2) 
    //both even 

检查,如果任一个是连

if(!x%2 || !y%2) 
    //either of them is even 
+0

@JuenKhaw .:看看任何偶数除以2得到余数为0,任何奇数给1。不是吗? nX%2相当于'nx is odd'。好像奇数会给1并进入循环。 – coderredoc 2015-04-04 02:10:50

+0

thx为你解释,这是有帮助的:D – 2015-04-04 06:32:11