How to remove the elements of an array within a certain range - c++

I have a one-dimensional array of size 10. I want to remove the elements from 5 to 8. Can somebody give me an example of how to do it? This is how I defined my array but I have no idea about how to start.
#include <iostream>
#include <iomanip>
using namespace std;
int array[10] = {1,2,3,4,5,6,7,8,9,10};
So, the output should be 1,2,3,4,5,10. (index 0 = element 1)
Thanks

An alternative to arrays is to use a vector. In this case you can do:
#include <vector>
// create vector for integers
std::vector<int> v;
// set values from 1 to 10
for (int i=1; i<=10; i++)
v.push_back(i);
// erase from 5 to 8
v.erase (v.begin()+5, v.begin()+9);
BTW, if your compiler supports C++11, you can initialize your vector as:
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

In the above case, its an array of 10 elements array[10]. As the array size is fixed, it may not be possible to remove an item from the array.
Rather, you can assign null or someother value to the corresponding element.
BTW, I would rather use, std::list or std:: vector instead of array.
Anyhow, If you mean to get rid of that element, you'd need to shift all the ones to the right of that element one to the left:
for (int i = index; i < /* length */; i++)
array[index] = array[index+1];
array[length-1] = 0;

You can't literally remove them because C++'s built-in arrays (like C's) are fixed-size.
What you can do is overwrite them with the values that come after them, and then (if you want to) zero out the four now-extra positions at the end of the array. e.g.:
// copy latter values over the values we don't want
for (int i=4; i<6; i++) array[i] = array[i+4];
// zero out the no-longer-necessary values at the end, just so they won't appear valid anymore
for (int i=6; i<10; i++) array[i] = 0;
and then when printing the array, print only the first 6 values rather than all 10, since your array is (conceptually, even if not actually) "shorter" now.

Not sure what exactly you want your output to be, so I'm just providing another possible solution here:
// your input
int array[10] = {1,2,3,4,5,6,7,8,9,10};
// 1. put all invalid element in the back of the array
// "it" points to the first invalid element
int* it = std::remove_if(std::begin(array), std::end(array),
[](int e)
{
return (e >= 5) && (e <= 8);
});
// 2. then, mark them as -1 (from "it" to the last element)
std::transform(it, std::end(array), it,
[](int e) -> int
{
return -1;
});
// now the array contains:
// {1,2,3,4,9,10,-1,-1,-1,-1}

Related

How to extract columns of a 2D array in c++?

My task is to count the no of elements greater than an element aij in the corresponding row i and column j for every element of a 2D array in C++. My way is to extract the ith row and jth column, sort them and traverse the sorted array with a counter variable until aij element is found.
But the problem is in extracting the entire row i and entire column j for every such element. I know that the row can easily be extracted with std::copy function in c++.
int **adj=new int *[n];
for(r=0;r<m;r++)
for(c=0;c<n;c++)
cin>>adj[r][c];
int buf[n];
std::copy(adj[i], adj[i] + n, buf);
But how to extract the corresponding jth column?
I can easily do it with a looping structure like:
int buf[m];
for(r=0;r<m;r++)
buf[r]=adj[r][j];
but this will increase time complexity keeping in mind that this operation is required for every element of the array. Any better way to do this?
If you decide to write program in C++, then
Stop using plain C-Style arrays. There is No reason whatsoever for C-Style arrays. Do never use them again. Simply stop this.
Stop using raw pointers. For now and ever. Do not use raw pointers
Do not use new. Never
The language C++, which you want to use, does not support VLA (avariable length arrays), Do not use C-Style arrays in the first place and not at all VLA (like int buf[m];
Especially, do not use such constructs, if you do not understand how thew work
In you first row, you are writing
int **adj=new int *[n];
With that you are allocating an array of pointer. Those pointers are not initialized. They point to somewhere random in the memory.
And with
for(r=0;r<m;r++)
for(c=0;c<n;c++)
cin>>adj[r][c];
You are getting user input and write them into random memory, somehwere, undifined, corrupting the heap and causing a crash.
With
int buf[n];
std::copy(adj[i], adj[i] + n, buf);
you copy some random values into buf. It will look like it works. But it is only by accident.
In the future please use std::vector or std array (if you know the dimension at compile time). For 2 dimensional arrays use a vector of vectors.
See the following example:
int main()
{
const size_t numberOfRows = 3;
const size_t numberOfColumns = 4;
std::vector<std::vector<int>> a2d(numberOfRows, std::vector<int>(numberOfColumns));
// Fill a2d with data
for (size_t row = 0; row < a2d.size(); ++row) {
for (size_t col = 0; col < a2d.front().size(); ++col) {
std::cin >> a2d[row][col];
}
}
// Get 2nd row
std::vector<int> row(numberOfColumns);
std::copy(a2d[1].begin(), a2d[1].end(), row.begin());
return 0;
}
But the problem is in extracting the entire row i and entire column j for every such element.
The algorithm you are trying to implement doesn't need to copy and sort the row and the column every time. You can copy and sort each row and each column once, then reuse those for every element. While time consuming, it should be asintotically faster than traversing the rows and columns multiple times to count the greater values.
See e.g. the following implementation (testable HERE).
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
int main()
{
std::vector<std::vector<int>> a {
{3, 5, 1, 2},
{8, 0, -2, 7},
{1, -5, 3, 6},
};
// Make a transposed copy. That's really cache unfriendly
auto a_t = std::vector<std::vector<int>>(a[0].size(), std::vector<int>(a.size()));
for (size_t r = 0; r < a.size(); ++r)
{
for (size_t c = 0; c < a[r].size(); ++c)
{
a_t[c][r] = a[r][c];
}
}
// Sort the rows of a_t (columns of a)
for (auto & row : a_t)
{
std::sort(row.begin(), row.end());
}
auto c = std::vector<std::vector<int>>(a.size(), std::vector<int>(a[0].size()));
for (size_t i = 0; i < c.size(); ++i)
{
// Sort a (copied) row at a time.
auto row_copy(a[i]);
std::sort(row_copy.begin(), row_copy.end());
// The columns have already been copied and sorted,
// now it just takes a couple of binary searches.
for (size_t j = 0; j < c[i].size(); ++j)
{
auto it_r = std::upper_bound(row_copy.cbegin(), row_copy.cend(), a[i][j]);
auto it_c = std::upper_bound(a_t[j].cbegin(), a_t[j].cend(), a[i][j]);
c[i][j] = std::distance(it_r, row_copy.cend())
+ std::distance(it_c, a_t[j].cend());
}
}
for (auto const & row : c)
{
for (auto i : row)
std::cout << std::setw(3) << i;
std::cout << '\n';
}
}

How to remove integers in array less than X in C++?

I found the same question for PHP and I tried to do the same in C++.
I tried following:
// returns new array with numbers lower then "number", len is set to
// new length.
int * filter(int array[], int &len, int number) {
int cnt = 0;
for (int i = 0; i < len; i++) {
if (array[i] < number) {
cnt++;
}
}
int *ret = new int[cnt];
cnt = 0;
for (int i = 0; i < len; i++) {
if (array[i] < number) {
ret[cnt] = array[i];
cnt++;
}
}
len = cnt;
return ret;
}
This function will create a new array with the integers that are lower than the integer number. I tried to bypass the problem that I don't know how long the new array should be.
Is there any better way to solve this problem?
Yes, use std::vector type. It will automatically handles allocations for you each time you push value to it (using push_back method).
Example
#include <iostream>
#include <vector>
int main() {
std::vector<int> a;
a.push_back(1);
a.push_back(2);
for (int value : a) {
std::cout << value << '\n';
}
}
It's also a good idea to avoid new syntax, as it doesn't automatically deallocate, unlike std::vector.
Also, while this is unrelated to question, C++ provides a function that does what you want already called std::copy_if.
std::remove is the algorithm you're looking for.
#include <iterator>
#include <algorithm>
int main()
{
int array[4] = {1, 42, 314, 42};
// If you only know `array` as a pointer, and `len`, then
// `std::begin(array)` becomes `array`, and
// `std::end(array)` becomes `array + len`.
auto end = std::remove(std::begin(array), std::end(array), 42);
// Now `end` points to the "new end" of the array.
// And `std::distance(std::begin(array), end)` is the "new length".
}
It moves all matched elements (42 in the example) to the end of the array. When inspecting array after std::remove runs, you get {1, 314, 42, 42}, and end points past the last nonmatching element (the first 42 in this case).
It's also possible to copy the nonmatching elements to another array using std::remove_copy, or std::copy_if, but in order to do this, you'll have to allocate another array of elements. At this point, you're better off using a dynamic growing array such as std::vector. In that case, use std::vector::erase like here in the answers with std::remove.

For loop with an array

#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int a[5];
for (int i = -1; i < 7; i++)
cout << i << " " << setw(2) << a[i] << endl;
}
So I'm trying to figure out why this won't work. If i take out a[i] it works, but if i leave it in, the for loop goes from -2 until the 1000's which is obviously not right. Is it because a[i] is not bound to the parameters of the for loop (i < 7)? I'm not really sure I understand.
EDIT As many of you have explained it was a matter of uninitializing the array and using bounds outside of the array (e.g -2). It was not something I thought of, nor found when searching for why this was happening.
First, as marcadian pointed out, the array a is not initialized, so values in the array are completely random.
Also, the size of the a array is 5, meaning that you can access between indexes 0 and 4 inclusive.
However, in your loop, you try to access at index -1, and index 6. Attempting to write and read at invalid indexes ( such as -1 and 6, in this case ) is undefinded behavior ( it can crash with a segmentation fault, or corrupt other variables, which can make debugging process very hard ... )
A way to avoid buffer overrun like you did is to use std::array STL container, like this :
std::array<int, 5> a;
//Access elements using the method 'at()', it has bound checking
a.at(0); // 0 is a valid index
//a.at(-1); // -1 is not a valid index, it will crash ( at least in debug mode )
//a.at(6); // 6 is also not a valid index
The std::array STL container does the same things normal array does, but provides useful methods
You're printing out random value in memory because variable a is not initialized. Uninitialized variable has random value in memory. What are you trying to do?
in computers an array is really just a given number of values, starting at array[0], and ending at array[n].
int a[5]; statically allocates space for 5 integers on the stack, starting at a[0], and ending at a[4].
Try this iteration instead:
for (int i = 0; i < 4; i++)
In addition to not initializing the array, a, the indices you would be using to access its elements are out of bounds. C++ uses zero-indexing - you could try, for instance:
int main() {
int a[] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++) {
cout << i << " " << a[i] << endl;
}
}
Output would be:
0 1
1 2
2 3
3 4
4 5

