最近在重温c++,忽然想到重做考试时没有做出来的考试题。于是选择了这样一道题来练手:
输入五个整数,判断其中有几组互质对。
首先,互质是什么概念?
互质,也就是两个整数的最大公因数为1.例如,7与5互质,4和6不互质。
在处理这一问题时,欧几里得提出了以下算法:
欲求两个数的最大公因数,其核心要务在于取模运算。
首先,先求出两个数取模的结果,如果余数为0,那就说明一个数是另一个数的整数倍,那么,两个数中较小的那个就是两个数的最大公因数。
如果余数不为0,那就把其中一个数换成余数,再对新的数对做取模运算,直到出现余数为0的情况.
不妨先用这个算法做一组数试验一下:在此选取72与372:
372%72=12;
将372用12替换:
72%12=0;
此时,12就是372和72的最大公因数。
因此,只要将这一套算法包装成函数,就可以实现对两个数最大公因数的判断了。
int gcd(int a, int b)
{
if (a % b == 0) return b;//若余数为0则小者为所求
else return gcd(b, a % b);//若余数不为0则用余数替代小者
}
易见,这里使用了递归(recursion)的技巧。在函数体内重复运用函数本身,使其自动做相同的工作。
之后,回到欲完成的问题上来,将此函数加以运用,以创造出针对问题而生的函数来:
void Prime(int arr[5]) {
int count = 0;
for (int i = 0; i < 5; i++) {
for (int j = i + 1; j < 5; j++) {
if (gcd(arr[i], arr[j]) == 1) count++;//若最大公因数为1,就让计数器+1
}
}
cout << count;
}
可以将数组大小处理成可调的,为了针对问题所以固定为5.
count变量记录了5个数对中的互质数对数量。
小学数学告诉我们,5元数组做两两判断,最后会有十次判断结果。所以,先固定一个i作为两个预判断数据内的一个固定者,再从其后面的那个数开始循环判断。这样,就最小限度地将10组判断完成而不浪费算力。
最后,输出计数器的值,即是总共的互质对数量。
用一个例子做演示:
#include<iostream>
using namespace std;
int gcd(int a, int b)
{
if (a % b == 0) return b;
else return gcd(b, a % b);
}
void Prime(int arr[5]) {
int count = 0;
for (int i = 0; i < 5; i++) {
for (int j = i + 1; j < 5; j++) {
if (gcd(arr[i], arr[j]) == 1) count++;
}
}
cout << count;
}
int main() {
int arr[5] = {114,514,19,198,10};
Prime(arr);
}
结果为3.这也符合我们的预期:只有{514,19},{19,198},{19,10}三对互质数。