根据这个post,我们可以通过以下代码获得数字的所有除数。
for (int i = 1; i <= num; ++i){
if (num % i == 0)
cout << i << endl;
}
例如,数字24
的除数为1 2 3 4 6 8 12 24
。
搜索了一些相关帖子后,我找不到任何好的解决方案。有没有有效的方法来实现这一目标?
我的解决方案:
然而,它似乎不是一个好的。
答案 0 :(得分:75)
因素是配对的。 1
和24
,2
和12
,3
和8
,4
和6
。
您的算法的改进可能是迭代到num
的平方根,而不是一直到num
,然后使用num / i
计算配对因子。
答案 1 :(得分:27)
你应该检查直到num的平方根为sqrt(num)* sqrt(num)= num:
这些方面的东西:
int square_root = (int) sqrt(num) + 1;
for (int i = 1; i < square_root; i++) {
if (num % i == 0&&i*i!=num)
cout << i << num/i << endl;
if (num % i == 0&&i*i==num)
cout << i << '\n';
}
答案 2 :(得分:13)
目前在科学中已知的算法复杂度(具有多项式复杂度的算法)意义上没有有效的方法。因此,迭代直到已经建议的平方根大多和你一样好。
主要是因为这一点,目前使用的密码学的很大一部分是基于这样的假设:计算任何给定整数的素数因子分解是非常耗时的。
答案 3 :(得分:7)
这是我的代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
#define pii pair<int, int>
#define MAX 46656
#define LMT 216
#define LEN 4830
#define RNG 100032
unsigned base[MAX / 64], segment[RNG / 64], primes[LEN];
#define sq(x) ((x)*(x))
#define mset(x,v) memset(x,v,sizeof(x))
#define chkC(x,n) (x[n>>6]&(1<<((n>>1)&31)))
#define setC(x,n) (x[n>>6]|=(1<<((n>>1)&31)))
// http://zobayer.blogspot.com/2009/09/segmented-sieve.html
void sieve()
{
unsigned i, j, k;
for (i = 3; i<LMT; i += 2)
if (!chkC(base, i))
for (j = i*i, k = i << 1; j<MAX; j += k)
setC(base, j);
primes[0] = 2;
for (i = 3, j = 1; i<MAX; i += 2)
if (!chkC(base, i))
primes[j++] = i;
}
//http://www.geeksforgeeks.org/print-all-prime-factors-of-a-given-number/
vector <pii> factors;
void primeFactors(int num)
{
int expo = 0;
for (int i = 0; primes[i] <= sqrt(num); i++)
{
expo = 0;
int prime = primes[i];
while (num % prime == 0){
expo++;
num = num / prime;
}
if (expo>0)
factors.push_back(make_pair(prime, expo));
}
if ( num >= 2)
factors.push_back(make_pair(num, 1));
}
vector <int> divisors;
void setDivisors(int n, int i) {
int j, x, k;
for (j = i; j<factors.size(); j++) {
x = factors[j].first * n;
for (k = 0; k<factors[j].second; k++) {
divisors.push_back(x);
setDivisors(x, j + 1);
x *= factors[j].first;
}
}
}
int main() {
sieve();
int n, x, i;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> x;
primeFactors(x);
setDivisors(1, 0);
divisors.push_back(1);
sort(divisors.begin(), divisors.end());
cout << divisors.size() << "\n";
for (int j = 0; j < divisors.size(); j++) {
cout << divisors[j] << " ";
}
cout << "\n";
divisors.clear();
factors.clear();
}
}
第一部分,sieve()用于查找素数并将它们放在primes []数组中。点击链接查找有关该代码的更多信息(按位筛选)。
第二部分primeFactors(x)将整数(x)作为输入,找出其素因子和相应的指数,并将它们放在向量因子[]中。例如,primeFactors(12)将以这种方式填充因子[]:
factors[0].first=2, factors[0].second=2
factors[1].first=3, factors[1].second=1
为12 = 2 ^ 2 * 3 ^ 1
第三部分setDivisors()以递归方式调用自身来计算x的所有除数,使用向量因子[]并将它们放在向量除数[]中。
它可以计算任何适合int的数的除数。它也很快。
答案 4 :(得分:5)
存在很多好的解决方案来找到所有不太大数的素因子。我只想指出,一旦你拥有它们,就不需要计算来获得所有因素。
如果N = p_1^{a}*p_{2}^{b}*p_{3}^{c}.....
然后因子的数量明显(a+1)(b+1)(c+1)....
,因为每个因素都可以零直到 a 次。
e.g。 12 = 2^2*3^1
因此它有3*2 = 6
个因素。 1,2,3,4,6,12
==
我原本以为你只想要不同因素的数量。但同样的逻辑适用。您只需迭代与指数的可能组合相对应的数字集。
所以上面的例子:
00
01
10
11
20
21
为您提供6
因素。
答案 5 :(得分:1)
如果您希望按排序顺序打印所有除数
int i;
for(i=1;i*i<n;i++){ /*print all the divisors from 1(inclusive) to
if(n%i==0){ √n (exclusive) */
cout<<i<<" ";
}
}
for( ;i>=1;i--){ /*print all the divisors from √n(inclusive) to
if(n%i==0){ n (inclusive)*/
cout<<(n/i)<<" ";
}
}
如果除数可以按任意顺序打印
for(int j=1;j*j<=n;j++){
if(n%j==0){
cout<<j<<" ";
if(j!=(n/j))
cout<<(n/j)<<" ";
}
}
两种方法的复杂度都是 O(√n)
答案 6 :(得分:0)
//Try this,it can find divisors of verrrrrrrrrry big numbers (pretty efficiently :-))
#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<conio.h>
using namespace std;
vector<double> D;
void divs(double N);
double mod(double &n1, double &n2);
void push(double N);
void show();
int main()
{
double N;
cout << "\n Enter number: "; cin >> N;
divs(N); // find and push divisors to D
cout << "\n Divisors of "<<N<<": "; show(); // show contents of D (all divisors of N)
_getch(); // used visual studio, if it isn't supported replace it by "getch();"
return(0);
}
void divs(double N)
{
for (double i = 1; i <= sqrt(N); ++i)
{
if (!mod(N, i)) { push(i); if(i*i!=N) push(N / i); }
}
}
double mod(double &n1, double &n2)
{
return(((n1/n2)-floor(n1/n2))*n2);
}
void push(double N)
{
double s = 1, e = D.size(), m = floor((s + e) / 2);
while (s <= e)
{
if (N==D[m-1]) { return; }
else if (N > D[m-1]) { s = m + 1; }
else { e = m - 1; }
m = floor((s + e) / 2);
}
D.insert(D.begin() + m, N);
}
void show()
{
for (double i = 0; i < D.size(); ++i) cout << D[i] << " ";
}
答案 7 :(得分:0)
int result_num;
bool flag;
cout << "Number Divisors\n";
for (int number = 1; number <= 35; number++)
{
flag = false;
cout << setw(3) << number << setw(14);
for (int i = 1; i <= number; i++)
{
result_num = number % i;
if (result_num == 0 && flag == true)
{
cout << "," << i;
}
if (result_num == 0 && flag == false)
{
cout << i;
}
flag = true;
}
cout << endl;
}
cout << "Press enter to continue.....";
cin.ignore();
return 0;
}
答案 8 :(得分:0)
这是this方法的Java实现:
public static int countAllFactors(int num)
{
TreeSet<Integer> tree_set = new TreeSet<Integer>();
for (int i = 1; i * i <= num; i+=1)
{
if (num % i == 0)
{
tree_set.add(i);
tree_set.add(num / i);
}
}
System.out.print(tree_set);
return tree_set.size();
}
答案 9 :(得分:0)
for (int i = 1; i*i <= num; ++i)
{
if (num % i == 0)
cout << i << endl;
if (num/i!=i)
cout << num/i << endl;
}
答案 10 :(得分:0)
//DIVISORS IN TIME COMPLEXITY sqrt(n)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
ll int n;
cin >> n;
for(ll i = 2; i <= sqrt(n); i++)
{
if (n%i==0)
{
if (n/i!=i)
cout << i << endl << n/i<< endl;
else
cout << i << endl;
}
}
}
答案 11 :(得分:0)
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define MOD 1000000007
#define fo(i,k,n) for(int i=k;i<=n;++i)
#define endl '\n'
ll etf[1000001];
ll spf[1000001];
void sieve(){
ll i,j;
for(i=0;i<=1000000;i++) {etf[i]=i;spf[i]=i;}
for(i=2;i<=1000000;i++){
if(etf[i]==i){
for(j=i;j<=1000000;j+=i){
etf[j]/=i;
etf[j]*=(i-1);
if(spf[j]==j)spf[j]=i;
}
}
}
}
void primefacto(ll n,vector<pair<ll,ll>>& vec){
ll lastprime = 1,k=0;
while(n>1){
if(lastprime!=spf[n])vec.push_back(make_pair(spf[n],0));
vec[vec.size()-1].second++;
lastprime=spf[n];
n/=spf[n];
}
}
void divisors(vector<pair<ll,ll>>& vec,ll idx,vector<ll>& divs,ll num){
if(idx==vec.size()){
divs.push_back(num);
return;
}
for(ll i=0;i<=vec[idx].second;i++){
divisors(vec,idx+1,divs,num*pow(vec[idx].first,i));
}
}
void solve(){
ll n;
cin>>n;
vector<pair<ll,ll>> vec;
primefacto(n,vec);
vector<ll> divs;
divisors(vec,0,divs,1);
for(auto it=divs.begin();it!=divs.end();it++){
cout<<*it<<endl;
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
sieve();
ll t;cin>>t;
while(t--) solve();
return 0;
}
答案 12 :(得分:0)
我们可以使用改进的筛法来获取 [1, N-1] 范围内所有数字的所有因子。
month
时间复杂度是O(N * log(N))作为谐波级数的和1 + 1/2 + 1/3 + ... + 1/N< /em> 可以近似为 log(N)。
关于时间复杂度的更多信息:https://math.stackexchange.com/a/3367064
PS:通常在编程问题中,任务将包括多个查询,其中每个查询代表不同的数字,因此一次预先计算范围内所有数字的除数将是有益的,因为查找需要 O(1) 时间案例。
答案 13 :(得分:-2)
for( int i = 1; i * i <= num; i++ )
{
/* upto sqrt is because every divisor after sqrt
is also found when the number is divided by i.
EXAMPLE like if number is 90 when it is divided by 5
then you can also see that 90/5 = 18
where 18 also divides the number.
But when number is a perfect square
then num / i == i therefore only i is the factor
*/