So, I need to implement TheSameDigit() function, basically this function needs to print out all combinations of numbers that has the same digits. TheSameDigit function MUST be recursive and use NoDigits() and DelDigit() functions.
NoDigits(int x) => This function will return the number of digits
input: 123, output: 3
DelDigit(int x, int delD) => This function return an int which value is x, but having the delD-digit removed.
input: x = 789, delD = 2, output = 79
TheSameDigit() => The function to prints the combination of numbers with the same digits(it does not work currently).
Input: 123
Output:
123
231
132
312
213
321
#include <iostream>
using namespace std;
int NoDigits(int x);
int DelDigit(int x, int delD);
void TheSameDigits(int x, int i, int origin, bool firstTime);
int main() {
int num;
cout << "Please input an integer: ";
cin >> num;
cout << "All integers have the same digits with " << num << " are: " << endl;
TheSameDigits(num, 1, num, 1);
}
int NoDigits(int x) {
if (x == 0) {
return 0;
}
return 1 + NoDigits(x / 10);
}
int DelDigit(int x, int delD) {
int size = NoDigits(x);
int reverse = 0;
for (int i = 0; x != 0; i++, x /= 10) {
if (i != size - delD) {
int digit = x % 10;
reverse = reverse * 10 + digit;
}
}
int newNum = 0;
for (int i = 0; reverse != 0; i++, reverse /= 10) {
int digit = reverse % 10;
newNum = newNum * 10 + digit;
}
return newNum;
}
void TheSameDigits(int x, int i, int origin, bool firstTime) {
const int size = NoDigits(origin);
// Base case
if (origin == x && !firstTime) {
return;
}
if (i == size) {
i = 1;
}
// Find the removed digit
int temp = x;
int removedDigit;
for (int j = 0; temp > 0; j++, temp /= 10) {
if (j == size - i) {
removedDigit = temp % 10;
break;
}
}
// Calculate the next combination
int nextNum = (DelDigit(x, i) * 10) + removedDigit;
cout << nextNum << endl;
TheSameDigits(nextNum, i + 1, origin, false);
}
Can someone help me implement TheSameDigit function or give me an idea about it?
Thank you!
bool isSphenic (int num){
int initial_num = num;
int product = 1;
int prime_count = 0;
int i = 2;
while (num > 1){
if(num % i == 0){
if(isPrime(i)){
num = num/i;
product = product * i;
prime_count = prime_count + 1;
}
}
i++;
}
if(product == initial_num && prime_count == 3 ){
return true;
}
return false;
}
I can't figure out where the lag is coming from. I'm using it on a list of about 100 numbers from 1 to 100. It correctly identifies the sphenic numbers but it takes minutes, or crashes...
The problem with the function is that it does not divide a given number by a prime number until the number is not divisible by the prime number.
For example for the number equal to 4 the division occurs inly once by 2 and then I is increased but num is not equal to 1. It is equal to 2 after the division.
So the function has an infinite loop.
The function can look similar to the function presented in the demonstrative program.
#include <iostream>
bool isSphenic ( unsigned int n )
{
const unsigned int DISTINCT_PRIMES = 3;
unsigned int count = 0;
unsigned int product = 1;
for ( unsigned int tmp = n, i = 2; count < DISTINCT_PRIMES && tmp != 1; i++ )
{
if ( tmp % i == 0 )
{
++count;
product *= i;
while ( tmp % i == 0 ) tmp /= i;
}
}
return count == DISTINCT_PRIMES && product == n;
}
int main()
{
const int N = 200;
for ( int i = 1; i < N; i++ )
{
if ( isSphenic( i ) ) std::cout << i << ' ';
}
std::cout << '\n';
return 0;
}
The program output is
30 42 66 70 78 102 105 110 114 130 138 154 165 170 174 182 186 190 195
Pay attention to that there is no need to call the function sPrime as you are doing.
I'm trying to get the longest(largest) sequence of consecutive prime numbers from an array..
On first test with 10 elements in the array works , but when i tried with 15 elements like: 3, 5, 7, 8, 9, 11, 13, 17, 19, 20, 23, 29, 31, 37, 41 it spit out 4, which is incorrect.
#include <iostream>
using namespace std;
int main()
{
int bar[100];
int x, j = 0;
int maxseq = 0;
int longestseqstart = 0;
cout << "How big is the array? =";
cin >> x;
for (int i = 0; i < x; i++) {
cout << "bar[" << i << "]=";
cin >> bar[i];
}
for (int i = 1; i < x - 1; i = j) {
int startseq = i;
int seq = 0;
j = i + 1;
bool prim = true;
int a = bar[i];
for (int d = 2; d <= a / 2; d++) {
if (a % d == 0) {
prim = false;
}
}
while (j < x && prim) {
seq++;
if (seq > maxseq) {
maxseq = seq;
longestseqstart = i;
}
int a = bar[j];
for (int d = 2; d <= a / 2; d++) {
if (a % d == 0) {
prim = false;
}
}
j++;
}
}
cout << "The longest sequence is: ";
cout << maxseq;
return 0;
}
I would write the program the following way
#include <iostream>
#include <iterator>
#include <algorithm>
bool is_prime( unsigned int n )
{
bool prime = n % 2 == 0 ? n == 2 : n != 1;
for ( unsigned int i = 3; prime && i <= n / i; i += 2 )
{
prime = n % i != 0;
}
return prime;
}
int main()
{
unsigned int a[] = { 3, 5, 7, 8, 9, 11, 13, 17, 19, 20, 23, 29, 31, 37, 41 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t maxseq = 0;
for ( auto current = std::find_if( a, a + N, is_prime );
current != a + N;
current = std::find_if( current, a + N, is_prime ) )
{
auto first = current;
current = std::find_if_not( current, a + N, is_prime );
size_t n = std::distance( first, current );
if ( maxseq < n ) maxseq = n;
}
std::cout << "The longest sequence is: " << maxseq << '\n';
return 0;
}
The program output is
The longest sequence is: 5
I did not use generic functions std::begin( a ) and std::end( a ) because in your program the array can contain less actual elements than the array dimension.
If you do not know yet standard C++ algorithms then the program can be defined the following way
#include <iostream>
bool is_prime( unsigned int n )
{
bool prime = n % 2 == 0 ? n == 2 : n != 1;
for ( unsigned int i = 3; prime && i <= n / i; i += 2 )
{
prime = n % i != 0;
}
return prime;
}
int main()
{
unsigned int a[] = { 3, 5, 7, 8, 9, 11, 13, 17, 19, 20, 23, 29, 31, 37, 41 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t maxseq = 0;
size_t n = 0;
for ( size_t i = 0; i < N; i++ )
{
bool prime = a[i] % 2 == 0 ? a[i] == 2 : a[i] != 1;
for ( unsigned int j = 3; prime && j <= a[i] / j; j += 2 )
{
prime = a[i] % j != 0;
}
if ( prime )
{
if ( maxseq < ++n ) maxseq = n;
}
else
{
n = 0;
}
}
std::cout << "The longest sequence is: " << maxseq << '\n';
return 0;
}
The program output is the same as above
The longest sequence is: 5
As for your program then this loop
for (int i = 1; i < x - 1; i = j) {
skips the first element of the array that is bar[0].
And due to this statement
j = i + 1;
the calculated value of seq one less than it should be because you do not take into account that bar[i] is already prime.
Set initially seq equal to 1.
int seq = 1;
Moreover you incorrectly are determining prime numbers. For example according to your algorithm 1 is prime.
You are checking twice for prime numbers and you are using a nested loop. That's not necessary. It's enough to read all numbers, check each number, increment the count if it's a prime number and store the maximum sequence length.
#include <iostream>
#include <vector>
using namespace std;
bool isPrime(int a) {
bool prim = true;
for (int d = 2; d*d <= a; ++d) {
if (a % d == 0) {
prim = false;
}
}
return prim;
}
int main()
{
int x;
int longestseqstart = 0;
cout << "How big is the array? =";
cin >> x;
std::vector<int> bar(x);
for (int i = 0; i < x; i++) {
cout << "bar[" << i << "]=";
cin >> bar[i];
}
unsigned int count = 0;
unsigned int maxseq = 0;
for (const auto &el : bar) {
if (isPrime(el)) {
++count;
if (count > maxseq) maxseq = count;
} else count = 0;
}
cout << "The longest sequence is: ";
cout << maxseq;
return 0;
}
Of course you can avoid the usage of std::vector and functions with
#include <iostream>
using namespace std;
int main()
{
int x;
int longestseqstart = 0;
cout << "How big is the array? =";
cin >> x;
int bar[100];
for (int i = 0; i < x; i++) {
cout << "bar[" << i << "]=";
cin >> bar[i];
}
unsigned int count = 0;
unsigned int maxseq = 0;
for (unsigned int i = 0; i < x; ++i) {
int a = bar[i];
bool prim = true;
for (int d = 2; d*d <= a; ++d) {
if (a % d == 0) {
prim = false;
}
}
if (prim) {
++count;
if (count > maxseq) maxseq = count;
} else count = 0;
}
cout << "The longest sequence is: ";
cout << maxseq;
return 0;
}
The algorithm looks basically OK. The issue is mostly one of organization: the way the inner loop block is set up means that a run of primes will be short by 1 because the longest sequence is only updated at the beginning of the inner loop, missing the final prime.
A couple of minimal failing examples are:
How big is the array? =1
bar[0]=13
The longest sequence is: 0
How big is the array? =2
bar[0]=5
bar[1]=6
The longest sequence is: 0
Note that there's a repeated prime check in two places. This should not be. If we move all of the prime logic into the loop and test for a new longest sequence only after finishing the entire run, we'll have a clear, accurate algorithm:
#include <iostream>
int is_prime(int n) {
for (int i = 2; i <= n / 2; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
int main() {
int nums[100];
int n;
std::cout << "How big is the array? =";
std::cin >> n;
for (int i = 0; i < n; i++) {
std::cout << "nums[" << i << "]=";
std::cin >> nums[i];
}
int longest = 0;
for (int i = 0, start = 0; i < n; i++) {
for (start = i; i < n && is_prime(nums[i]); i++);
longest = std::max(longest, i - start);
}
std::cout << "The longest sequence is: " << longest;
return 0;
}
In this rewrite I...
avoided using namespace std;.
removed unnecessary/confusing variables.
used clear variable names (bar should only be used in example code when the name doesn't matter).
moved is_prime to its own function.
But there are outstanding issues with this code. It should...
use a vector instead of an array. As it stands, it's vulnerable to a buffer overflow attack should the user specify an array length > 100.
use a faster method of finding primes. We only need to check up to the square root of the number and can skip a lot of numbers such as even numbers after 2. I suspect this is incidental to this exercise but it's worth mentioning.
move the longest_prime_sequence to a separate function (and possibly user input gathering as well).
Convert the array to a Boolean array and find longest length. Try this snippet(not optimized):
bool is_prime(int n) {
for (int i = 2; i < n; i++) {
if (n%i == 0) return false;
}
return true;
}
int main() {
//Input
unsigned int bar[15] = { 3, 5, 7, 8, 9, 11, 13, 17, 19, 20, 23, 29, 31, 37, 41 };
// Convert input to boolean array
bool boo[15];
for (int i = 0; i < 15; i++) {
boo[i] = is_prime(bar[i]);
}
//Check the longest boolean array
int longest = 0;
for (int i = 0; i < 15; i++) {
int count = 0;
while (boo[i + count] && (i+ count) <15) {
count++;
}
if (longest < count) longest = count;
}
//Output
cout << longest;
return 0;
}
The assignment calls for using 3 input and 3 output files, but for now I am trying just one. The program is supposed to include a function template that sorts an array of values in ascending order. The function will receive an unordered array and will return an ordered array. The function isn't supposed to perform any input or output.
My code exists as the following:
#include <iostream>
#include <iostream>
#include <fstream>
using namespace std;
ifstream inNumbers("intTestRead.txt");
ofstream outNumbers("intTestWrite.txt");
template<typename int[], typename int> void SelectionSort(int[], int);
void SelectionSort(int v[], int n)
{
int iMin;
for (int i = 0; i < n - 1; i++)
{
iMin = i;
for (int j = i + 1; j < n; j++)
{
if (v[j] < v[iMin])
{
iMin = j;
}
}
int aux = v[i];
v[i] = v[iMin];
v[iMin] = aux;
}
}
void main()
{
int data[100];
int i;
int length = 0;
if (!inNumbers)
cerr << "intTestRead.txt file could not be opened" << endl;
for (i = 0; i < 100 && inNumbers; ++i)
{
inNumbers >> data[i];
if (inNumbers)
{
length += 1;
}
SelectionSort(data, length);
outNumbers << data[i] << endl;
}
}
I mainly program in Java, and now just beginning C++ confuses me with templates and whatnot. The sorting function was given to us by the professor. My reading file looks like this:
65 40 84 9 79 90 71 93 39 44
It's supposed to look like this:
9 39 40 44 65 71 79 84 90 93
But look's like this:
65
65
84
84
84
90
90
93
93
93
-858993460
^^ I know because I'm using endl results in the new lines, but multiple recursions of the same number + the -85 is putting me off. Any help would be greatly appreciated.
Don't call the sort function after each input. Just call it when all input is ready.
Something like:
void main()
{
int data[100];
int i;
int length = 0;
if (!inNumbers)
cerr << "intTestRead.txt file could not be opened" << endl;
for (i = 0; i < 100 && inNumbers; ++i)
{
inNumbers >> data[i];
if (inNumbers)
{
length += 1;
}
}
SelectionSort(data, length);
for (i = 0; i < length; ++i)
{
outNumbers << data[i] << endl;
}
}
Looked at it again, and used an alternative:
#include <iostream>
#include <iostream>
#include <fstream>
#define NUMBERS 10
using namespace std;
ifstream inNumbers("intTestRead.txt");
ofstream outNumbers("intTestWrite.txt");
template <class T>
void Swap(T& A, T& B)
{
T temp;
temp = A;
A = B;
B = temp;
}
template <class T>
void SelectionSort(T A[], int N)
{
T min;
int j, k, minIndex;
for (k = 0; k < N; k++) {
min = A[k]; minIndex = k;
for (j = k + 1; j < N; j++) {
if (A[j] < min) { min = A[j]; minIndex = j; }
}
Swap(A[k], A[minIndex]);
}
}
void main()
{
int data[100];
int i = 0;
if (!inNumbers)
cerr << "intTestRead.txt file could not be opened" << endl;
for (i = 0; i < NUMBERS && inNumbers; ++i)
{
inNumbers >> data[i];
}
SelectionSort(data, NUMBERS);
for (int i = 0; i < NUMBERS; ++i)
outNumbers << data[i] << endl;
}
Input:
65
40
84
9
79
90
71
93
39
44
Output:
9
39
40
44
65
71
79
84
90
93
As part of a homework assignment, I need to be able to implement a merge sort using a structure as the main argument. Having not been familiar with the merge sort until today, i have attempted to write my own implementation of it. For some reason I cannot get it to work.
Here is my code:
#include<iostream>
#include<stdlib.h>
using namespace std;
struct MergeArgument
{
int *numArray;
int *tempArray;
int lowIndex, highIndex;
};
void merge(MergeArgument*);
void merge_sort(MergeArgument*);
int main(int argc, char** argv)
{ int SIZE = 25;
MergeArgument arg;
int arr[SIZE];
int temp[SIZE];
for(int k = 0; k < SIZE; k++)
{
arr[k] = rand() % 100;
cout << arr[k] << " ";
}
arg.numArray = arr;
arg.tempArray = temp;
arg.lowIndex = 0;
arg.highIndex = SIZE - 1;
cout << endl;
merge_sort(&arg);
cout << "Sorted array: \n";
for (int i = 0; i < SIZE; i++)
cout << arr[i] << " ";
cout << endl;
return 0;
}
void merge_sort(MergeArgument *arg)
{ int tempHigh, tempLow;
if(arg->lowIndex < arg->highIndex)
{
tempHigh = arg->highIndex;
tempLow = arg->lowIndex;
arg->highIndex = (tempHigh + tempLow) / 2;
merge_sort(arg);
arg->highIndex = tempHigh;
arg->lowIndex = ((tempHigh + tempLow) / 2) + 1;
merge_sort(arg);
arg->lowIndex = tempLow;
merge(arg);
}
}
void merge(MergeArgument *arg)
{ int low = arg->lowIndex, mid = ((arg->lowIndex + arg->highIndex) / 2), high = arg->highIndex;
int i = low, lowCounter = low, highCounter = mid + 1;
while((lowCounter <= mid) && (highCounter <= high))
{
if(arg->numArray[lowCounter] < arg->numArray[highCounter])
{
arg->tempArray[i] = arg->numArray[lowCounter];
lowCounter++;
}
else
{
arg->tempArray[i] = arg->numArray[highCounter];
highCounter++;
}
i++;
}
if (lowCounter < mid)
{
for (int k = lowCounter; k < mid; k++)
{
arg->tempArray[i] = arg->numArray[k];
i++;
}
}
else
{
for (int k = highCounter; k <= arg->highIndex; k++)
{
arg->tempArray[i] = arg->numArray[k];
i++;
}
}
for(int k = arg->lowIndex; k <= arg->highIndex; k++)
{
arg->numArray[k] = arg->tempArray[k];
}
}
Here is the output I am getting:
83 86 77 15 93 35 86 92 49 21 62 27 90 59 63 26 40 26 72 36 11 68 67 29 82
Sorted array:
11 -1216235240 15 0 21 26 -1079135248 26 27 -1079135396 29 -1216770650 35 -1216235240 49 -1216492084 59 0 68 72 82 83 0 86 82
Can anyone point out what exactly I am doing wrong?
This is pretty close to working, although you might want to consider some of the comments folks have made on making this more C++ like. No doubt this is from hard-won experience that there is never enough time to go back and do what you really should do.
The problem I see is here, in merge:
if (lowCounter < mid)
{
for (int k = lowCounter; k < mid; k++)
{
arg->tempArray[i] = arg->numArray[k];
i++;
}
}
You might want to compare and contrast the bounds here to the initial loop.