请解释此功能

Please explain this function

本文关键字:功能 解释      更新时间:2023-10-16

下面的代码用于按照的升序或降序对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是如何工作的吗?

这个程序的主要内容是函数指针的使用。bool(*pComparison)(int, int)是指向返回bool类型值并将int值作为参数2的函数的指针。您可以检查不同的输出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的余数。例如,1212%2=0

34%2=0

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

每个奇数都可以写成2m+1的形式。现在,如果我们把这个数字除以2,我们将得到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. 

几个例子可以澄清你的想法——

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

引用标准:

T二进制%运算符从第一个表达式除以第二个表达式得到余数。如果第二个操作数/或%为零,则行为未定义;否则(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)对于任何给定的偶数NN % 2总是给出0。这是因为根据定义,偶数是2的乘积。

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

正因为如此,我们可以使用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之前,则返回true(否则为false)。首先,它检查条件(nX%2)&&!(nY%2)。这种情况本质上意味着:

"检查nX是否为奇数,nY是否为偶数。"

如果它的计算结果为true,函数将返回false-首先取偶数,因此nY应放在nX之前)。

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

"检查nX是否为偶数,nY是否为奇数。"

如果计算结果为true,则函数返回true-首先取偶数,因此nX应放在nY之前。

如果这两个条件都被评估为false,则意味着它们要么都是奇数,要么都是偶数。在这种情况下,函数会使用"升序"比较来比较它们——先取较低的数字。

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