Extracting a subsequence from an array - c++

I'm trying to solve an algorithm for extracting a subsequence from an array. It should display the longest subsequence of prime numbers. I have written the whole algorithm but I still get an infinite cycle and I can't figure out where and why. I'm incrementing both indices and modifying the first index at the end, but it is still not working. Thanks a lot !!!
P.S: citire reads the array, prim detects if a number is prime or composed, afisare displays the subsequence and detSecv determines the longest subsequence.
#include <iostream>
#include <math.h>
using namespace std;
void citireSecv(int &n,int x[50])
{
cout<<"Da n: ";
cin>>n;
for(int i=1;i<=n;i++)
{
cout<<"Da un nr: ";
cin>>x[i];
}
}
int prim(int n)
{
int d=2;
while(d<=sqrt(n) && n%d!=0)
{
if(d==2)
d=3;
else
d=d+2;
}
if(d>sqrt(n)) return 1;
else return 0;
}
void afisare(int n,int x[50],int st,int f)
{
for(int i=st;i<=f;i++)
cout<<x[i]<<" ";
}
void detSecv(int n,int x[100],int &st,int &f)
{
st=1; f=0;
int i=1,j;
while(i<=n-1)
{
while(i<=n-1)
{
if(prim(x[i])==0 && prim(x[i+1])==0) i++;
}
j=i+1;
while(j<=n-1)
if(prim(x[j])==0 && prim(x[j+1])==0) j++;
if((j-i) > (f-st))
{
st=i;
f=j;
}
i=j+1;
}
}
int main()
{
int n,x[100],st,f;
citireSecv(n,x);
detSecv(n,x,st,f);
afisare(n,x,st,f);
return 0;
}
Input data:
n=2
First number is: 5
Second number is: 7

Probably just one of many issues with that code:
while(i<=n-1)
{
if(prim(x[i])==0 && prim(x[i+1])==0) i++;
}
j=i+1;
while(j<=n-1)
if(prim(x[j])==0 && prim(x[j+1])==0) j++;
There are two potential infinite loops here. If the conditions in the while don't return true on the first iteration, i (or j) will never get incremented, and you will have your infinite loop. You should almost always increment such variables outside of any conditions.

With a slight change in your code, you make it work, and one thing, you don't need to start array with index 1. you can always start with index zero.
for(int i=1;i<=n;i++)
{
cout<<"Da un nr: ";
cin>>x[i];
}
try to check for a case when no prime subsequence is found, while printing.
void detSecv(int n, int *x, int &start, int &end)
{
start = -1;
end = -1;
int i=0,j;
while(i < n) {
if(prim(x[i])) {
j = i + 1;
while(j < n)
if(prim(x[j])) j++;
else break;
} else {
i++;
continue;
}
if((j-i) > (end - start)) {
start = i;
end = j-1;
}
i=j+1;
}
}

This is a better way to verify if a number is prime or not
bool IsPrime(int number) {
int primeStep = 2;
double stepLimit = sqrt(number);
while(primeStep <= stepLimit)
{
if(number % primeStep == 0)
return false;
primeStep += 1;
}
return true;
}
And nou you can apply that function for each number in your array, and if it's prime , you add it in a new array like this:
void detSecv(int numberOfItems,int *arrayOfNumbers)
{
int arrayOfPrimeNumbers[50] = {};
int index = 0;
for(int i = 0; i < numberOfItems; i++)
{
if(IsPrime(arrayOfNumbers[i])){
arrayOfPrimeNumbers[index] = arrayOfNumbers[i];
index += 1;
}
}
int secondIndex = 0;
while(arrayOfPrimeNumbers[secondIndex] != 0)
{
cout << arrayOfPrimeNumbers[secondIndex] << " ";
secondIndex += 1;
}
}

Related

Write a program that will display all prime numbers from the given range