Shifting and adding an element to an array

Suppose I have an array: int list[] = {1, 2, 4, 5, 6};
and I want to shift the array from the middle to the right and place 3 in the place of 4 so it would look like: {1, 2, 3, 4, 5, 6}.
How would I do it?
If you can use the C++ Standard Library, then std::vector is a replacement for arrays. It has a dedicated method insert to do what you want:
std::vector<int> v;
... // add elements 1, 2, 4, 5, 6 to it
v.insert(v.begin() + 2, 3); // insert 3 at position 2
This is good if you know where to insert your new element. However, it seems that your list should always be sorted, and you want to insert the new element so it remains sorted. If so, you better use std::multiset:
std::multiset<int> v;
... // add elements 1, 2, 4, 5, 6 to it
v.insert(3); // insert 3
Here, you don't need to tell where to insert the new element.
If you cannot use vector, one solution is:
Create an array with a lot of space (with a few empty positions at the end);
int * array = malloc(sizeof(int) * array_size);
Use two variables one to save the size of the array (lets called size) another to count the number of elements already added (lets called number_of_elements_in_the_array)
When you added an element at the position 'x', you do the following (with x < size of the array):
int tmp = array[x]; // save the current value
array[x] = new_value; // update with the new value
int tmp2;
number_of_elements_in_the_array++;
// we reach the limited
if(number_of_elements_in_the_array == size)
{
size = 2 * size; //lets double that size
int *new_array = malloc(sizeof(int) * size);
// copy the first elements
for(int i = 0; i <= x; i++)
new_array[i] = array[i];
new_array[x+1] = tmp;
// copy the last elements
for(int i = x+1; i < number_of_elements_in_the_array; i++)
new_array[i+1] = array[i];
free(array) // free the old space
array = new_array; // update the new pointer
}
else
{
// shift the remaining elements
for(int i = x+1; i < number_of_elements_in_the_array; i++)
{
tmp2 = array[i];
array[i] = tmp;
tmp = tmp2;
}
}
when you reach the limited, create a new array with more memory, copy from the old array to the new one, and update the variables number_of_elements_in_the_array and size accordingly.
Disclaimer : I didn't tested, thus it might be some minor erros, but the overall ideia is there.

