请解释这个功能
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);
(如果您正确编码了选择排序功能)。
注意:基于不同的函数指针,这个通用排序例程将给出不同的输出。例程的其余部分是基本排序例程,将 min
或 max
的值交换到当前元素。
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) 对于任何给定的偶数 N
,N % 2
总是给出 0。那是因为根据定义,偶数是 2 的乘积。
2) 对于任何给定的奇数 M
,M % 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);
}
此函数接受两个参数:nX
和 nY
,如果 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" 比较来比较它们 - 较小的数字将首先被采用。
下面的代码用于对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);
(如果您正确编码了选择排序功能)。
注意:基于不同的函数指针,这个通用排序例程将给出不同的输出。例程的其余部分是基本排序例程,将 min
或 max
的值交换到当前元素。
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) 对于任何给定的偶数 N
,N % 2
总是给出 0。那是因为根据定义,偶数是 2 的乘积。
2) 对于任何给定的奇数 M
,M % 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);
}
此函数接受两个参数:nX
和 nY
,如果 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" 比较来比较它们 - 较小的数字将首先被采用。