Write a program that will display all prime numbers from the given range. The program must satisfy the following requirements:
a. ask the user of range to display
b. contains the following function:
i. checkRange() – a functions that checks if the entered range is correct or not. A message will be displayed if the range is invalid.
ii. displayPrime() – a function that displays all prime numbers in the given range
NOTE: you will provide the parameter(s) for each function.
here's the code that i made: there is something wrong in my code. I can't pinpoint what is it
#include <iostream>
using namespace std;
int main()
{
int Prime, strt, end, result;
bool isprime=true;
Again:
cout<<"Start: ";
cin>>strt;
cout<<"End: ";
cin>>strt;
cout<<"\n";
if (strt>end)
{
cout<<"Range is Invalid, Try Again."<<"\n";
goto Again;
}
result = Prime(strt,end);
cout<<"Prime numbers in the given range are: "<<result<<endl;
return 0;
}
int Prime(int strt, int end, int num, isprime)
{
int result;
while (strt<end)
{
isprime=true;
if (strt == 0 || strt == 1)
{
isprime = false;
}
for (num = 2; num <= strt/2; ++num)
{
if (strt % num == 0)
{
isprime = false;
break;
}
}
if (isprime)
cout << strt << ", ";
++strt;
}
return result;
}
Here is the answer, there are many issues with the code that I won't go through them, ask if you don't understand something
#include <iostream>
using namespace std;
int prime(int strt, int end)
{
bool isprime;
int count;
while (strt<end)
{
isprime=true;
if (strt == 0 || strt == 1)
{
isprime = false;
}
for (int num = 2; num <= strt/2; ++num)
{
if (strt % num == 0)
{
isprime = false;
break;
}
}
if (isprime) {
cout << strt << ", ";
++count;
}
++strt;
}
return 0;
}
int main()
{
int strt, end, result;
Again:
cout<<"Start: ";
cin>>strt;
cout<<"End: ";
cin>>end;
cout<<"\n";
if (strt>end)
{
cout<<"Range is Invalid, Try Again."<<"\n";
goto Again;
}
cout<<"Prime numbers in the given range are: ";
prime(strt,end);
return 0;
}
This is Probably the simplest way I can put it for you.
#include<iostream>
using namespace std;
int check_range(int a,int b)
{
if (a > b)
return 0;
else
return 1;
}
int check_prime(int a,int b)
{
bool isprime;
while (a < b)
{
isprime=true;
if (a == 0 || a == 1)
{
isprime = false;
}
for (int i = 2; i <= a/2; i++)
{
if (a % i == 0)
{
isprime = false;
break;
}
}
if (isprime) {
cout <<a<<" ";
}
a++;
}
}
int main()
{
int strt,end;
Repeat :
cout<<"Enter the lower limit of range :";
cin>>strt;
cout<<"Enter the upper limit of range :";
cin>>end;
int p = check_range(strt,end);
if (p)
{
check_prime(strt,end);
}
else
{
cout<<"The range is inappropriate.\n";
goto Repeat;
}
}
Hope you would understand.

Breaking out of loop from function after printing the last prime number of a given range