How to get column of a multidimensional array in C/C++?

int matrix[9][9],*p;
p=matrix[0];
this works and gives first row of matrix, but how to get first column of matrix I've tried p=matrix[][0]; ? Also I don't understand why below code gets compiler error ?
int matrix[9][9],p[9]; // it looks really ugly, byt why it doesn't work ?
p=matrix[0]; // compiler gives "invalid array assigment"
is it because multidimensional arrays are arrays of arrays - and we should interpret matrix[i][j] as j-th element of i-th nested array ?
In C/C++, multidimensional arrays are actually stored as one dimensional arrays (in the memory). Your 2D matrix is stored as a one dimensional array with row-first ordering. That is why getting a column out of it is not easy, and not provided by default. There is no contiguous array in the memory that you can get a pointer to which represents a column of a multidimensional array. See below:
When you do p=matrix[0], you are just getting the pointer to the first element matrix[0][0], and that makes you think that you got the pointer to first row. Actually, it is a pointer to the entire contiguous array that holds matrix, as follows:
matrix[0][0]
matrix[0][1]
matrix[0][2]
.
.
matrix[1][0]
matrix[1][1]
matrix[1][2]
.
.
matrix[8][0]
matrix[8][1]
matrix[8][2]
.
.
matrix[8][8]
As seen above, the elements of any given column are separated by other elements in the corresponding rows.
So, as a side note, with pointer p, you can walk through the entire 81 elements of your matrix if you wanted to.
You can get the first column using a loop like
for(int i = 0; i < 9; i++)
{
printf("Element %d: %d", i, matrix[i][0]);
}
I think the assignment doesn't work properly because you're trying to assign something's that's not an address to a pointer.
(Sorry this is c code)
There is no difference between specifying matrix[81] or matrix[9][9]
matrix[r][c] simply means the same as matrix[9*r+c]
There are other containers better suited fort multidimensional arrays like boost::multi_array
http://www.boost.org/doc/libs/1_53_0/libs/multi_array/doc/index.html
Think of the bare array just like allocating a contiguous piece of memory. You, the programmer then has to handle this piece of memory yourself. The bare name of the array, e.g. matrix is a pointer to the first element of this allocated piece of memory. Then *(matrix+1) is the same as matrix[0][1] or matrix[1].
p is an array of int, matrix[0] is a pointer..
matrix itself is the nearest thing you can get to a column of the array, inasmuch as (matrix + 1)[0][0] is the same as matrix[1][0].
Here's a program which builds a 10x10 array and prints the second column:
#include <iostream>
using namespace std;
int main()
{
int aa[10][10];
for(int i = 0; i<10; i++)
for(int j = 0; j<10; j++)
aa[i][j] = i*10+j;
int col = 2;
// pointer to a length-10 1d array
int (*p)[10] = (int (*)[10])&(aa[0][col]);
for(int i =0; i<10; i++)
cout << *(p[i]) << endl;
return 0;
}
The difference from aa[row][2] is using a pointer to a length-10 1d int array int (*p)[10], For more context about int (*p)[10], see this answer
p saves the address of 1d array {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
. And p+1 saves the address of 1d array {12, 13, 14, 15, 16, 17, 18, 19, 20, 21}. *(p[1]) or *(*(p+1)) access the first value of 1d array.
If you want your matrix to contiguous locations, declare it as a one dimensional array and perform the row and column calculations yourself:
int contiguous_matrix[81];
int& location(int row, int column)
{
return contiguous_matrix[row * 9 + column];
}
You can also iterate over each column of a row:
typedef void (*Function_Pointer)(int&);
void Column_Iteration(Function_Pointer p_func, int row)
{
row = row * MAXIMUM_COLUMNS;
for (unsigned int column = 0; column < 9; ++column)
{
p_func(contiguous_matrix[row + column]);
}
}
For static declared arrays you can access them like continuous 1D array, p = matrix[0] will give you the 1st column of 1st row. Then the 1D array can be accessed like p[i], *(p+i), or p[current_raw * raw_size + current_column).
The things are getting tricky if a 2D array is represented with **p as it will be interpreted as an array of pointers to 1D arrays.
I don't know if this is a efficient solution but by doing this way I'm able to get the column,
int arr[9][2] = { {2, 57}, {3, 66}, {4, 73}, {5, 76}, {6, 79}, {7, 81}, {8, 90}, {9, 96}, {10, 100}};
int c[18];
int co = 0;
for (auto & i : arr) {
for (int j : i) {
c[co++] = j;
}
}
for (int i = 0; i < co; ++i) {
if (i % 2 != 0)
std::cout << c[i] << " ";
}