Factorization of numbers [duplicate] - c++

This question already has an answer here:
Is there a way to factorize large numbers in c++
(1 answer)
Closed 10 months ago.
I'm trying to write a function that has one integer parameter (let's call it 𝑛), which returns as a result a vector consisting of all prime factors of the number 𝑛, where each factor appears as many times how many times it appears in the factorization of numbers into prime factors.
#include <iostream>
#include <vector>
#include <cmath>
bool is_prime(int n)
{
if (n <= 1)
return false;
for (int i = 2; i < sqrt(n); i++)
if (n % i == 0)
return false;
return true;
}
std::vector<int> PrimeFactors(int n)
{
std::vector<int> a, b, temp;
for (int i = 1; i < n; i++)
if (is_prime(i))
temp.push_back(i);
for (int i = 0; i < temp.size(); i++)
for (int j = 0; j < temp.size(); j++)
for (int k = 0; k < temp.size(); k++)
{
if (temp[i] * temp[j] == n)
{
b.push_back(temp[i]);
b.push_back(temp[j]);
return b;
}
if (temp[i] * temp[j] * temp[k] == n)
{
b.push_back(temp[i]);
b.push_back(temp[j]);
b.push_back(temp[k]);
return b;
}
}
}
int main()
{
int n;
std::cin >> n;
std::cin.ignore(1000, '\n');
for (int i : PrimeFactors(n))
std::cout << i << " ";
return 0;
}
Storing number exactly the time it appears in factorization makes this tough a little bit. Could you give an idea for algorithm?

Use the % operator to find numbers that divide n evenly. Each time you find a factor, divide n by that factor as long as it continues to divide evenly.
std::vector<int> PrimeFactors(int n) {
std::vector<int> r;
for (int i = 2; i * i <= n; i += 1 + (i > 2)) {
while ((n % i) == 0) {
r.push_back(i);
n /= i;
}
}
if (n != 1)
r.push_back(n);
return r;
}

Related

Why is this code not printing the prime factors of num?

I wrote this code for obtaining the prime factors of a number taken as an input from the user.
#include<bits/stdc++.h>
using namespace std;
void prime_Factors(int);
bool isPrime(int);
int main()
{
int num;
cout << "Enter the number to find it's prime factors: ";
cin >> num;
prime_Factors(num);
}
void prime_Factors(int n1)
{
for(int i = 2; i<n1; i++)
{
if(isPrime(i))
{
int x = i;
while(n1%x==0)
{
cout << i << " ";
x *= i;
}
}
}
}
bool isPrime(int n0)
{
if(n0==1)
return false;
for(int i = 0; i*i <= n0; i++)
{
if(n0%i==0)
return false;
}
return true;
}
The prime_Factors() function call in main() function is not printing the prime factors. Pls help!!
The ranges of the loops are wrong.
Firstly, the loop for(int i = 2; i<n1; i++) will fail to find prime factors of prime numbers (the numbers theirself). It should be for(int i = 2; i<=n1; i++).
Secondly, the loop for(int i = 0; i*i <= n0; i++) will result in division-by-zero. It should be for(int i = 2; i*i <= n0; i++).
Thinking about using the Sieve of Eratosthenes made me try it out:
#include <iostream>
#include <cstdint>
#include <vector>
void prime_factors(uint32_t n) {
while(n % 2 == 0) {
std::cout << "2 ";
n /= 2;
}
std::vector<bool> sieve(n / 2, true);
for (uint32_t i = 3; i * i <= n; i += 2) {
if (sieve.at(i / 2 - 1)) {
uint32_t j = i * i;
for (; j < n; j += 2 * i) {
sieve.at(j / 2 - 1) = false;
}
if (j == n) {
do {
std::cout << i << " ";
n /= i;
} while (!sieve.at(n / 2 - 1));
}
}
}
if (n > 1) std::cout << n;
std::cout << "\n";
}
int main() {
prime_factors(123456789);
}
https://godbolt.org/z/8doWbYrs6