I'm writing a code to find the last prime number of a given range. Suppose the range is 1 to 50. Then the last prime no. I want to print must be 47. My idea was to maybe reverse the order of prime numbers in the range and then try printing only the first value. Again kinda like if my order was 1 to 50 then I would start printing from 47, 43 and so on and only print 47. But I'm stuck and not getting ideas on how I could do this. here's my code
int prime_bef(int n)
{
int check = 0;
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
check++;
}
}
if (check == 2)
{
cout << n << " ";
}
return 0;
}
int main ()
{
int l;
int u;
cin >> l >> u;
for (int i = u; i >= l; i--)
{
prime_bef(i);
}
return 0;
}
You can just use exit() in the place you want to end the program, and it works fine in your case. But by far the best approach is returning a value to test for continuation, it is the most readable.
#include<iostream>
#include <stdlib.h>
using namespace std;
int prime_bef(int n)
{
int check = 0;
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
check++;
}
}
if (check == 2)
{
cout << n << " ";
exit(0);
}
return 0;
}
int main ()
{
int l;
int u;
cin >> l >> u;
for (int i = u; i >= l; i--)
{
prime_bef(i);
}
return 0;
}
Same code using bool return type:
#include<iostream>
using namespace std;
bool prime_bef(int n)
{
int check = 0;
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
check++;
}
}
if (check == 2)
{
cout << n << " ";
return true;
}
return false;
}
int main ()
{
int l;
int u;
cin >> l >> u;
for (int i = u; i >= l; i--)
{
if(prime_bef(i))
break;
}
return 0;
}
Here is a simple and efficient way to check if the number is prime. I am checking if the number is prime and when it is true I am printing the number and breaking the loop so that only 1 number is printed. You can always remove the break statement and print all prime numbers in range.
#include<iostream>
using namespace std;
bool isPrime(int n){
if(n==2)return true;
if(n%2==0 || n==1)return false;
for(int i=3; i*i<=n; ++i){
if(n%i==0){
return false;
}
}
return true;
}
int main (){
int l, u;
cin>>l>>u;
for (int i = u; i >= l; i--){
if(isPrime(i)){
cout<<i<<"\n";
break;
}
}
return 0;
}
I'll give you a hint... while you are iteratively checking for the prime nature of the number, also check whether the last prime number calculated in the loop is greater than the max term of the range and break the loop when the condition becomes false.
Here a C++17 approach :
#include <cmath>
#include <iostream>
#include <vector>
// type to use for storing primes
using prime_t = unsigned long;
// there is a way to determine an upper bound to the number of primes smaller then a maximum number.
// See : https://primes.utm.edu/howmany.html
// this can be used to estimate the size of the output buffer (vector)
prime_t pi_n(const prime_t max)
{
prime_t pi_n{ max };
if (max > 10)
{
auto ln_n = std::log(static_cast<double>(max));
auto value = static_cast<double>(max) / (ln_n - 1.0);
pi_n = static_cast<prime_t>(value + 0.5);
}
return pi_n;
}
// Calculate prime numbers smaller then max
// https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
auto calculate_primes(const prime_t max)
{
std::vector<bool> is_primes(max, true);
// 0, 1 are not primes
is_primes[0] = false;
is_primes[1] = false;
// sieve
for (prime_t n = prime_t{ 2 }; n < prime_t{ max }; ++n)
{
if (is_primes[n])
{
auto n2 = n * n;
for (prime_t m = n2; m < max; m += n)
{
is_primes[m] = false;
}
}
}
// avoid unnecessary resizes of vector by pre-allocating enough entries to hold result
prime_t n{ 0 };
std::vector<prime_t> primes;
primes.reserve(pi_n(max));
// add all prime numbers found by the sieve
for (const auto is_prime : is_primes)
{
if (is_prime) primes.push_back(n);
n++;
}
return primes;
}
int main()
{
const prime_t max{ 50 };
auto primes = calculate_primes(max);
// max prime is last one in container
auto max_prime = primes.back();
std::cout << "maximum prime number smaller then " << max << ", is " << max_prime << std::endl;
}

Unable to find the error in the code I wrote for a question on loops in C++. Could anyone point it out?

