Finding factors of a number. Not getting accurate results - c++

Can someone help correct my algorithm? I've tested it on a few numbers, and it doesn't output the complete factorization. For numbers with a large number of factors, it just completely fails.
int num = 20;
for(int i = 2; i <= num; i++)
{
if(num%i == 0)
{
cout << i << endl;
cout << num << endl;
num = num/i;
}
}
EDIT: The two answers provided did not work, still not getting full results.
EDIT2: Divisors VS Factors

Judging from you comment to #Luchian Grigore, you're confusing divisors with (prime) factorization. Divisors of a number are all numbers for which num % i == 0 is true. Factorization means getting a representation of num by a product of smaller numbers. If you want uniqueness of factorization, you usually use prime factorization.
To get all the divisors your code should be
for ( int i = 1; i <= num; ++i ) // note that 1 and num are both trivially divisors of num
{
if ( num % i == 0 ) // only check for divisibility
{
std::cout << i << std::endl;
}
}
to get the (prime) factorization, it's
for ( int i = 2; i <= num; ++i )
{
while ( num % i == 0 ) // check for divisibility
{
num /= i;
std::cout << i << std::endl;
}
// at this point, i cannot be a divisor of the (possibly modified) num.
}

The problem is that you're increasing i even if it is a divisor, and you shouldn't unless you find all its occurences.
So, for 4, you'd have 2 twice. But after the first 2 you encounter, you exit the loop because i is incremented to 3 and num became 2.
The following should work:
for(int i = 2; i <= num; )
{
if(num%i == 0)
{
cout << i << endl;
cout << num << endl;
num = num/i;
}
else
{
i++;
}
}

for(int i = 2; i <= num; i++)
{
if(num%i == 0)
{
cout << i << endl;
cout << num << endl;
num = num/i;
i--; // Add this to account for multiple divisors
}
}
for(int i = 2; i <= num; i++)
{
if(num%i == 0)
{
cout << i << endl;
cout << num << endl;
}
}

This should work. Note, should use c++11 for move constructor, otherwise you are going to want to pass in a std::list& instead.
std::list<int64_t> factor(int64_t f)
{
std::list<int64_t> factors;
for(int64_t ii = 2; ii<=f; ii++) {
while(f % ii == 0) {
f = f/ii;
factors.push_back(ii);
}
}
return factors;
}

Related

How do i sum all numbers using loop?

For Example, I have number 1 + 6 + 7 + 12 + 13 + 18+.....+ n (n is the input from users which represent the number of elements) the index of this number starts from 1 by this it means​ that if the index is an odd number (1,3,5...) I want to increment the element at that index by 5 and if the index is an even number I want to increment the element at that index by 1 until I reach the of n number of elements. What I want is to sum all those numbers.
Sorry, It may hard to understand because of my poor English So let me write some of my C code here:
using namespace std;
int i, n, result = 0;
cout << "Input number to sum: ";
cin >> n;
// Finding result
for (i = 0; i <= n; i++){
if (i % 2 == 0) {
result +=i;
} else {
result += i * 5;
}
}
// Make last number have equal sign "1+6+7+12 = 36"
for (i = 0; i <= n; i++){
if (i == n) {
cout << i..?? << "=";
} else {
cout << i..?? << "+";
}
}
// Print result out
cout << result;
return 0;
}
Combine the computation with the output (I usually preach the opposite, but in this case it actually simplifies matters).
for (int i = 0; i <= n; i++)
{
int value = i % 2 == 0 ? i + 1 : i + 5;
cout << (i > 0 ? " + " : "") << value;
result += value;
}
cout << " = " << result;
I agree with the molbdnilo that combining calculations and output in this case, simplify the code.
I don't agree with the algorithm, though, given OP's description.
In the following the calculations are repeated to output the result
#include <iostream>
int main()
{
int n;
std::cout << "Input number to sum: ";
std::cin >> n;
auto update = [] (int i) { return i % 2 == 0 ? 1 : 5; };
int result = 0;
int value = 0;
for (int i = 0; i < n; i++)
{
value += update(i);
result += value;
}
std::cout << '\n';
for (int i = 0, value = 0; i < n; i++)
{
value += update(i);
std::cout << (i > 0 ? " + " : "") << value;
}
std::cout << " = " << result;
}
Testable here.
I agree with molbdnilo's answer. However the algorithm some changes.
The index starts from 1 , so value check for i in for loop should be
for (int i = 0; i < n; i++)
while updating the values, increment should be done on value and not on i.
Here is my solution:
using namespace std;
int main()
{
int i, n, result, value = 0;
cout << "Input number to sum: ";
cin >> n;
for (i = 0; i < n; i++)
{
value = i % 2 == 0 ? value + 1 : value + 5;
cout << (i > 0 ? " + " : "") << value;
result += value;
}
cout << " = " << result;
return 0;
}
Testable here