C++ - Count all possible scalene triangle with length of each side smaller than N

With 3 <= N <= 100000, I tried the following O(n^2) algo but I want it to be efficient, O(n)
please help with homework :D
typedef long long ll;
int n;
int solve(int n)
{
int ans=0;
for(int i = n; i >= 3; i--)
{
int j = 1, k = i -1;
while(j < k)
{
if(j + k > i)
{
ans += k - j;
k--;
}
else
j++;
}
}
return ans;
}

list of prime numbers between 1 and 100

I want to find the list of prime numbers, I try this code but it doesn't show me anything:
#include <iostream>
using namespace std;
int main()
{
int n, i;
std::cout << "Liste des nombres premiers : " << std::endl;
for (n = 1; n < 100; n++) {
for (i = 2; i < n; i++) {
if (n % i == 0)
std::cout << n << " ";
}
}
return 0;
}
I don't like your code at all. Try to do this: create a function that tells you if a number is prime, and then go with a for loop through all numbers from 1 to 100, and check with the function if they are prime.
Here is an easy to remember function (for natural numbers):
bool isPrime(int n)
{
if (n <= 1)
return 0;
if (n == 2)
return 1;
if (n%2 == 0)
return 0;
for (int i=3; i*i <= n; i+=2)
if (n%i == 0)
return 0;
return 1;
}
This function returns 1 if the number is prime, and returns 0 if it isn't.
The idea is this:
If n is 0 or 1, it is not prime.
If n is 2, it is prime.
If n is a multiple of 2, but it isn't 2, it is not prime.
Then, you have to check if n has any divisors until you get to square root of n (i * i <= n)
To correct program errors:
Initialize the value of n as 2.
And print when i is equal to n not when n % i is 0. It should be rather n % i == 0 then break.
Change i < n to i <= n.
Try the first approach (used sqrt()):
#include <iostream>
#include <cmath>
int main(void)
{
for (int i = 2; i < 100; i++) {
if (i == 2 || i == 3) { // if number is 2 or 3, then prints it
std::cout << i << ' ';
}
for (int j = 2; j * j <= i; j++)
{
if (i % j == 0) break;
else if (j + 1 > sqrt(i)) std::cout << i << ' ';
}
}
return 0;
}
Alternative approach:
#include <iostream>
int main(void)
{
for (int n = 2; n < 100; n++)
for (int i = 2; i <= n; i++)
if (i == n) std::cout << i << ' ';
else if (n % i == 0) break;
return 0;
}

prime seive algorithm giving a runtime error

I am trying to implement the Sieve of Eratosthenes algorithm but it giving a runtime error.
didn't get any output though. after providing the input,
#include<iostream>
using namespace std;
//Sieve Approach - Generate an array containing prime Numbers
void prime_sieve(int *p) {
//first mark all odd number's prime
for (int i = 3; i <= 10000; i += 2) {
p[i] = 1;
}
// Sieve
for (long long int i = 3; i <= 10000; i += 2) {
//if the current number is not marked (it is prime)
if (p[i] == 1) {
//mark all the multiples of i as not prime
for (long long int j = i * i; j <= 10000; j = j + i ) {
p[j] = 0;
}
}
}
//special case
p[2] = 1;
p[1] = p[0] = 0;
}
int main() {
int n;
cin >> n;
int p[10000] = {0};
prime_sieve(p);
//lets print primes upto range n
for (int i = 0; i <= n; i++) {
if (p[i] == 1) {
cout << i << " ";
}
}
return 0;
}
compiler didn't throwing any error also it is not providing the output also
program freezes for some seconds and then terminates
As mentioned in the comments, you are going out of bound.
There is also some confusion about the meaning of p[].
In addition, you are not using the value of n in the function, which leads to unnecessary calculations.
Here is a tested programme (up to n = 10000):
#include <iostream>
#include <vector>
#include <cmath>
//Sieve Approach - Generate an array containing prime Numbers less than n
void prime_sieve(std::vector<int> &p, long long int n) {
//first mark all odd number's prime
for (long long int i = 4; i <= n; i += 2) {
p[i] = 0;
}
// Sieve
for (long long int i = 3; i <= sqrt(n); i += 2) {
//if the current number is not marked (it is prime)
if (p[i] == 1) {
//mark all the multiples of i as not prime
for (long long int j = i * i; j <= n; j = j + i ) {
p[j] = 0;
}
}
}
//special cases
p[1] = p[0] = 0;
}
int main() {
long long int n;
std::cout << "Enter n: ";
std::cin >> n;
std::vector<int> p (n+1, 1);
prime_sieve(p, n);
//lets print primes upto range n
for (long long int i = 0; i <= n; i++) {
if (p[i] == 1) {
std::cout << i << " ";
}
}
return 0;
}