a beginner at coding here.
I was practising loops(c++) when I stumbled upon this problem:-
Write a program in C++ to find the perfect numbers between 1 and 500. (6,28 and 496)
Perfect number: It is a positive integer that is equal to the sum of its proper divisors. The smallest perfect number is 6, which is the sum of 1, 2, and 3.
I wrote the following code:-
#include <iostream>
using namespace std;
int main() {
int n=2; //test numbers from 2 to 500.
int div=1; //divisor for n.
int sum=0; //sum of divisors which divide n.
while (n<=500) {
while (div<n){ //if div divides n, then it will added to sum and incremented, else only incremented.
if (n%div==0){
sum=sum+div;
div++;
} else{
div++;
}
}
if (sum==n){
cout<<n<<" is a perfect number."<<endl;
n++;
} else{
n++;
}
}
return 0;
}
The code is supposed to print that 6, 28 and 496 are perfect numbers.
But instead, it's not printing anything. Haven't been able to find the error yet after checking for 30+ minutes.
Could anyone point out the error?
You forget to re-initialize some variables in your loop.
for seems more appropriate than while here.
Create sub function also help to "identify" scope.
#include <iostream>
bool isPerfectNumber(int n)
{
int sum = 0;
for (int div = 1; div != n; ++div) {
if (n % div == 0) {
sum += div;
}
}
return sum == n && n > 0;
}
int main()
{
for (int i = 2; i != 501; ++i) {
if (isPerfectNumber(i)) {
std::cout << n << " is a perfect number." << std::endl;
}
}
return 0;
}
#include<iostream>
using namespace std;
bool perfect_num(int x);
int main() {
int m, n, x;
cout << "input the range m, n: " << "\n";
cin >> m >> n;
for (x = m; x <= n; ++x) {
if (perfect_num(x)) {
cout << x << " ";
}
}
return 0;
}
bool perfect_num(int x) {
bool flag = false;
//initialize
int sum = 0, i;
//loop 1 to x
for (i = 1; i < x; ++i) {
//judge whether is the factor
if (x % i == 0) {
sum += i;
}
}
//update flag
flag = (sum == x);
return flag;
}
#include<iostream>
using namespace std;
//judge function
bool isPerfectNum(int num){
int tmp = 0;
for (int i = 1; i < num; ++i) {
if (num % i == 0) {
tmp += i;
}
}
return tmp == num;
}
int main(){
cout << "Perfect Number contains: ";
for (int i = 1; i <= 500; ++i){
if (isPerfectNum(i)) {
cout << i << " ";
}
}
cout << "\n";
return 0;
}
at the end of your first loop, you should bring back div and sum to their default value.
int main() {
int n=2; //test numbers from 2 to 500.
int div=1; //divisor for n.
int sum=0; //sum of divisors which divide n.
while (n<=500) {
while (div<n){ //if div divides n, then it will added to sum and incremented, else only incremented.
if (n%div==0){
sum=sum+div;
div++;
} else{
div++;
}
}
if (sum==n){
cout<<n<<" is a perfect number."<<endl;
n++;
} else{
n++;
}
div = 1; // you should bring them back here.
sum = 0;
}
return 0;
}

Generate numbers from 2 to 10,000. The numbers printed can only be a multiple of 2 prime numbers

