why my code is unable to handle large array input(>10000)? - c++

int n;//input size of array
cin >> n;
vector <int> a(n);
vector <int> in;
for (int i = 0; i < n; i++)
cin >> a[i];//input array elements
if (n == 1) {
cout << "1" << "\n";
return 0;
}
for (int i = 1; i <= n ; i++)//to get longest incresing subsequence in the array
{
int flag = 0, j = i;
while (j < n && a[j] >= a[j - 1] ) {
j++;
flag = 1;
}
if (flag == 1) {
in.push_back(j - i + 1);
i = j;
}
}
int maxval = in[0]; //to get maximum sized element from in
for (int i = 1; i < in.size(); i++)
if (in[i] > maxval)
maxval = in[i];
cout << maxval << "\n";
I tried the same code for values < 10000 it's working fine...i've replaced all int's by long long int's then also it's showing vector subscript out of range error...
Sample input :
10
49532 49472 49426 49362 49324 49247 49165 49162 49108 49093
i'm expecting 0 but it shows "vector subscript out of range"

The reason of the problem is this statement
int maxval = in[0];//to get maximum sized element from in
The vector in is empty when this input is used
10
49532 49472 49426 49362 49324 49247 49165 49162 49108 49093
So you may not use the subscript operator.
You could write for example
int maxval = in.empty() ? 0 : in[0];

Fix this:
int maxval = in.size()? in[0]:0;
the vector class operator checks the index is between lower and upper limit of array which will be (0 -> size-1)
MSVC lib:
_NODISCARD _Ty& operator[](const size_type _Pos) noexcept { // strengthened
auto& _My_data = _Mypair._Myval2;
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(
_Pos < static_cast<size_type>(_My_data._Mylast - _My_data._Myfirst), "vector subscript out of range");
#endif // _CONTAINER_DEBUG_LEVEL > 0
return _My_data._Myfirst[_Pos];
}
the problem is that the in.push_back never get called then the size is zero.
so in[0] call operator will throw exception index out range.

Related

Debug Assertion Fail (vector subscript out of range)