Function to find the smallest prime x and the biggest m = power_of(x) such that n % m = 0 and n % x = 0?

Given m integer from 1 to m, for each 1 <=i <= m find the smallest prime x that i % x = 0 and the biggest number y which is a power of x such that i % y = 0
My main approach is :
I use Eratos agorithm to find x for every single m like this :
I use set for more convenient track
#include<bits/stdc++.h>
using namespace std;
set<int> s;
void Eratos() {
while(!s.empty()) {
int prime = *s.begin();
s.erase(prime);
X[prime] = prime;
for(int j = prime * 2; j <= L ; j++) {
if(s.count(j)) {
int P = j / prime;
if( P % prime == 0) Y[j] = Y[P]*prime;
else Y[j] = prime;
}
}
}
signed main() {
for(int i = 2; i<= m; i++) s.insert(i);
Eratos();
for(int i = 1; i <= m; i++) cout << X[m] << " " << Y[m] ;
}
with X[m] is the number x corresponding to m and same as Y[m]
But it seems not really quick and optimal solution. And the memory request for this is so big and when m is 1000000. I get MLE. So is there an function that can help to solve this problem please. Thank you so much.
Instead of simply marking a number prime/not-prime in the original Sieve of Eratosthenes, save the corresponding smallest prime factor which divides that number.
Once that's done, the biggest power of the smallest prime of a number would mean to simply check how many times that smallest prime appears in the prime factorization of that number which is what the nested for loop does in the following code:
#include <iostream>
#include <vector>
using namespace std;
void SoE(vector<int>& sieve)
{
for (int i = 2; i < sieve.size(); i += 2)
sieve[i] = 2;
for (int i = 3; i < sieve.size(); i += 2)
if (sieve[i] == 0)
for (int j = i; j < sieve.size(); j += i)
if(sieve[j] == 0)
sieve[j] = i;
}
int main()
{
int m;
cin >> m;
vector<int> sieve(m + 1, 0);
SoE(sieve);
for (int i = 2; i < sieve.size(); ++i)
{
int x, y;
x = y = sieve[i];
for (int j = i; sieve[j / x] == x; j /= x)
y *= x;
cout << x << ' ' << y << endl;
}
}
I didn't get what you're trying to do but I understand that you're trying to use Sieve of Eratosthenes to find prime numbers. Well, what you probably need is a bitset, it's like a boolean array but uses bits instead of bytes which means it uses less memory. Here's what I did:
#include <iostream>
#include <vector>
#include <bits/stdc++.h>
#include <cmath>
using namespace std;
vector<int> primes;
int main()
{
const int m = 1e7;
bitset<m> bs;
int limit = (int) sqrt (m);
for (int i = 2; i < limit; i++) {
if (!bs[i]) {
for (int j = i * i; j < m; j += i)
bs[j] = 1;
}
}
for (int i = 2; i < m; i++) {
if (!bs[i]) {
primes.push_back (i);
}
}
return 0;
}