Homework: I'm just stumped as hell. I have algorithms set up, but I have no idea how to code this
Just to be clear you do not need arrays or to pass variables by reference.
The purpose of the project is to take a problem apart and using Top-Down_Design or scratch pad method develop the algorithm.
Problem:
Examine the numbers from 2 to 10000. Output the number if it is a Dual_Prime.
I will call a DualPrime a number that is the product of two primes. Ad where the two primes are not equal . So 9 is not a dual prime. 15 is ( 3 * 5 ) .
The output has 10 numbers on each line.
My Algorithm set-up
Step 1: find prime numbers.:
bool Prime_Number(int number)
{
for (int i = 2; i <= sqrt(number); i++)
{
if (number % 1 == 0)
return false;
}
return true;
}
Step 2: store prime numbers in a array
Step 3: Multiply each array to each other
void Multiply_Prime_Numbers(int Array[], int Size)
{
for (int j = 0; j < Size- 1; j++)
{
Dual_Prime[] = Arr[j] * Arr[j + 1]
}
}
Step 4: Bubble sort
void Bubble_Sort(int Array[], int Size) // Sends largest number to the right
{
for (int i = Size - 1; i > 0; i--)
for (int j = 0; j < i; j++)
if (Array[j] > Array[j + 1])
{
int Temp = Array[j + 1];
Array[j + 1] = Array[j];
Array[j] = Temp;
}
}
Step 5: Display New Array by rows of 10
void Print_Array(int Array[], int Size)
{
for (int i = 0; i < Size; i++)
{
cout << Dual_Prime[i] << (((j % 10) == 9) ? '\n' : '\t');
}
cout << endl;
}
I haven't learned dynamic arrays yet,
Although dynamic arrays and the sieve of Eratosthenes are more preferable, I tried to write minimally fixed version of your code.
First, we define following global variables which are used in your original implementation of Multiply_Prime_Numbers.
(Please check this post.)
constexpr int DP_Size_Max = 10000;
int DP_Size = 0;
int Dual_Prime[DP_Size_Max];
Next we fix Prime_Number as follows.
The condition number%1==0 in the original code is not appropriate:
bool Prime_Number(int number)
{
if(number<=1){
return false;
}
for (int i = 2; i*i <= number; i++)
{
if (number % i == 0)
return false;
}
return true;
}
In addition, Multiply_Prime_Numbers should be implemented by double for-loops as follows:
void Multiply_Prime_Numbers(int Array[], int Size)
{
for (int i = 0; i < Size; ++i)
{
for (int j = i+1; j < Size; ++j)
{
Dual_Prime[DP_Size] = Array[i]*Array[j];
if(Dual_Prime[DP_Size] >= DP_Size_Max){
return;
}
++DP_Size;
}
}
}
Then these functions work as follows.
Here's a DEMO of this minimally fixed version.
int main()
{
int prime_numbers[DP_Size_Max];
int size = 0;
for(int j=2; j<DP_Size_Max; ++j)
{
if(Prime_Number(j)){
prime_numbers[size]=j;
++size;
}
}
Multiply_Prime_Numbers(prime_numbers, size);
Bubble_Sort(Dual_Prime, DP_Size);
for(int i=0; i<DP_Size;++i){
std::cout << Dual_Prime[i] << (((i % 10) == 9) ? '\n' : '\t');;
}
std::cout << std::endl;
return 0;
}
The Sieve of Eratosthenes is a known algorithm which speeds up the search of all the primes up to a certain number.
The OP can use it to implement the first steps of their implementation, but they can also adapt it to avoid the sorting step.
Given the list of all primes (up to half the maximum number to examine):
Create an array of bool as big as the range of numbers to be examined.
Multiply each distinct couple of primes, using two nested loops.
If the product is less than 10000 (the maximum) set the corrisponding element of the array to true. Otherwise break out the inner loop.
Once finished, traverse the array and if the value is true, print the corresponding index.
Here there's a proof of concept (implemented without the OP's assignment restrictions).
// Ex10_TwoPrimes.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include "pch.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void Homework_Header(string Title);
void Do_Exercise();
void Sieve_Of_Eratosthenes(int n);
void Generate_Semi_Prime();
bool Semi_Prime(int candidate);
bool prime[5000 + 1];
int main()
{
Do_Exercise();
cin.get();
return 0;
}
void Do_Exercise()
{
int n = 5000;
Sieve_Of_Eratosthenes(n);
cout << endl;
Generate_Semi_Prime();
}
void Sieve_Of_Eratosthenes(int n)
{
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
memset(prime, true, sizeof(prime));
for (int p = 2; p*p <= n; p++)
{
// If prime[p] is not changed, then it is a prime
if (prime[p] == true)
{
// Update all multiples of p
for (int i = p * p; i <= n; i += p)
prime[i] = false;
}
}
}
bool Semi_Prime(int candidate)
{
for (int index = 2; index <= candidate / 2; index++)
{
if (prime[index])
{
if (candidate % index == 0)
{
int q = candidate / index;
if (prime[q] && q != index)
return true;
}
}
}
return false;
}
void Generate_Semi_Prime()
{
for (int i = 2; i <= 10000; i++)
if (Semi_Prime(i)) cout << i << "\t";
}

Matrix Traversal to print all and shortest path - infinite loop