How to make the outcome of a boolean function to output a certain statement when the boolean is TRUE or FALSE in the main (c++)?

Problem
I am trying to write a program that can output all of a numbers prime factors. I started by making a function to check whether a factor is prime or not:
bool checkPrime() {
for (x = 1; x <= i; ++x) {
if (x % i != 0) {
return 1;
}
else {
return 0;
}
}
Main
int main() {
cout << "Enter any positive number: " << endl;
cin >> n;
cout << "Prime Factors of " << n << " are: " << endl;
for (i = 1; i <= n; ++i) {
if (n % i == 0) {
for (x = 1; x <= i; ++x) {
cout << i << " ";
}
}
cout << "\n";
system("pause");
}
Question
How can I implement my "checkPrime" function to check whether or not I run:
cout << i << " ";
I reckon the problem is to print the boolean return value of checkPrime() function as true or false. I'm not going in to the correctness of checkPrime() function in this answer. But for your purpose use something like the following.
std::cout << std::boolalpha << checkPrime() << std::noboolalpha << std::endl;
Refer: https://en.cppreference.com/w/cpp/io/manip/boolalpha
I didn't look into you checkPrime() function, but ideally it should accept n as an argument.
Change checkPrime to accept an input.
Fix the the implementation. The current implementation is not correct.
Add a call to the function in main and output the number based on the return value of the function.
bool checkPrime(int i)
{
// 1 and 2 are primes
if ( i < 2 )
{
return true;
}
if ( i % 2 == 0 )
{
return false;
}
// Check with only odd numbers.
// Division by even numbers is not necessary.
// Even numbers greater than 2 are not prime numbers.
// Also, you don't need to check for division by numbers greater than sqrt(i)
for (x = 3; x*x <= i; x +=2 )
{
if ( i % x == 0)
{
return false;
}
}
return true;
}
In main:
for (i = 1; i <= n; ++i)
{
if (n % i == 0 )
{
if ( checkPrime(i) )
{
cout << i << " ";
}
}
}
You can combine the two if statements into one if statement.
for (i = 1; i <= n; ++i)
{
if (n % i == 0 && checkPrime(i) )
{
cout << i << " ";
}
}

C++ How to use a function returning a Boolean Value to determine prime numbers

I am suppose to make a program that asks a user to input an integer 'n' between 1 and 100, and have an input validation loop. The program will then calculate the first 'n' prime numbers and print them. So I figured out how to calculate the prime numbers and display them, 10 numbers per line, all in the main function. What I have to do is to have a function called isPrime() that takes an integer and returns true if it is prime and false otherwise. I'm not sure how to go about this. This is the code I have for function main().
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int number;
int count = 0;
cout << "Enter an integer between 1 and 100: ";
cin >> number;
while (number < 0 || number > 100)
{
cout << "Invalid number." << endl;
cout << "Enter an integer between 1 and 100: ";
cin >> number;
}
cout << "The first " << number << " primes: \n" << endl;
for (int i = 2; number > 0; ++i)
{
bool isPrime = true;
for (int j = 2; j < i; ++j)
{
if (i % j == 0)
{
isPrime = false;
break;
}
}
if (isPrime)
{
count++;
--number;
cout << setw(5) << i;
if (count % 10 == 0)
cout << endl;
}
}
cout << endl;
system("pause");
return 0;
}
Any help is good, thanks in advance.
You seem to be testing i % j for every j lower then i. But if you tested for j = 3 then you can exclude all multiples of 3. When a number can't be divided by 3 it can't be divided by 6. This will improve performance.
You can also implement the AKS primalty test https://en.wikipedia.org/wiki/AKS_primality_test
This might be a little more work. I don't know the details of this test but it is deterministic and works on all numbers.
If you want a function bool isPrime(int number) you can just extract this code from your main method, it looks something like this:
bool isPrime(int number){
for (int j = 2; j < number/2; ++j)
{
if (number % j == 0)
{
return false;
}
}
return true;
}
The for loop in the main function will be something like:
for (int i = 2; number > 0; ++i)
{
if (isPrime(i))
{
count++;
--number;
cout << setw(5) << i;
if (count % 10 == 0)
cout << endl;
}
}

Display output 4 per line

I'm taking my first programming course and am new to this forum. Any help will be greatly appreciated! For one of my class assignments I had to write a program that would find the factors of a given number, I've got the program up and running but one of the stipulations is that the output must be displayed four to a line and that's where I'm running into trouble. I've read around on some other forums as well as here but I guess I'm not grasping what I would have to do in my particular case.
Here's my code as is:
#include <iostream>
using namespace std;
int main(){
int n;
while (cout << "Please enter a number: " && !(cin >> n) || (n < 0.0) || cin.peek() != '\n')
{
cout << "Input must be a positive number!" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
for (int i=2; i <= n; i++)
{
while (n % i == 0)
{
n /= i;
cout << "*" << i;
}
}
cout << endl;
system ("PAUSE");
return 0;
}
You're going to need to add a counter outside the loop.
//int counter = 0;
for (int i=2; i <= n; i++)
{
while (n % i == 0)
{
n /= i;
cout << "*" << i;
}
}
The counter will need to keep track of how many entries have been printed.
Once you have seen 4 entries printed:
print an extra newline
and set the counter back to 0
You may use the following:
void display_factors(std::size_t n, std::size_t factor_by_line)
{
const char* sep = "";
std::size_t count = 0;
std::cout << n << " = ";
for (int i = 2; i <= n; ++i) {
while (n % i == 0) {
n /= i;
if (count == factor_by_line) {
std::cout << std::endl;
count = 0;
}
++count;
std::cout << sep << i;
sep = " * ";
}
}
std::cout << std::endl;
}
Live Demo

Classifying digits of an integer value

I spent a day on this code for count even and zero and odd numbers
From long datatype I used a function to send data. Here is the code
#include <iostream>
using namespace std;
void digitCount(long long int &num);
int main ()
{
long long int num;
cout <<"Enter any No. " <<endl;
cin >>num;
cout <<endl;
digitCount(num);
return 0;
}
void digitCount(long long int &num)
{
int e = 0, z = 0, o = 0, x = 0;
for (int i = 0; i <= num; i++)
{
x= num % 10;
if(x == 0)
{
++z;
num = num / 10;
}
else if(x%2==1)
{
++o;
num = num / 10;
}
else
{
++e;
num = num / 10;
}
}
cout << "No of zeros Digits = " << z<< endl;
cout << "No of odd Digits = " << o << endl;
cout << "No of Even Digits = " << e << endl;
}
the problem is when I count odd numbers there is a number missed
for example when i input : 12345
the result is
no of even : 2
no of odd : 2 (should be 3)
no of zero : 0
and here the question :
Write a function that takes as parameter an integer (as a long value) and returns the number of odd, even, and zero digits. Also write a program to test your function. Use pass by reference method.
Instead of the for loop you should use:
while (num > 0)
You're constantly changing num and when it gets to 1 (in your 12345 example), i is at 3. I also modified your digitcount to demonstrate some decent formatting for readable code.
void digitCount(long long int &num) {
int e(0), z(0), o(0), x(0);
while (num > 0) {
x = num % 10;
if (x == 0) {
z++;
}
else if (x % 2 == 1) {
o++;
}
else {
e++;
}
num /= 10;
}
cout << "No of zeros Digits = " << z << endl;
cout << "No of odd Digits = " << o << endl;
cout << "No of Even Digits = " << e << endl;
}
If you believe this solves your problem && is the best answer, please click the checkmark next to this answer. Thanks