当且仅当没有整数
时,两个整数a和b是相对素数x> 1,y> 0,z> 0使得a = xy且b = xz。
我编写的程序确定了少于n的正整数对n的相对质数,但我的程序工作太慢,因为有时数字太大了。你能修好我的课程吗?
我的程序应该适用于n <= 1000000000
这是我的代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
long int n;
int cntr = 0, cntr2 = 0;
cin >> n;
if (!n) return 0;
vector <int> num;
for (int i = 2; i < n; i++)
{
if (n % i != 0)
{
if (num.size()>0)
{
for (int j = 0; j < num.size(); j++)
{
if (i % num[j] != 0)
cntr2++;
}
if (cntr2 == num.size())
cntr++;
cntr2 = 0;
}
else
cntr++;
}
else
num.push_back(i);
}
cout << cntr + 1 << endl;
}
答案 0 :(得分:3)
您可以采取许多措施使此任务更快。你的方法是O(N ^ 2),这让我觉得很差。
简单快速版本的第一次传递是将您的rel-prime测试更改为使用GCD。
for (int i = 2; i < n; i++)
{
if (GCD(i,n)==1) cntr++
}
cout << cntr + 1 << endl;
使用标准的欧拉风格GCD算法,您可以轻松地在网上找到,这将比您正在做的更好。
从这里尝试迭代GCD功能:GCD function in c++ sans cmath library
如果这不足以满足您的目的(可能不是这样),那么我建议您在网上搜索几种更快的方法之一。但是,搜索知道您正在寻找Euler Totient函数可能会有所帮助:http://en.wikipedia.org/wiki/Euler%27s_totient_function
答案 1 :(得分:1)
你需要做两件事:
关于第1点 - 你可以做很多事情。首先 - 如果n是偶数,则检查偶数是没有意义的 - 所以你可以将“要测试的数字”递增2.如果n可以被3整除,你可以跳过每三个数字。这很容易实现,并会为一些数字加快代码速度。 Richard Plunkett概述的方法对第2点有所帮助。我认为有更快的算法;我会考虑一下。
答案 2 :(得分:-1)
为了使它适用于更大的n值,用long int替换所有int,如果你使用的是c ++ 11,你可以使用long long int,如果仍然不够的话。为了让它运行得更快,你可以在外部for循环添加
之前/*reserve Some value that is close to the outcome*/
num.reserve(n/2);
这会有所帮助,但不会很多。