#include<iostream>
#include<random>
#include<ctime>
#include<cstdlib>
#include<vector>
#include<algorithm>
using namespace std;
int path_checker(vector<pair<int,int> > path, int i, int j)
{
//cout<<"path_checker"<<endl;
std::vector<pair<int, int> >::iterator it;
for(it = path.begin(); it!=path.end();it++)
if(it->first == i && it->second ==j)
return 1;
return 0;
}
int isVertex(int i, int j, int n)
{
//cout<<"isVertex"<<endl;
if((i>=0) && (j>=0))
{
if((i <= n) && (j <= n))
return 1;
}
return 0;
}
void printAllPathsU(int *array, int i, int j, int n, vector<pair<int,int> > path,int index)
{
// cout<<"PrintAllPathsU_first"<<endl;
// vector<pair<int,int>> path2 = {0};
if((i == n) && (j == n))
{
if((path_checker(path,i,j)))
{
cout<<"Inside printing path"<<endl;
//vector<pair<int,int> >::iterator it;
for(int i = 0; i < path.size();i++)
cout<<"a["<<path[i].first<<"]["<<path[i].second<<"] ";
return;
}
else
{
path.push_back(make_pair(i,j));
cout<<"Inside printing path"<<endl;
//vector<pair<int,int> >::iterator it;
for(int i = 0; i < path.size();i++)
cout<<"a["<<path[i].first<<"]["<<path[i].second<<"] ";
return;
}
}
if((*((array+i*n)+j) == 1) && (!path_checker(path,i,j)))
{
//cout<<path.size()<<endl;
path.push_back(make_pair(i,j));
index++;
//len++;
if(isVertex(i,j-1,n))
printAllPathsU((int *)array,i,j-1,n,path,index);
if(isVertex(i-1,j,n))
printAllPathsU((int *)array,i-1,j,n,path,index);
if(isVertex(i,j+1,n))
printAllPathsU((int *)array,i,j+1,n,path,index);
if(isVertex(i+1,j,n))
printAllPathsU((int *)array,i+1,j,n,path,index);
}
else if((*((array+i*n)+j) == 1) && (path_checker(path,i,j)))
{
//cout<<"inside second else"<<endl;
return;
}
else if(*((array+i*n)+j) == 0)
{
// cout<<"inside third else"<<endl;
return;
}
}
void printAllPaths(int *array, int n)
{
vector<pair<int,int> > path;
//cout<<"PrintALLPaths"<<endl;
printAllPathsU(array, 0, 0, n, path, 0);
}
int main()
{ //populating matrix
int n;
cout << "Enter value of n (for n x n matrix): ";
cin >> n;
int i;
int j;
int k;
int test=1;
int array[n][n];
int randomval;
int total_elements = n*n;
int counter_0 = 0;
int max_0 = 0.2 * total_elements;
cout << "Number of zeros(20% of n*n) in matrix: ";
cout<<max_0<<endl;
int count=0;
srand(time(0));
for(i = 0;i < n;i++)
{
for(j = 0;j<n;j++)
{
array[i][j]=-1;
}
}
while(count < total_elements)
{
i=rand()%n;
j=rand()%n;
if(array[i][j]==1 || array[i][j]==0)
{
continue;
}
else if(array[i][j] == -1)
{
count+=1;
if(i==0 && j==0)
{
array[i][j]=1;
}
else if (counter_0 < max_0)
{
counter_0+=1;
array[i][j] = 0;
}
else if(counter_0 >= max_0)
{
test+=1;
array[i][j] = 1;
}
}
else{continue;}
}
cout<<"# of 1s:"<<test<<" & # of 0s:"<<counter_0<<endl;
cout<<"Elements Populated:"<<count<<endl;
cout<<"Total Elements in matrix:"<<total_elements<<endl;
if(counter_0 < max_0)
{ cout<<"adding more zeros"<<endl;
while(k < (max_0 - counter_0))
{
i = rand()%n;
j = rand()%n;
if(array[i][j] == 0)
{
}
else
{
array[i][j] = 0;
k+=1;
}
}
}
for(i = 0;i < n;i++)
{
for(j = 0;j<n;j++)
{
cout<<array[i][j]<<" ";
}
cout<<endl;
}
//printing paths
if(array[1][0]==0 && array[0][1]==0)
{
cout<<"No Possible paths homie #snorlaxiseverywhere";
}else
{
//printing paths
printAllPaths((int *)array, n);
}
return 0;
}
The question is to traverse through a n * n matrix populated with 1s and 0s, with the number of 0s in the matrix being 20% of the total number of elements, and print all paths and then the shortest path from the [0][0] to [n][n], using four direction: up,down,left and right.
So far I have tried to implement printing all possible paths. However, I am stuck in an infinite loop in the
else if((*((array+i*n)+j) == 1) && (!path_checker(path,i,j)))
{
...
}
I cout the path.size() to check what the size is becoming in each instance, and the output is somewhat like :
35
48
37
...and so on infinitely (values ranging approx between 30-50)
Any ideas how to correct this?
EDIT : Changed up some logic, not stuck infinite loop. But all of the function calls exit through the "second else" and the "third else" inside the function - printAllPathsU(...).
Thanks!
As long as the question is how to "print all paths", you should have an infinite loop because there are infinitely many paths. If the question is how to print all non-self-intersecting paths, then this rephrasing gives a hint on how to go about solving the problem.