ERROR: AddressSanitizer: negative-size-param: (size=-4) - c++

Trying to write some code, and erase() is giving me a runtime error. What's wrong with the way I used erase?
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
int size = nums.size();
vector<int> list;
for(int i = 1; i <= size; i++)
list.push_back(i);
for(int i = 0; i < size; i++) {
int num = nums[i];
list[num - 1] = 0;
}
for(int i = 0; i < size; i++) {
if(list[i] == 0) {
list.erase(list.begin() + i);
}
}
return list;
}
};
Here's the problem I am trying to solve
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.
Example:
Input:
[4,3,2,7,8,2,3,1]
Output:
[5,6]

Since all the non solutions were marked 0, you can remove all 0's in the vector using list.erase( remove (list.begin(), list.end(), 0), list.end() );

My first suggestion, concentrate on this:
for(int i = 0; i < size; i++) {
if(list[i] == 0) {
list.erase(list.begin() + i);
}
}
You are removing elements from list which changes the size. This will lead to accessing elements beyond your list.

Related

How to switch C++ array elements positions based on specified conditions?

I'm having a little problem with getting my head around this homework task. The task says: "Write a function called MoveSmallest that moves all the minimal integer elements at the start of the array. All the remaining items must stay at their places. (the array and its size are parameters)
Example: the array: 2, 3, 5, 1, 2, 3, 6, 4, 2, 1, 1 changes into 1, 1, 1, 2, 3, 5, 2, 3, 6, 4, 2
void MoveSmallest(int A[],int n)
{
int Min;
for(int i=0;i<n;i++)
{
if(i==0)
{
Min=A[i];
}
else if(A[i]<=Min)
{
Min=A[i];
}
}
So far I've only figured to check which one is the smallest element of the array. I don't have any ideas what to do next.
Once you have found the minimum value, all there is left to do is moving things around in order to have the minimum values at the beginning of the array.
You can do this by permuting the values until you have arrived to the "left" of the array (i.e index 0).
void MoveSmallest(int A[],int n)
{
int Min;
for(int i=0;i<n;i++)
{
if(i==0)
{
Min=A[i];
}
else if(A[i]<=Min)
{
Min=A[i];
}
}
for(int i = 0; i < n; i++)
{
if(A[i] == Min)
{
for(int j = i; j > 0; j--)
{
int tmp = A[j];
A[j] = A[j-1];
A[j-1] = tmp;
}
}
}
}
You could also use std::swap to do the permutation, instead of the temporary variable tmp.
Starting from the end of the array, keep track of how many minimal elements you have encountered. Then whenever you encounter a non-minimum element, move it to the right the number of minimal elements you have encountered so far:
void MoveSmallest(int A[], int n)
{
int min;
//Find min logic
//shift non-min elements and count min elements
int cnt = 0;
for (int i = n-1; i >=0; --i)
{
if (A[i] == min)
cnt++;
else
A[i+cnt] = A[i];
}
//Add min elements
for (int i = 0; i < cnt; ++i)
A[i] = min;
}
This will run in O(n) time and O(1) space.
Since your posts mention "basic C++" but not mention what is "basic", here is another solution. This is under the assumption that creating arrays for "work" purposes is considered "basic C++".
void MoveSmallest(int A[], int n)
{
// get the minimum value
int Min = A[0];
for (int i = 1; i < n; ++i)
{
if (A[i] < Min)
Min = A[i];
}
// get the count of the number of minimum values
int minCount = 0;
for (int i = 0; i < n; ++i)
{
if (A[i] == Min)
++minCount;
}
if (minCount > 0)
{
// create a work array and fill in the first
// minCount values with the minimum value
int *B = new int[n];
for (int i = 0; i < minCount; ++i)
B[i] = Min;
// now fill in the rest of the work array with the values
// in the A[] array that are not equal to Min
int current_pos = minCount;
for (int i = 0; i < n; ++i)
{
if (A[i] != Min)
B[current_pos++] = A[i];
}
// Now copy work array back to A array
for (int i = 0; i < n; ++i)
A[i] = B[i];
// get rid of work array
delete[] B;
}
}
Live Example
This runs in linear time O(n), as opposed to quadratic time O(n*n).
The disadvantage of course is that you need room for the work array, so the memory cost is linear O(n).

Delete duplicates from array C++

I am trying to create a simple program which calls on 2 functions. The first function takes a partially filled array, loops through it and deletes any duplicate values. When a value is deleted from the array, the remaining numbers are moved backwards to fill the gap i.e. when the function is finished, all null values of the array will be together at the end.
The second function prints the updated array.
My current code is below. At present when I run my code, the console shows:
2 6 0 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460. It should be showing: 1 2 5 6 if it worked correctly.
Also, I am not sure how to move the remaining elements of the array backwards so that the null values will be together at the end.
#include "pch.h"
#include <iostream>
using namespace std;
void deleteRepeats(int *arr, int arraySize, int& posUsed);
void printArray(int *arr, int arraySize);
int main()
{
int arr[10] = { 1, 2, 2, 5, 6, 1};
int posUsed = 6;
int arraySize = 10;
deleteRepeats(arr, arraySize, posUsed);
printArray(arr, arraySize);
return 0;
}
void deleteRepeats(int *arr, int arraySize, int& posUsed)
{
{
for (int i = 0; i < arraySize; i++)
{
for (int j = i; j < arraySize; j++)
{
if (arr[i] == arr[j])
{
for (int k = j; k < arraySize; k++)
{
arr[k] = arr[k + 1];
}
posUsed--;
}
else
j++;
}
}
}
}
void printArray(int *arr, int arraySize)
{
for (int i = 0; i < arraySize; i++)
{
cout << arr[i] << " ";
}
}
I would let the std containers to what you like to do.
Sort the vector
Use erase and unique to delete duplicates.
Here is the code
#include <vector>
#include <iostream>
#include <algorithm>
void print(const std::vector<int> &arr){
for (const auto & i : arr){
std::cout << i <<" ";
}
std::cout <<"\n";
}
int main() {
std::vector<int> arr{1, 2, 2, 5, 6, 1};
print(arr);
std::sort( arr.begin(), arr.end() );
arr.erase( std::unique( arr.begin(), arr.end() ), arr.end() );
print(arr);
}
Ps. Using int *arr, int arraySize is not very C++ like. Please always try to use a proper container (which almost always will be std::vector).
EDIT:
I changed my answer a bit, because I found this speed comparison (and actuallty the whole question answered).
What's the most efficient way to erase duplicates and sort a vector?
Given your assignment constraints (more C-like, than idiomatic C++), you can rewrite your function like this, to make it work:
void deleteRepeats(int *arr, int arraySize, int& posUsed)
{
for (int i = 0; i < posUsed; ++i)
{
int duplicates = 0;
int j = i + 1;
// find the first duplicate, if exists
for ( ; j < posUsed; ++j)
{
if ( arr[i] == arr[j] ) {
++duplicates;
break;
}
}
// overwrite the duplicated values moving the rest of the elements...
for (int k = j + 1; k < posUsed; ++k)
{
if (arr[i] != arr[k])
{
arr[j] = arr[k];
++j;
}
// ...but skip other duplicates
else
{
++duplicates;
}
}
posUsed -= duplicates;
}
// clean up (could be limited to the duplicates only)
for (int i = posUsed; i < arraySize; ++i)
arr[i] = 0;
}
It might be easier to imagine the algorithm having separate input and output arrays. Then, in pseudo-code:
for i = 0 to input_array_size-1
Is input[i] equal to input[j] for any j between 0 and i-1?
Yes - do nothing
No - copy input[i] to output
To implement this with shared input and output, you need to have two array sizes, input_array_size and output_array_size. Then, the pseudo-code becomes
output_array_size = 0
for i = 0 to input_array_size-1
Is array[i] equal to array[j] for any j between 0 and output_array_size-1?
Yes - do nothing
No:
copy array[i] to array[output_array_size]
Increase output_array_size
Note: it writes output where the input once was, so the check for duplicates should look at all elements that were output. For example, if your array is 1, 2, 1, 3, 5, 6, 3, then for the last 3 the accumulated output is 1, 2, 3, 5, 6, and the code should compare all these with the current element.
To simplify debugging, where it says "do nothing", you can set current element to -1. This way, if you print your array during execution (for debugging), it will be clearer which elements were removed.
there are only two changes made as you can see
1: you were traversing the whole array as you have declared a posUsed=6 variable which is because there are only 6 elements so in in loops you need to traverse in array upto posUsed index like i<posUsed j<posUsed k<posUsed
2: the second changes is in j loop j=i+1 because you don't need to compare the element of any index with element of the same index you have to compare it with elements after that index. if you compare it with same element it will be same and the program will delete that same element which results in ERROR.
onw more thing is that we don't traverse after posUsed index because after that the array is already empty/zero or null whatever you call it
and if you want to display just the non duplicated elements and not the zero's at the end of the array just add if(arr[i]==0) return; in the printArray function loop before cout statement
void deleteRepeats(int *arr, int arraySize, int& posUsed)
{
{
for (int i = 0; i < posUsed; i++)
{
for (int j = i+1; j < posUsed; j++)
{
if (arr[i] == arr[j])
{
for (int k = j; k < posUsed; k++)
{
arr[k] = arr[k + 1];
}
}
}
}
}
}
using two pointers
and if the array sorted
int removeDuplicates(vector<int>& nums) {
if(nums.size() == 0) return 0;
int i = 0;
for(int j = 1; j < nums.size(); j++)
if(nums[j] != nums[i]) nums[++i] = nums[j];
// return new array length
return i + 1;
}
//input: [1, 1, 2, 1] (arr1)
//output: 2 (returned length)
// print unique element
for(int i = 0; i < output; i++) cout << arr1[i] << '\n';
// [1, 2]
time complexity: O(N/2) -> O(N)
space complexity: O(1)
Removing duplicate elements from an unsorted array by O(n^2) complexity.
for (i = 1; i < vec.size(); i++)
{
for (j = 0; j < i; j++)
{
if (vec[i] == vec[j])
{
vec[i] = -1; //Every duplicate element will replace by -1
}
}
}
for (i = 0; i < vec.size(); i++)
{
if (vec[i] != -1)
{
copy.push_back(vec[i]);
/*if you are using an array then store this value into a new array.
first, declare a new array. The new array size will be equal to the
previous array. Like this :
int newArr[sizeOfPreviousArrary];
int j = 0;
newArr[j] = arr[i];
j++;
*/
}
}
Removing duplicate elements from an sorted array by O(n) complexity.
for (i = 0; i < n; i++)
{
if (arr[i] != arr[i+1]){
vec.push_back(arr[i]);
/*if you are using an array then store this value into a new array.
first, declare a new array. The new array size will be equal to the
previous array. Like this :
int newArr[sizeOfPreviousArrary];
int j = 0;
newArr[j] = arr[i];
j++;
*/
}
}
Use map or set for deleting duplicates
void removeDuplicates(int arr[], int n)
{
int i;
// Initialise a set
// to store the array values
set<int> s;
// Insert the array elements
// into the set
for (i = 0; i < n; i++) {
// insert into set
s.insert(arr[i]);
}
set<int>::iterator it;
// Print the array with duplicates removed
cout << "\nAfter removing duplicates:\n";
for (it = s.begin(); it != s.end(); ++it)
cout << *it << ", ";
cout << '\n';
}

Getting segmentation fault (vector declaration)

Find out the maximum sub-array of non negative numbers from an array.
The sub-array should be continuous. That is, a sub-array created by choosing the second and fourth element and skipping the third element is invalid.
Maximum sub-array is defined in terms of the sum of the elements in the sub-array. Sub-array A is greater than sub-array B if sum(A) > sum(B).
This is my solution:
vector<int> Solution::maxset(vector<int> &A) {
// Do not write main() function.
// Do not read input, instead use the arguments to the function.
// Do not print the output, instead return values as specified
// Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details
vector <int> bla;
int sum[100]={0};
int k = 0;
int j = 1;
for (int i =0; i < A.size(); i++){
if (A[i] > -1){
sum[k] = A[i] + sum[k];
}
else {
k++;
}
}
cout<<sum[0]<<" ";
cout<<sum[1]<<" ";
cout << sum[2] << " ";
int s = 0;
for (int i =0; i< 100; i++){
if (s < sum[i]){
s = sum[i];
k = i;
}
}
cout << s;
int count = 0;
for (int i =0; i < A.size(); i++){
if (A[i] < 0) {
count ++;
}
if (count == k) {
int j = i+1;
int x = 0;
while (A[j] > 0 && j< (A.size()-1)) {
// bla[x] = A[j];
x++;
j++;
}
}
}
return bla;
}
If I uncomment the line bla[x] = A[j], I get segmentation error. Can someone explain how to undetstand this error? I read it somewhere that there is not enough space in stack. I do not understand how.
Thank you
You can pass the size to a vector object or you can call it's default constructor which creates a vector object with 0 size.
std::vector<int> vecInt(10);
for(int i(0); i < vecInt.size(); i++)
vecInt[i] = i;
Or you can declare a vector with size 0:
std::vector<int> vecInt;
vecInt[0] = 10; // segfault
Because you try to store values in an un-allocated space.
To solve such problem use push_back to store and pop to clear:
So your example can be like this:
while (A[j] > 0 || j< (A.size()-1)) {
// bla[x] = A[j];
bla.push_back(A[j]);
x++;
j++;
}

Finding the Kth Smallest Element in an unsorted vector (Iteratively)

I'm trying to make a code that returns the kth smallest element in a vector.
For example:
Lets say you have a vector rand which contains elements {0, 3, 2, 5}
And the user inputs 2 as a value for K.
The function should then return element 2 from the vector since it is the 2nd (kth) smallest element in the vector.
so far this is my code:
int iterative_kth_element(vector<int>& vec, size_t k)
{
int index = 0;
int min = vec[0];
for(int i = k;i<vec.size();i--) {
for (int j = 1; j < vec.size();j++) {
if ( min > vec[j] ) {
min = vec[j];
index = i;
}
vec.erase(vec.begin() + index);
if (i == 1) {
return min;
}
}
}
}
it keeps returning some huge number that is not even in the vector.
for(int i = k;i<vec.size();i--)
doesn't seem right, assuming that k is always < vec.size(), then condition i<vec.size() is completely useless here. Instead you might rather add:
for(int i = k; i > 0; i--)
And nested loop should actually check all elements, therefore it should start at 0 (it skips first element):
for (int j = 0; j < vec.size(); j++) {
^
And I believe that
index = i;
was meant to be:
index = j;
And make sure all possible paths of execution return some value, pay attention to warnings the compiler gives you. Put one more return statement at the end of function:
return min;
BUT your main problems are:
you should update min before the nested loop starts the execution
the scope of nested loop shouldn't contain the erase call
Try:
int foo(std::vector<int>& vec, const size_t k)
{
int index = 0;
int min = -1;
for(size_t i = 0; i < k; ++i) {
if (vec.empty()) return min;
min = vec[0];
for (size_t j = 0; j < vec.size(); ++j) {
if (vec[j] < min) {
min = vec[j];
index = j;
}
}
vec.erase(vec.begin() + index);
}
return min;
}
int main() {
int a[] = {0, 3, 2, 5};
std::vector<int> v(a, a+4);
std::cout << foo(v, 2);
}
Start here: http://en.wikipedia.org/wiki/Selection_algorithm
int iterative_kth_element(vector<int>& vec, size_t k)
{
int minIndex, minValue;
for (int i = 0; i < k; i++)
{
minIndex = i;
minValue = vec[i];
for (int j = i+1; j < n; j++)
{
if (vec[j] < minValue)
{
minIndex = j;
minValue = vec[j];
}
}
int tmp = vec[i];
vec[i] = vec[minIndex];
vec[minIndex] = tmp;
}
return vec[k];
}
1/ you have a vector but you almost use it only as an array
2/ consider using an iterator.
3/ you are receiving the vector as a reference, which means modifications on it such as erasing an element is effective out of the scope of the method, do you really want to do that?
Here is some incomplete code for my solution. It only takes 1 pass over the vector. This will run in linear time with respect to vec. Hopefully it clears things up. My previous text is kind of wordy. I left it below this source though.
int iterative_kth_element(vector<int>& vec, size_t k)
{
int mins[k];
//assume first k elements are min
for(int i=0; i<k; i++)
{
mins[i] = vec[i];
}
//TODO:
//sort mins array here
//bubble sort is okay if k is small, or pivot
for(int i=k; i < vec.size(); i++)
{
//since mins is sorted, mins[k-1] is the highest value
if(vec[i] < mins[k-1])
{
mins[k-1] = vec[i];
}
//TODO:
//sort mins array here
//you could do a slick bubble sort starting from
//the back of mins until you find the location
//for the new min item
}
return mins[k-1];
}
//previous text
If you're finding a the kth smallest item. You should initialize an array with the first k item. Or store the indexes into vec where the smallest items are found.(would start with 0,1,2,3,...,k)
int index = 0;
int min = vec[0];
should be
int* mins = new int[k];
for(int i=0; i < k; i++) {
mins[i] = vec[i];
}
I would also recommend keeping this array of k smallest integers sorted. If you know where the largest item is, you only have to check each element in vec against the largest item in mins. You'll need a sort method though, which will be called everytime you find something smaller than one of your mins.
After one iteration of vec, you should have the k smallest items in that array. Just return the largest item. Stored at location 0 or k-1 in your array.
Something else to note: If k is greater than vec.size() / 2, you should look for the (vec.size() - k) largest item.
This should be log(k*n) time with a maximum memory footprint of 1.5n(the case where k is exactly vec.size()/2 is the worst case).
where n is the size of vec and k is the parm in the function.(k's upper limit is n/2 if you implement that note).
Worst case scenario is getting a list of numbers in descending order with k being half the size of n.
The array of integer numbers is set.
To delete from the array all positive elements, which allocated
between maximal and minimal elements.
To calculate the sum of negative cells of array.
To calculate the minimum of prime elements

How do I implement this bubble sort differently?

I'm looking to implement a bubble sort. I have the following code that I wrote, which uses a for loop inside of a do loop. How can I make this into a bubble sort that uses two for loops?
Here's my code:
do {
switched = false;
for (int i = 1; i < size; i++) {
if (a[i] < a[i-1]) {
int temp = a[i];
a[i] = a[i-1];
a[i-1] = temp;
switched = true;
}
}
} while (switched);
(This is tagged homework, but this is studying for the final exam, not actual homework.)
Because you know the last element in the list will always be sorted (since it bubbled up to the top) you can stop there.
for(int x = size; x >= 0; x--) {
bool switched = false;
for(int i = 1; i < x; i++) {
if(blah) {
// swap code here
switched = true;
}
}
if(!switched) break; // not the biggest fan of this but it gets the job done
}
A bit obligate, but hey, you asked for it:
for(bool switched=true; switched;)
{
switched = false;
for (int i = 1; i < size; i++) {
if (a[i] < a[i-1]) {
int temp = a[i];
a[i] = a[i-1];
a[i-1] = temp;
switched = true;
}
}
}
Two for loops...
Since the maximum number of times your inner loop will run is size times, you know that the outer loop only can be bound by size.
for (int x = 0; x < size; x++ )
{
switched = false;
for (int i = 1; i < size; i++)
{
if (a[i] < a[i - 1])
{
int temp = a[i];
a[i] = a[i - 1];
a[i - 1] = temp;
switched = true;
}
}
if(switched)
{
break;
}
}
A simple improvement to bubble sort is to remember the last location where a swap occurred. After each pass the elements beyond that point are sorted. Next time through the loop only iterate up to the previous high water mark.
void bubble_sort(int *arr, int size)
{
for (int hwm; size > 1; size = hwm)
{
hwm = 0;
for (int i = 1; i < size; ++i)
{
if (arr[i] < arr[i-1])
{
std::swap(arr[i], arr[i-1]);
hwm = i;
}
}
}
}
You can run the inside loop size times instead of checking switched, by having an outer loop for(int j=0; j<size; ++j). To make it slightly less badly inefficient you can make the inner loop 1 step shorter each time.
The first full pass through the loop (that is, the first iteration of your outer do loop) is guaranteed to put the largest element in position a[size - 1]. (Do you see why?) The next full pass is guaranteed not to change that, and, in addition, to put the second-largest element in position a[size - 2]. (Again, do you see why?) And so on. So the first pass needs i to go from 1 to size - 1, but the second only needs i to go from 1 to size - 2, the third only needs i to go from 1 to size - 3, and so on. Overall, you need at most size - 1 passes (with the last pass just covering position 1 and comparing a[1] to a[0] to make sure the smallest element is in place).
So, your outer for-loop needs to vary max_i, initially set to size - 1 and ending up at 1, and your inner for-loop needs to vary i from 1 to max_i.
Think about the maximum number of times the do loop can execute.
A really silly method to use two for loops would be as follows:
for(bool switched=true;switched;)
{
switched=false;
for(int i=1; i<size; ++i)
{
if (a[i] < a[i-1])
{
int temp = a[i];
a[i] = a[i-1];
a[i-1] = temp;
switched = true;
}
}
}
A more serious answer might be as below... but now that I think about it this probably is not bubble sort:
for(int i=0; i<(size-1); ++i)
{
for(int j=(i+1); j<(size-1); ++j)
{
if(a[i]>a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}