I found that my result.push_back(make_pair(a[i], b[j]));, which
causing this error but i dont know why (i don't even access vector<pair<int,int>>result;)
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<utility>
using namespace std;
void input(int n,vector<int>&a) {
int temps;
for (int i = 0; i < n; i++) {
cin >> temps;
a.push_back(temps);
}
}
int main() {
//input
long n, m;
cin >> n; //6
vector<int>a, b;
input(n, a); //{2 5 4 1 7 5}
cin >> m; //7
input(m, b); //{2 3 1 3 2 4 6}
//algorithm
long max = *max_element(a.begin(), a.end()) + *max_element(b.begin(), b.end());
long min = *min_element(a.begin(), a.end()) + *min_element(b.begin(), b.end());
vector<pair<int, int>>result;
int possible = max, plate = 0;
for (int check = max; check >= min; check--) {
int j = 0, i = 0, plate2 = 0;
for (; i < a.size(); i++) {
if (a[i] >= check) {}
else {
if (j > b.size() - 1) { break; }
if (a[i] + b[j] >= check) {
j++; plate2++;
result.push_back(make_pair(a[i], b[j]));
}
else {
i--; j++;
}
}
}
if (i > a.size() - 1) { possible = check; plate = plate2; break; }
}
cout << possible << " " << plate << endl; //5 3
return 0;
}
if you remove the line result.push_back(make_pair(a[i],b[j]);, there is no error message anymore, so i think i'm not access wrong a[i] and b[j] elements
if (j > b.size() - 1) { break; } //(1)
if (a[i] + b[j] >= check) { //(2)
j++; plate2++; // HERE IS YOUR PROBLEM (3)
result.push_back(make_pair(a[i], b[j])); //(4)
Assume that j == b.size()-1 at the beginning. The if (j > b.size() - 1) clause is false, so the loop does not break. It continues with (2), which is okay. In (3) you add +1 to j, so now j == b.size(). In (4) you try to access b[j], which is now b[b.size()], which is invalid, as indizes start at 0.
IOW: You tried to assure that j never points beyond the number of valid elements, but then you increment j after that test and access invalid memory.

Memory error in finding prime sum

Problem: Given an even number ( greater than 2 ), return two prime numbers whose sum will be equal to given number.
Solution: Using sieve of eratosthenes find all prime numbers upto given number. Then find the pair of numbers whose sum is equal to given number.
Code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
void primesum(int A)
{
std::vector<bool> primes(A + 1, 1);
std::vector<int> arr, final;
primes[0] = 0;
primes[1] = 0;
for (int i = 2; i <= int(sqrt(A)); i++)
{
if (primes[i] == 1)
{
for (int j = 2; i + j <= A; j++)
{
primes[i * j] = 0;
}
}
}
for (int i = 0; i < primes.size(); i++)
if (primes[i])
arr.push_back(i);
/* for (auto x : primes)
std::cout << x << " ";
std::cout << "\n"; */
std::vector<int>::iterator it;
for (int i = 0; i < arr.size(); i++)
{
it = std::find(arr.begin(), arr.end(), A - arr[i]);
if (it != arr.end())
{
final.push_back(arr[i]);
final.push_back(A - arr[i]);
break;
}
}
std::cout << final[0] << " " << final[1] << "\n";
return;
}
int main()
{
int x = 184;
primesum(x);
return 0;
}
This code is working for most of the cases except for case like when x=184. Error in this case is:
a.out: malloc.c:2394: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
[1] 13944 abort (core dumped) ./a.out
I'm not able to understand why this is happening and what's its solution?
Let x=184. Then primes.size() is 185. The first loop iterates till i=13. 13 is the prime number. The second loop iterates till j=171. In the loop you access primes[2223]. It is a write out of bounds, causes UB. As the result you get corrupted dynamic memory and the assertion.
It looks like you did a typo in the loop condition, you wanted i * j <= A.
With primes[i * j] = 0 you have invalid indices exceeding your vector size while finding the primes, that is the reason this code crashes. You can correct this to
for (int i = 2; i <= int(sqrt(A)); i++)
{
if (primes[i] == 1)
{
for (int j = 2; i * j <= A; j++)
{
primes[i * j] = 0;
}
}
}

Find Maximum Strength given number of elements to be skipped on left and right.Please Tell me why my code gives wrong output for certain test cases?

Given an array "s" of "n" items, you have for each item an left value "L[i]" and right value "R[i]" and its strength "S[i]",if you pick an element you can not pick L[i] elements on immediate left of it and R[i] on immediate right of it, find the maximum strength possible.
Example input:
5 //n
1 3 7 3 7 //strength
0 0 2 2 2 //Left Value
3 0 1 0 0 //Right Value
Output:
10
Code:
#include < bits / stdc++.h >
using namespace std;
unsigned long int getMax(int n, int * s, int * l, int * r) {
unsigned long int dyn[n + 1] = {};
dyn[1] = s[1];
for (int i = 2; i <= n; i++) {
dyn[i] = dyn[i - 1];
unsigned long int onInc = s[i];
int left = i - l[i] - 1;
if (left >= 1) {
unsigned int k = left;
while ((k > 0) && ((r[k] + k) >= i)) {
k--;
}
if (k != 0) {
if ((dyn[k] + s[i]) > dyn[i]) {
onInc = dyn[k] + s[i];
}
}
}
dyn[i] = (dyn[i] > onInc) ? dyn[i] : onInc;
}
return dyn[n];
}
int main() {
int n;
cin >> n;
int s[n + 1] = {}, l[n + 1] = {}, r[n + 1] = {};
for (int i = 1; i <= n; i++) {
cin >> s[i];
}
for (int i = 1; i <= n; i++) {
cin >> l[i];
}
for (int i = 1; i <= n; i++) {
cin >> r[i];
}
cout << getMax(n, s, l, r) << endl;
return 0;
}
Problem in your approach:
In your DP table, the information you are storing is about maximum possible so far. The information regarding whether the ith index has been considered is lost. You can consider taking strength at current index to extend previous indices only if any of the previously seen indices is either not in range or it is in range and has not been considered.
Solution:
Reconfigure your DP recurrence. Let DP[i] denote the maximum answer if ith index was considered. Now you will only need to extend those that satisfy range condition. The answer would be maximum value of all DP indices.
Code:
vector<long> DP(n,0);
DP[0]=strength[0]; // base condition
for(int i = 1; i < n ; i++){
DP[i] = strength[i];
for(int j = 0; j < i ; j++){
if(j >= (i-l[i]) || i <= (j+r[j])){ // can't extend
}
else{
DP[i]=max(DP[i],strength[i]+DP[j]); // extend to maximize result
}
}
}
long ans=*max_element(DP.begin(),DP.end());
Time Complexity: O(n^2)
Possible Optimizations:
There are better ways to calculate maximum values which you might want to look into. You can start by looking into Segment tree and Binary Indexed Trees.

Priority Queue using Heap

I have written this code after studying from Introduction to Algorithm. I am unable to find out what is the problem with the code. I have written the code for heapsort and it runs well. heap_extract_max() will return the maximum value. heap_increase_key() increase the priority of an element. Here I have written program for priority queue using singly linked list which runs well.
#include <iostream>
#include <vector>
#include <algorithm>
template<typename T>
void max_heapify(std::vector<T>& array, size_t index)
{
size_t largest;
size_t left = (2*index) + 1;
size_t right = left + 1;
if(left < array.size() && array[left] > array[index])
largest = left;
else
largest = index;
if(right < array.size() && array[right] > array[largest])
largest = right;
if(largest != index)
{
int tmp = array[index];
array[index] = array[largest];
array[largest] = tmp;
max_heapify(array, largest);
}
}
template<typename T>
void build_max_heap(std::vector<T>& array)
{
for(size_t i = (array.size()/2) - 1; i >= 0; i--)
max_heapify(array, i);
}
template<typename T>
T heap_maximum(std::vector<T>& array)
{
return array[0];
}
template<typename T>
T heap_extract_max(std::vector<T>& array)
{
if(array.size() < 0)
{
std::cerr << "Heap Underflow \n";
}
else
{
T max = array[0];
array[0] = array[array.size() - 1];
//array.size() = array.size() - 1;
max_heapify(array, 1);
return max;
}
}
template<typename T>
void heap_increase_key(std::vector<T>& array, size_t index, T value)
{
if(value < array[index])
{
std::cerr <<"New value is smaller than the current value\n";
return;
}
else
{
array[index] = value;
while(index > 0 && array[(index/2) - 1] < array[index])
{
std::swap(array[index], array[(index/2) - 1]);
index = (index/2) - 1;
}
}
}
template<typename T>
void max_heap_insert(std::vector<T>& array, T value)
{
array[array.size()] = -1;
heap_increase_key(array, array.size(), value);
}
int main()
{
std::vector<int> v({1, 2, 6, 3, 7});
build_max_heap(v);
std::cout << heap_extract_max(v)<<"\n";
for(size_t i = 0; i < v.size(); i++)
{
std::cout << v[i] << " ";
}
std::cout << "\n";
}
It is not showing any output. I am writing commands
$ g++ -std=c++11 priorityqueue.cpp -o priorityqueue
$ ./priorityqueue
Problem is with the below function what will be return for if case
because of that
Control may reach end of non-void function
template<typename T>
T heap_extract_max(std::vector<T>& array)
{
if(array.size() < 0)
{
std::cerr << "Heap Underflow \n";
}
else
{
T max = array[0];
array[0] = array[array.size() - 1];
//array.size() = array.size() - 1;
max_heapify(array, 1);
return max;
}
}
Add return -1 or anything else for if case
if(array.size() < 0)
{
std::cerr << "Heap Underflow \n";
return -1;
}
second problem
for(size_t i = (array.size()/2) - 1; i >= 0; i--)
Comparison of unsigned expression >= 0 is always true
Try changing to:(as suggested by Serge Rogatch)
for(int64_t i = (int64_t(array.size())/2) - 1; i >= 0; i--)
As well as there is problem with extracting it
Before change result was
7
2 3 6 1 2
Program ended with exit code: 0
Because of wrong handling of remove .Handled removed properly in below code
template<typename T>
T heap_extract_max(std::vector<T>& array)
{
if(array.size() < 0)
{
std::cerr << "Heap Underflow \n";
return -1;
}
else
{
T max = array[0];
array[0] = array[array.size() - 1];
array.erase(std::remove(array.begin(), array.end(), array[0]),
array.end());
array.shrink_to_fit();
max_heapify(array, 0);
return max;
}
}
After change
7
6 3 1 2
Program ended with exit code: 0
It seems your program enters an infinite loop or crashes. I see a problem here:
for(size_t i = (array.size()/2) - 1; i >= 0; i--)
Because i is unsigned, it is always i >= 0. Also, for array.size() <= 1, you initialize it with some large positive integer, because i tries to go negative, but size_t is never negative, so the number wraps.
Try changing to:
for(int64_t i = (int64_t(array.size())/2) - 1; i >= 0; i--)
Also you seem to confuse 0- and 1-based array indexing, and you should do array.pop_back() in place of //array.size() = array.size() - 1;. Furthermore, it seems you intended array[1] instead of array[0] here:
T max = array[0];
array[0] = array[array.size() - 1];
If you stick with 1-based indexing, you should place and keep a dummy element at index 0 in your array:
std::vector<int> v({/*dummy*/-1, 1, 2, 6, 3, 7});
Array size is never negative, so you don't need if(array.size() < 0) and what's in then clause.
Though 0-based indexing is more natural in C++ and heap can be implemented with it too. For this you would need to revise all the index arithmetic like:
size_t left = (2*index) + 1;
size_t right = left + 1;
and
array[(index/2) - 1]

C/C++ How can I get unique value from 2 arrays?

I need to get the unique value from 2 int arrays
Duplicate is allowed
There is just one unique value
like :
int arr1[3]={1,2,3};
int arr2[3]={2,2,3};
and the value i want to get is :
int unique[]={1}
how can i do this?
im already confused in my 'for' and 'if'
this was not homework
i know how to merge 2 arrays and del duplicate values
but i alse need to know which array have the unique value
plz help me :)
and here is some code i did
int arr1[3]={1,2,3}
int arr2[3]={2,2,3}
int arrunique[1];
bool unique = true;
for (int i=0;i!=3;i++)
{
for (int j=0;j!=3;j++)
{
if(arr1[i]==arr2[j])
{
unique=false;
continue;
}
else
{
unique=true;
}
if(unique)
{
arrunique[0]=arr1[i]
break;
}
}
cout << arrunique[0];
Assuming:
You have two arrays of different length,
The arrays are sorted
The arrays can have duplicate values in them
You want to get the list of values that only appear in one of the arrays
including their duplicates if present
You can do (untested):
// Assuming arr1[], arr2[], and lengths as arr1_length
int i = 0,j = 0, k = 0;
int unique[arr1_length + arr2_length];
while(i < arr1_length && j < arr2_length) {
if(arr1[i] == arr2[j]) {
// skip all occurrences of this number in both lists
int temp = arr1[i];
while(i < arr1_length && arr1[i] == temp) i++;
while(j < arr2_length && arr2[j] == temp) j++;
} else if(arr1[i] > arr2[j]) {
// the lower number only occurs in arr2
unique[k++] = arr2[j++];
} else if(arr2[j] > arr1[i]) {
// the lower number only occurs in arr1
unique[k++] = arr1[i++];
}
}
while(i < arr1_length) {
// if there are numbers still to read in arr1, they're all unique
unique[k++] = arr1[i++];
}
while(j < arr2_length) {
// if there are numbers still to read in arr2, they're all unique
unique[k++] = arr2[j++];
}
Some alternatives:
If you don't want the duplicates in the unique array, then you can skip all occurrences of this number in the relevant list when you assign to the unique array.
If you want to record the position instead of the values, then maintain two arrays of "unique positions" (one for each input array) and assign the value of i or j to the corresponding array as appropriate.
If there's only one unique value, change the assignments into the unique array to return.
Depending on your needs, you might also want to look at set_symmetric_difference() function of the standard library. However, its treatment of duplicate values makes its use a bit tricky, to say the least.
#include <stdio.h>
#include <stdlib.h>
int cmp ( const void *a , const void *b )
{
return *(int *)a - *(int *)b;
}
int main()
{
int arr1[5] = {5,4,6,3,1};
int arr2[3] = {5, 8, 9};
int unique[8];
qsort(arr1,5,sizeof(arr1[0]),cmp);
printf("\n");
qsort(arr2,3,sizeof(arr2[0]),cmp);
//printf("%d", arr1[0]);
int i = 0;
int k = 0;
int j = -1;
while (i < 5 && k < 3)
{
if(arr1[i] < arr2[k])
{
unique[++j] = arr1[i];
i++;
}
else if (arr1[i] > arr2[k])
{
unique[++j] = arr2[k];
k++;
}
else
{
i++;
k++;
}
}
//int len = j;
int t = 0;
if(i == 5)
{
for(t = k; t < 3; t++)
unique[++j] = arr2[t];
}
else
for(t = i; t < 5; t++)
unique[++j] = arr2[t];
for(i = 0; i <= j; i++)
printf("%d ", unique[i]);
return 0;
}
This is my codes,though there is a good answer .
I didn't realize the idea that know which array have the unique value.
I also think that the right answer that you chose didn't , either.
Here is my version of the algorithm for finding identical elements in sorted arrays on Python in C ++, it works in a similar way
def unique_array(array0 : (int), array1 : (int)) -> (int):
index0, index1, buffer = 0, 0, []
while index0 != len(array0) and index1 != len(array1):
if array0[index0] < array1[index1]:
buffer.append(array0[index0])
index0 += 1
elif array0[index0] > array1[index1]:
buffer.append(array1[index1])
index1 += 1
else:
index0 += 1; index1 += 1
buffer.extend(array0[index0 : len(array0)])
buffer.extend(array1[index1 : len(array1)])
return buffer