Getting segmentation fault (vector declaration) - c++

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++;
}

Related

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';
}

How to pass and return 2d array to a function

I'm trying to change a 2D array values in different function so it suits my need.
For an example in the code below I'm trying to change the Matrix to reflexive by changing the to "1" .
I have an issue returning the new array and replace it with the old one in the main program so I can use it again.
int reflexive(int m, int n, int matrix[100][100])
{
for(int i = 1;i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
if(i == j)
{
if(matrix[i][j] != 1)
matrix[i][j] = 1;
}
return matrix;
}
}
}
int main()
{
int matrix[100][100];
int m , n;
for(int i = 1;i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
cin>>matrix[i][j];
}
}
matrix[m][n] = reflexive(m,n,matrix);
return 0;
}
I want to fix this code so it can return the full new 2D array to the main program.
In your function reflexive the return statement is inside the loop. This causes that the function is terminated immediately when the return statement is reached. If you would proper format your code you would be able to see this behavior easily.
Further note, that the first element in an array has the index 0 and the index of the last element is the the size of the array -1. This is, because the array index is the element "offset". This means that
a[i]
and
*(a + i)
access the same array element.
for(int i = 1;i <= m; i++) // <--- should be for(int i=0; i<m; i++)
{
for(int j = 1; j <= n; j++) // <--- should be for(int j=0; j<n; j++)
{
if(i == j)
{
if(matrix[i][j] != 1)
matrix[i][j] = 1;
}
return matrix; // <--- here the function is terminated
}
}
An array is passed to a function by a pointer and not by value. This means if a formal parameter of a function is an array, then not all the values of the actual parameter are copied to the array. There is only passed a pointer to the values of the paramter to the function.
Because of that you do not need any return value in your case.
The following code should do what you want:
int reflexive(int m, int n, int matrix[100][100])
{
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
if(i == j)
{
if(matrix[i][j] != 1)
matrix[i][j] = 1; // <----- write to the data by pointer
}
}
}
}
int main()
{
int matrix[100][100];
......
reflexive(m,n,matrix);
......
}
Use vector<vector<int>> and pass it by reference
Using an array here is tedious and error-prone. Therefore:
#include <vector>
std::vector<std::vector<int> > reflexive(std::vector<std::vector<int> > matrix)
{
for(int i = 0; i < matrix.size; i++){
for(int j = 0; j < matrix[i].size; j++){
....
int main()
{
std::vector<std::vector<int> > matrix(100, std::vector<int>(100));
int m , n; //<<whereever they come from I guess? Saw no cin in your code. Have no set value right now.
for(int i = 0; i < m; i++)
{
for(int j =0; j < n; j++)
{
cin>>matrix[i][j];
}
}
}
or
#include<array>
...
std::array<std::array<int, 100>, 100> matrix;
std::array is of fixed size, std::vector is dynamic. Also learn about std::list while you're at it.
In any case, you should find a basic tutorial that talks about them and read all of it. Important standards.
That said, especially if you want to use dynamic sized arrays, you have no guarantee that every sub-array is of the same size ("a jagged 2d array), which is somehwat okay in a small program but should be avoided in the big picture, by using a class that ensures this property.
In the case of a matrix, one easy option is to use a library that deals with matrices, like for example Eigen.
edit:
If at some point you need the code above in const-correct:
std::vector<std::vector<int> > reflexive(const std::vector<std::vector<int> >& input)
{
std::vector<std::vector<int> > output = input;
....
return output;
}
(or make it void if it is allowed to modify the original matrix)

vector.insert doesn't resize vector?

i'm trying to create a function that takes in a vector by reference and if it sees a vector entry 2, it would take delete the entry and replace it with 4 copies of 5.
so if the vector is 222 (then it is size n = 3), i want 555555555555 as the new vector
however, it only works properly for the first few, when the index is < n.
so right now, it would change vector a to be 555522
any ideas how to make the vector resize?
void replace2 (vector <int>* a, int n){
for (int i = 0; i < n; ++i){
if ((*a)[i] == 2){
(*a).erase((*a).begin() + i);
for(int j = 0; j < 4; ++j){
(*a).insert((*a).begin() + i, 5);
}
}
}
}
The problem with using
for ( int i = 0; i < n; ++i ) { ... }
has already been pointed out in one of the comments:
After the first iteration of the loop, (*a)[i] no longer equals 2. Remaining iterations do nothing.
Your function will be simplified if you iterate from the end of the vector and go back.
Also, pass a reference to the vector instead of a pointer.
Here's a complete program:
#include <vector>
#include <iostream>
void replace2(std::vector <int>& a, int n){
for (int i = n-1; i >= 0; --i){
if (a[i] == 2){
a.erase(a.begin() + i);
for(int j = 0; j < 4; ++j){
a.insert(a.begin() + i, 5);
}
}
}
}
int main()
{
std::vector<int> a{2, 2, 2};
replace2(a, 3);
for(auto item : a )
{
std::cout << item;
}
std::cout << std::endl;
}
See it working at https://ideone.com/0Lip5j.

Sorting A Random Valued Array Ascendingly by the Value

I am new to C++, I have a problem with sorting an array that has random value generated by rand() function.
The array length is 100 and the value was filled by a random number from 0 to 9 (0,1,2,3,4,5,6,7,8,9).
I have already succeed on determining the array's value, but still failed when I want to sort the array based on it's value ascendingly. By this, it means that when I print the array value, it may not be sorted by it's index, but by it's value.
Like this:
X[10]=0;
X[1]=1;
X[60]=2; ... etc until X[99]=...
Here is code to determine the value and sort it, what I have wrong here? Please help..
int length= 100;
X = new int[length];
int i;
int j;
int temp;
//determining the array value
for (i = 0; i < length; i++) {
X[i] = rand() % 10;
}
//sorting
for (i = 0; i < length; i++) {
for (j = 0; j < length; j++) {
if (X[i] < X[j]) {
temp = X[j];
X[j] = X[i];
X[i] = temp;
}
}
}
//print the array
for (i = 0; i < length; i++) {
cout << "X[" << i << "] = " << X[i] << "\n";
Sleep(10);
}
Code above won't print the sorted by value, it printed the array sorted by it's index ascendingly, not by it's value like what I want above.
Please hand me solution to this,
Thanks in advance
You are trying to initialize and sort the array in the same loop.
-First initialize the array:
for (i = 0; i < length; i++) {
X[i] = rand() % 10;
}
-Then sort the array: (Below sorting method is insertion sort, if you want to speed the process you can use counting sort since the array only contains numbers.)
for (i = 0; i < length; i++) {
for (j = i+1; j < length; j++) {
if (X[i] > X[j]) {
temp = X[j];
X[j] = X[i];
X[i] = temp;
}
}
}

Selection sort ascending

That is my function:
int main() {
double data[100];
int num;
cout<<"num= ";
cin>>num;
for(int i = 1; i <= num; i++) {
cout<<i<<" element = ";
cin>>data[i];
}
Sort(data, num);
for (int i = 1; i <= num; i++) {
cout<<data[i]<<endl;
}
return 0;
}
void Sort(double data[], int n) {
int i,j,k;
double min;
for(i = 0; i < n-1; i++) {
k = i;
min = data[k];
for(j = i+1; j < n; j++)
if(data[j] < min) {
k = j;
min = data[k];
}
data[k] = data[i];
data[i] = min;
}
}
if I write for exp. three elements: 8,9,1 again cout 8,9,1?
for(int i = 1; i <= num; i++) { // WRONG
I think you mean:
for(int i = 0; i < num; i++) { // RIGHT
Arrays in C are 0-indexed remember.
Your sorting function is fine. The only problem is that you enter elements at positions 1 through n, inclusive, while you should use 0 through n-1, inclusive, in both loops of the main() function.
If you need to print numbers 1 through n, use
cout<<(i+1)<<" element = ";
You should get used of the 0 index begin in the for loop
for(int i = 0; i < N; ++i)
so fixing these two index errors will make your code run properly.
the reason is:
if you write data to data[] using 1 as the begining, your data array's first item will be a random number:
if you insert 3 elements, the array will be like this:
data[0] = ??? // maybe a very very big number
data[1] = 8
data[2] = 9
data[3] = 1
and in your Sort function, your index begins at 0 and ends before num, that means your code would only sort data[0], data[1], data[2].
if you use: num = 3, 3 2 1 as your input data for the origin code you could see that 3 and 2 is sorted
I guess your Sort code is googled from somewhere, please try to understand it.
Good online algorithm course: https://www.coursera.org/course/algs4partI
a very good algorithm online book: http://algs4.cs.princeton.edu/home/
btw, for(j = i+1; j < n; j++) in the Sort function would be better if it has { } braces.