请解释这个功能

Please explain this function

下面的代码用于对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 是如何工作的吗?

运算符取模%returns其操作数相除的余数。它可以用来检查一个数是偶数还是奇数,因为如果 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
    }
}

这个程序最主要的是函数指针的使用。 bool(*pComparison)(int, int) 是一个指向 returns 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.
}

If nx is even the if we divide it by 2 it will give remainder of 0. For example, 12 12%2=0

34%2=0

9%2=1 ----> that's why this is odd.

Every odd number can be written in the form 2m+1 Now if we divide this number by 2 we will get remainder of 1 as 1st part is giving remainder 0.

Even number the explanation is same even number is represented by 2m.So when divided by 2 it will give remainder 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. 

几个例子来阐明你的想法--

检查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

引自《标准》:

Tthe binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined (74)

(74) According to work underway toward the revision of ISO C, the preferred algorithm for integer division follows the rules defined in the ISO Fortran standard, ISO/IEC 1539:1991, in which the quotient is always rounded toward zero.

示例:

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

现在,模 2 运算只能给我们两个可能的结果:0 或 1。另外:

1) 对于任何给定的偶数 NN % 2 总是给出 0。那是因为根据定义,偶数是 2 的乘积。

2) 对于任何给定的奇数 MM % 2 总是给出 1。那是因为任何偶数都可以定义为 2K + 1,其中 K 是一个 N0(自然数或零)。

由于以上原因,我们可以使用x % 2表达式作为逻辑条件,因为在C/C++中“0为假,其他均为真”。

所以:

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,如果 nX 应放在 nY 之前,则 returns 为真(否则为假)。首先,它检查条件 (nX%2)&&!(nY%2)。这个条件本质上意味着:

"Check, if nX is an odd number and nY is an even number."

如果计算结果为 true,函数 returns false - 首先取偶数,因此 nY 应该放在 nX 之前)。

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

"Check, if nX is an even number and nY is an odd number."

如果计算结果为真,函数 returns 为真 - 首先取偶数,因此 nX 应该放在 nY 之前。

如果这两个条件的计算结果均为假,则意味着它们要么都是奇数,要么都是偶数。在这种情况下,函数使用 "Ascending" 比较来比较它们 - 较小的数字将首先被采用。