Prime factorisation for large amount of numbers - c++

So I have to make prime factorisation for up to 10^6 different numbers from 1 to 8*10^6. I've done this with Sieve of Erathostenes, but it seems that it's too slow. I have no idea how can I deal with it. Here's my code:
int factors[8000001] = { };
void sieve(int* tab, int max)
{
for (int i = 2; i * i < max; ++i)
{
if(tab[i] == 0)
{
for (int j = i; j * i < max; ++j)
{
if (tab[i*j] > i || tab[i*j] == 0)
tab[i*j] = i;
}
}
}
}
in main():
cin >> number;
while (number > 1)
{
if (factors[number] == 0)
{
cout << number;
number = 1;
}
else if (number != factors[number])
cout << factors[number] << "*";
else
cout << factors[number];
number /= factors[number];
}
cout << "\n";
For smaller tests it works perfectly, but not for large ones. What can I improve? (I'm also using ios_base::sync_with_stdio(0); line)

Related

How to compare elements in an array for equality?

I've come across this problem where I have to transform a number from the decimal system to the binary and compare if the numbers are equal
Example:
7 is becoming 111
The output is false
and where 5 is 101
The output is true
I've figured out how to transform the numbers with an array
But have no idea how to compare them
#include<iostream>
using namespace std;
int main()
{
int num;
cin >> num;
int arr[8] = {};
if ((num >= 0) && (num <= 255))
{
while (num != 0)
{
for (int i = 0; i < 8; i++)
{
if (num % 2 == 0)
arr[i] = 0;
else
{
arr[i] = 1;
}
num = num / 2;
}
}
for (int i = 7; i >= 0; i--)
cout << arr[i];
cout << endl;
}
else
{
cout << "error" << endl;
return 1;
}
system("pause");
return 0;
}

How to display output in rows of five numbers?

I'm new to programming and I have to display all the prime numbers that are the product of this code in rows of five. After too many hours of trying to find something online, this is what I came up with. This way, not even the prime numbers are being displayed in the end; only 1s all the way. I'd be happy to know what I did wrong or what I could change.
#include <iomanip>
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
int main() {
int n { 0 };
cout << "Please enter an initial value n<2000 in order for the calculation to begin: " << endl;
cin >> n;
vector<bool> cygnus(n + 1);
for (int m = 0; m <= n; m++) {
cygnus[m]=true;
}
for (int j = 2; j < n; j++) {
if (cygnus[j] == true) {
for (int i = j + 1; i <= n; i++) {
if (i % j == 0) {
cygnus[i] = false;
}
}
}
}
int s = 0;
for (auto value : cygnus) {
if (value == true && s > 0) {
for (int counter = s; counter++; ) {
if (counter % 5 == 0) {
cout << setw(3) << s << " \n ";
}
if (counter % 5 != 0) {
cout << setw(3) << s << " ";
}
}
}
s++;
}
cout << endl;
return 0;
}
You are seriously over-complicating your output logic. Just have a counter variable declared (and initialized to zero) outside the for loop that does the output and then, every time you print a number, increment it. When that reaches the value of 5, print a newline and reset it to zero.
A couple of other points:
The STL containers (like std::vector) use the size_t type (not int) for their sizes and indexes. In the code below, I have changed all your int variables to this type; fortunately, that won't affect your algorithm.
Note that 1 is not a prime number.
Here's a re-worked version of your code:
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
int main()
{
size_t n{ 0 };
cout << "Please enter an initial value n<2000 in order for the calculation to begin: " << endl;
cin >> n;
vector<bool>cygnus(n + 1);
for (size_t m = 0; m <= n; m++) {
cygnus[m] = true;
}
for (size_t j = 2; j < n; j++) {
if (cygnus[j] == true) {
for (size_t i = j + 1; i <= n; i++) {
if (i % j == 0) {
cygnus[i] = false;
}
}
}
}
size_t s = 0;
size_t counter = 0;
for (auto value : cygnus) {
if (value == true && s > 1) { // Note that 1 is NOT a prime number
cout << setw(3) << s << " ";
if (++counter == 5) {
cout << "\n ";
counter = 0;
}
}
s++;
}
if (counter != 0) cout << "\n "; // Add newline for any partial last line.
cout << endl;
return 0;
}

Repeating digits in number C++

The task is to write a function which takes a number and finds the digit that is repeated most times in that number. It should print the found digit and the times it is repeated.
I had a problem with the case when two digits were repeating a same number of times.
For example with given number 788995 it should return 8 -> 2 \\ 9 -> 2
How can I print that?
Here is the function:
void maxDigitInNumber (long long n)
{
if (n < MIN || n > MAX)
{
cout << -1;
return;
}
n = abs(n);
int numOfDigits = (int)log10(n)+1;
int digits[100];
int helper[100] = {0};
int counter = 0;
int maxSize = 0;
int number = 0;
for (int i = 0; i <= numOfDigits; i++)
{
digits[i] = n%10;
n /= 10;
}
for(int i = 0; i < numOfDigits; i++)
{
if(helper[i] == 0)
{
counter = 0;
for(int j = i; j < numOfDigits; j++)
{
if(digits[j] == digits[i])
{
counter++;
helper[j] = 1;
}
if(counter > maxSize)
{
maxSize = counter;
number = digits[i];
}
}
}
}
if (number == 0)
{
for (int i = 0; i < numOfDigits; i++)
{
cout << digits[i] << "->" << maxSize << endl;
}
}
else
{
cout << number << "->" << maxSize << endl;
}
}
You should store the count for each digit before picking the max. After that you can pick the max value among all counts, and print all entries matching that max:
int count[10] = {0};
do {
count[n%10]++;
n /= 10;
} while (n != 0);
int maxCount = 0;
for (int i = 0 ; i != 10 ; i++) {
maxCount = max(maxCount, count[i]);
}
bool first = true;
for (int i = 0 ; i != 10 ; i++) {
if (count[i] == maxCount) {
if (!first) {
cout << " \\\\ ";
} else {
first = false;
}
cout << i << "->" << maxCount;
}
}
There are only 10 digits, so an histogram of the digits in the number takes up only 10 words.
// ....
int hist[10] = {}; // Full tally available for further analysis
int max_count = 0; // result.
int max_digit = -1;
for (int i = 0; i <= numOfDigits; i++)
{
int digit = n % 10;
if (++hist[digit] > max_count)
{
max_count = hist[digit]; // could also be ++max_count ;)
max_digit = digit;
}
n /= 10;
}
Here are some algorithms you can use:
// prints digits with a certain score:
void print_if_score_is(const int hist[10], int score)
{
for (int i = 0; i < 10; ++i)
if (hist[i] == score)
std::cout << " digit: " << i << ", score: " << score << "\n";
}
int get_next_best_score(const int hist[10], int score)
{
int new_max = -1;
for (int i = 0; i < 10; ++i)
if (hist[i] > new_max && hist[i] < score)
new_max = i;
return new_max;
}
Usage:
// ....
std::cout << "Digit most frequently found: \n";
print_if_score_is(hist, max_count);
std:: cout << "next in list: \n";
int next_best = get_next_best_score(hist, max_count);
print_if_score_is(hist, next_best);
//...
Structure your program like this:
One function accepts the number to be analyzed and returns a std::multiset. multiset allows multiple entries for the same key. So for the number 788995 you would end up with a multiset { 1: [5, 7], 2: [8, 9] }
Another function analyzes the multiset and returns the numbers for the highest-ranking key in the set.

Consecutive comparisons using if statements inside a while loop

I am supposed to compare two consecutive integers, i and j, that are given from a list of integers separated by whitespace which end with a 0 and, if i is less than j, I compare j to max and i to min. If the opposite, I compare j to min and i to max. The output is supposed to be each comparison I do with max, min, i, and j. Additionally, the list must be greater than 2 integers. If it is less then I am supposed to output 0. However the program does not seem to execute the if statements correctly.
int i = 1;
int j;
int max = 0;
int min = 0;
int counter = 0;
while (i != 0) {
cin >> i;
if (counter == 0) {
cout << 0 << endl;
i = min;
j = max;
} else if (counter == 1) {
cout << 0 << endl;
i = min;
j = max;
} else {
if (i < j) {
if (j > max) {
cout << j << " " << max << endl;
max = j;
}
if (i < min) {
cout << i << " " << min << endl;
min = i;
}
}
else {
if (j < min) {
cout << j << " " << min << endl;
min = j;
}
if (i > max) {
cout << i << " " << max << endl;
max = i;
}
}
}
j = i;
counter += 1;
}
}
You are overwriting i (and j) in the first iteration of the while loop (counter == 0) with min which is 0. As your while says while (i != 0) you immediately exit, after one while iteration. The ifs should be fine.
Input and counter logic can be improved by:
#include <iostream>
using namespace std;
int main(){
int i;
int j;
int max = 0;
int min = 0;
int counter = 0;
bool flag = true; // fix the input logic
while (flag){
cin >>i;
cin>>j;
if(i==0 || j==0){
flag = false;
break;
}else{
counter ++;
if(counter < 2 ){
//your code
}
else if(i<j){
cout<<"i: "<<i<<" j: "<<j;
j = max;
i = min;
// your code
}
else if(i>j){
//your code
}
}
}
return 0;
}

How to count the number of numbers below N having only one or two prime factors?

There are how many numbers below n having only one or two prime factors?? Like below 100 there are 91 numbers which have only one or two prime factors excluding 9 (some of them are 60, 66, 78, 90).
I'd like to do this in C++.
#include<iostream>
using namespace std;
int main()
{
long long num, i, k, counter, b = 0, a, flag;
cout << "Enter Number" << endl;
cin >> num;
counter = 0;
for (a = 2; a <= num; a++)
{
counter = 0;
i = 2;
for (i = 2; i <= a; i++)
{
flag = 0;
k = 2;
if (a%i == 0) {
while (k <= i - 1) {
if (i%k == 0) {
flag = 1;
break;
}
k++;
}
if (flag == 0)
{
counter++;
}
}
}
if (counter <= 2)
{
b++;
}
}
cout << "Total Number Which Have One Or Two Prime Factor are :: " << b << endl;
return 0;
}