I'm new to C++ and trying to make this piece of code work properly. It's a basic algorithm for
prime numbers. I make an array the size of which is defined by the user input. Then I need to print
only the max prime number from this array. How can I do that here?
unsigned long long nPrime(unsigned n) {
long long *a = new long long[n + 1];
long long maxNum = a[n];
for (int i = 0; i < n + 1; i++) {
a[i] = i;
}
for (int j = 2; j < n + 1; j++) {
if (a[j] != 0) {
for (int k = j * j; k < n + 1; k += j) {
a[k] = 0;
}
cout << a[j] << endl;
}
}
return 0;
}
You can find the biggest number in an array using std::max_element from <algorithm>:
return *std::max_element(a, a+n);
But this isn't even necessary. Since the biggest prime will be the last prime you found, just keep track of that:
int biggestPrime = 2;
And then, when you found a prime:
biggestPrime = j;
You can also replace your array of long long with an array of bool, since the index already keeps track of the number:
unsigned long long nPrime(unsigned n) {
bool *a = new bool[n + 1]();
long long maxNum = a[n];
int biggestPrime = 2;
for (int j = 2; j < n + 1; j++) {
if (!a[j]) {
for (int k = j * j; k < n + 1; k += j) {
a[k] = true;
}
biggestPrime = j;
}
}
delete[] a;
return biggestPrime;
}
And last but not least, don't forget to delete your dynamically allocated memory when you're done:
delete[] a;
As it seems you mark non-prime numbers with value 0 in the array. We know that primes are positive numbers, to simplify, let maxNum be -1. Then I added one for at the and of the function which will calculate the maximum prime value in the array. This is the one way to do :
unsigned long long nPrime(unsigned n) {
long long *a = new long long[n + 1];
long long maxNum = -1;
for (long long i = 0; i < n + 1; i++) {
a[i] = i;
}
for (long long i = 2; i < n + 1; i++) {
for (long long k = i * i; k < n + 1; k += i) {
a[k] = 0;
}
}
for (long long i = 1; i < n; i++) {
if (a[i] != 0 && maxNum < a[i]) maxNum = a[i];
}
return maxNum;
}
Also instead of last for you can use faster version. In this version you don't even need maxNum value : let's start from the end and first value which is non zero will be the answer:
for (long long i = n; i >= 2; i--) {
if (a[i] != 0) return a[i];
}
Related
So the problem asked me to find the greatest product from a given sequence of non-negative integers. What I did was I tried to find the greatest two integers from the sequence (for which I used a vector, by taking an input of n numbers) and multiplied them, since there are no negative integers. I used the long long type as well, since just an int type would not be enough for huge numbers. I kept getting a random huge number as the output whenever I tried to run the program :
#include <iostream>
#include <vector>
using namespace std;
long long max_prod(const vector<int>& numbers) {
int max1 = -1;
int max2 = -1;
int n = numbers.size();
for (int i = 0; i<n; i++){
if (numbers[i] > numbers[max1])
max1 = i;
}
for (int j = 0; j < n; j++) {
if (numbers[j] > numbers[max2] && j!=max1)
max2 = j;
}
return ((long long)(numbers[max1])) * ((long long)(numbers[max2]));
}
int main(){
int n;
cin >> n;
vector<int> numbers(n);
for (int i = 0; i<n; i++){
cin >> numbers[i];
}
long long result = max_prod(numbers);
cout << result << "\n";
return 0;
}
the last line is the output given by the program
You haver undefined behavior right here
long long max_prod(const vector<int>& numbers) {
int max1 = -1; <<<<<====
int max2 = -1;
int n = numbers.size();
for (int i = 0; i < n; i++) {
if (numbers[i] > numbers[max1]) <<<<<==
max1 = i;
}
for (int j = 0; j < n; j++) {
if (numbers[j] > numbers[max2] && j != max1)
max2 = j;
}
return ((long long)(numbers[max1])) * ((long long)(numbers[max2]));
}
You try to access numbers[-1] (twice once in the j loop and once in the i loop).
Set maxi and maxj to 0
I'm practicing myself by doing some leetcode questions, however, I don't know why that's an overflow problem right here. I knew the way I sum the subarray was terrible, any tips for the sum of the subarray?
and the run time for this code would be forever
#include <numeric>
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int size = arr.size();//5
int ans = 0;
int sumAll = 0;
int start = 3;
int tempsum;
for(int i =0; i< size; i++){ //sumitself
sumAll += arr[i];
}
ans = sumAll; //alreayd have the 1 index
if(size%2 == 0){//even number 6
int temp = size-1; //5
if(size == 2)
ans = sumAll;
else{
while(start <= temp){//3 < 5
for(int i = 0; i< size; i++){
for(int k =0; k< start; k++){//3
tempsum += arr[i+k];
if(i+k > temp) //reach 5
break;
}
}
start+=2;
}
}
ans+= tempsum;
}
else{//odd number
if(size == 1)
ans = sumAll;
else{
while(start < size){//3
for(int i = 0; i< size; i++){
for(int k =0; k< start; k++){//3
tempsum += arr[i+k];
if(i+k > size) //reach 5
break;
}
}
start+=2;
}
ans+= tempsum;
ans+= sumAll; //size index
}
}
return ans;
}
};
The problem is with arr[i+k]. The result of i + k can be equal to, or larger, than size. You check it after you have already gone out of bounds.
You should probably modify the inner loop condition so that never happens:
for(int k =0; k < start && (i + k) < size; k++){//3
Now you don't even need the inner check.
You can use prefix sum array technique and then for each index you can calculate the sub-array sum for each odd-length array using prefix sum array. I submitted the below solution in LeetCode and it beats runtime of 100% of submissions and memory usage of 56.95%
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int n = arr.size();
vector<int> prefix(n+1,0);
int sum = 0;
prefix[1] = arr[0];
for(int i=1;i<n;i++)
prefix[i+1]=(arr[i]+prefix[i]);
for(int i=0;i<n;i++)
{
for(int j=i;j<n;j+=2)
sum+=prefix[j+1]-prefix[i];
}
return sum;
}
};
https://leetcode.com/problems/sum-of-all-odd-length-subarrays/discuss/1263893/Java-100-one-pass-O(n)-with-explanation
class Solution {
public int sumOddLengthSubarrays(int[] arr) {
// alt solution: O(n)
//for each i:
// if(n -1 - i) is odd, then arr[i] is counted (n-1-i)/2 + 1 times, each from 0 to i, total ((n-i)/2+1)*(i+1) times
// if(n -1 - i) is even, then arr[i] is counted (n-1-i)/2 + 1 times, if starting subseq index diff with i is even;
// (n-1-i)/2 times, if starting index diff with i s odd, total (n-i)/2 *(i+1) + (i+1)/2
// if i is even i - 1, i - 3, .. 1, total (i -2)/2 + 1 = i / 2 = (i+1) / 2
// if i is odd i-1, i-3, .., 0 total (i-1)/2 + 1 = (i+1) / 2
int total = 0;
int n = arr.length;
for(int i = 0; i < n; i++)
total += (((n - 1 - i) / 2 + 1) * (i + 1) - ((n-i) % 2)*((i+1) / 2)) * arr[i];
return total;
}
}
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;
}
The following code is to find the Maximum Pairwise Product (MPP) which is:
You're given an array of N integers and a number K. The maximum
K-product of the array is the maximum product of any K length subsequence of the array. For example, the maximum 2-product of the array
[-5, 3, 4, -6] is 30 because the product of the subsequence [-5, -6]
is 30 and it is impossible to achieve a larger subsequence products.
The code below calculates the MPP for every input except for "90000 and 100000" which must give an output 9,000,000,000, but I got 410065408:
int MaxPairwiseProduct(const vector<int>& numbers) {
int result = 0;
int n = numbers.size();
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (numbers[i] * numbers[j] > result && numbers[i] * numbers[j] % 2 == 0) {
result = numbers[i] * numbers[j];
}
}
}
return result;
}
Sadly, these pages (1 and 2) did not help me with my request.
Because when you multiply your integer, it is outgoing of the int type boundaries. In this case, use the long long type:
long long MaxPairwiseProduct(const vector< long long >& numbers) {
long long result = 0;
int n = numbers.size();
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (numbers[i] * numbers[j] > result && numbers[i] * numbers[j] % 2 == 0) {
result = numbers[i] * numbers[j];
}
}
}
return result;
Please note that if your numbers are too big (bigger than 2^63-1) you can not use standard C++ types. There is all type boundaries C++ data types.
How do I solve following programming riddle in O(N)?
Array of integers: Tab[N]
Find max(Tab[K] - K + Tab[L] + L)
where 0 <= K <= L <= N
The only solution I can come up with is O(N^2) where I compare each element and update maximum sum.
int curr_max = INTEGER_MIN;
for(int i = 0; i < N; i++){
for(int j = i; j < N; j++){
curr_max = max(Tab[i]-i + Tab[j] + j,curr_max);
}
}
In general, a possible way to solve such kind of tasks, due to K<=L constraint, is to use pre-calculated running max. (The version below can be optimized, but anyway has O(N) time and space complexity.)
int t[N+1]; // input
int a[N+1]; // running max t[i]-i, left to right
a[0] = t[0]-0;
for (int i = 1; i <= N; ++i)
a[i] = max(a[i-1], t[i]-i);
int b[N+1]; // running max t[i]+i, right to left
b[N] = t[N]+N;
for (int i = N-1; i >= 0; --i)
b[i] = max(b[i+1], t[i]+i);
int mx = a[0] + b[0];
for (int i = 1; i <= N; ++i)
mx = max(mx, a[i] + b[i]);
However, in our case, it can be shown that if K: Tab[K]-K -> max and L: Tab[K]+K -> max then K<=L. In other words, if L and K are indices of the two maxima respectively, the property L<=K holds. Therefore, the naïve approach should work too:
int K = 0, L = 0;
for (int i = 1; i <= N; ++i) {
if (t[i]-i > t[K]-K)
K = i;
if (t[i]+i > t[L]+L)
L = i;
}
assert(K <= L);
int mx = t[K]-K + t[L]+L;
How about:
int L_max = INTEGER_MIN;
int K_max = INTEGER_MIN;
for(int i=0; i<N; i++)
{
K_max = max(Tab[i] -i, K_max);
L_max = max(Tab[i] +i, L_max);
}
curr_max = K_max + L_max;
Note that it does not validate K <= L, neither does the code in the question.