Shifting and adding an element to an array - c++

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.

Related

why do we need to create an auxiliary array to rearrange it?

i'm new to c++ and working through the problem of rearranging a sorted array in O(n) time so that first comes the maximum element, then the minimum, then the second max, then the second min, so it goes.
my solution doesn't pass the tests without an auxiliary array result to which I then copy over my values - see below for the initial and the working solutions:
// initial:
void maxMin(int arr[], int size) {
bool switchPointer = true;
int min_ptr = 0;
int max_ptr = size - 1;
for (int i = 0; i < size; i++) {
if (switchPointer) {
arr[i] = arr[max_ptr];
max_ptr--;
} else {
arr[i] = arr[min_ptr];
min_ptr++;
}
switchPointer = !switchPointer;
}
}
// working
void maxMin(int arr[], int size) {
int* result = new int[size];
bool switchPointer = true;
int min_ptr = 0;
int max_ptr = size - 1;
for (int i = 0; i < size; i++) {
if (switchPointer) {
result[i] = arr[max_ptr];
max_ptr--;
} else {
result[i] = arr[min_ptr];
min_ptr++;
}
switchPointer = !switchPointer;
}
for (int j = 0; j < size; j++) {
arr[j] = result[j]; // copying to original array
}
delete [] result;
}
why do we need an auxiliary result array? thank you!
Because if you apply your algorithm "in-place" you will overwrite MIN values of your original array before you could use them. Imagine:
arr = {1, 2, 3, 4, 5}
expected result is {5, 1, 4, 2, 3}
in first iteration you will do arr[0] = arr[4] // arr[0] is equal to 5 now
in second iteration you will do arr[1] = arr[0] // but this is not what you want, because arr[0] was already changed and is not equal to "1" anymore
Usually you use temp variables when you need to read your original source of data and not the modified version. In your case I think the problem arises when you do
arr[i] = arr[max_ptr]; or arr[i] = arr[min_ptr]; in your non working example. In this case you modify the array and you read (arr[max_ptr]) the same overwritten array leading to inconsistencies in your algorithm. Using an auxiliary variable solves the issue since you read the original data but you store it somewhere else.

How to safely insert an element into an array c++?

I have a simple program to add an element to an array:
void printArray(int inp[], int size)
{
cout << "[";
for (int i = 0; i < size - 1; i++)
{
cout << inp[i] << ", ";
}
cout << inp[size - 1] << "]" << endl;
}
int addElement(int inputArray[], int inputSize, int element, int atIndex)
{
int cur = inputSize;
while (cur >= 0)
{
if (cur == atIndex)
{
inputArray[cur] = element;
return inputSize + 1;
}
inputArray[cur] = inputArray[cur - 1];
cur--;
}
return inputSize + 1;
}
int arr1[] = {1, 5, 9, 2};
int arr2[] = {1, 5, 9, 2};
int main()
{
int arraySize = sizeof(arr1) / sizeof(arr1[0]);
addElement(arr1, arraySize, 7, 0);
printArray(arr1, arraySize + 1);
printArray(arr2, arraySize);
return 0;
}
This outputs:
[7, 1, 5, 9, 2] [2, 5, 9, 2]
Even though I haven't touched arr2 it is modified. I think because arr1 and arr2 are allocated contiguously in memory, and naively adding an element to arr1 overwrites arr2[0].
How should I handle this case and add only if the next space is unused, otherwise move the entire array to another location?
You can achieve this easily by using std::vector.
It has a method called insert, where you just pass a position and a number as arguments and it will handle the reallocation by itself.
For example: if you write:
vector<int> vec = { 1, 2, 3, 4, 5 };
vec.insert(vec.begin() + 2, 100);
Now elements in your vector are 1, 2, 100, 3, 4, 5.
I don't know if this will help you, but you can also add multiple elements at once:
vector<int> vec = { 1, 2, 3, 4, 5 };
vec.insert(vec.begin() + 3, { 100, 101 });
Now elements in your vector are: 1, 2, 3, 100, 101, 4, 5.
As you can see, the first argument is the position of the first inserted element and the second one is element or list of elements that you want to insert.
You can read more about std::vector here and about std::vector::insert here
Hope this helps.
As what the comments mentioned by #StoryTeller, you can use a std::vector.
But you have to pick on which function of the container you wanna use, there are 2 types.
::insert, which inserts data on the specific location in the
container. This is iterator based.
::push_back, which inserts at the back/last of the container
You can use any of them, depending on your purpose, just be sure of ::insert that you are pointing to the correct position(iterator wise).
Also, as of C++11 you can use ::emplace and ::emplace_back, which constructs and inserts data. You can find more at,
http://www.cplusplus.com/reference/vector/vector/
Hope this helps.
I have a simple program to add an element to an array:
Impossible. An array's size is fixed at compile time. In other words,
int arr1[] = {1, 5, 9, 2};
is a lot like:
int arr1_1 = 1;
int arr1_2 = 5;
int arr1_3 = 9;
int arr1_4 = 2;
I think it is helpful, for learning purposes, to view an array like this, and not like a container which can shrink and grow while the program is running. Adding an element to an array at runtime would be like asking to add a variable at runtime. C++ arrays don't work like that.
You can use new[] to set an array's initial size at runtime, but even then you cannot "add" anything. In fact, don't use new[], ever.
Go to cppreference.com, learn about std::vector and relearn everything from scratch. Start with the example code at the bottom of the page.

How can we find out in which element in an array the address and value came from in c++

For example: int a[4] = {2, 4, 34}
Lets say the address of a[0] is at 2000 and we know the value of the element at a[0] is 2.
Given only a memory address and a value of an element, is it possible to determine the position of the element in the array?
If so, please provide an example on how to do this.
Is this what you are looking for? Just using some pointer arithmetic;
int main ()
{
int ary[] = { 1, 2, 3, 5 };
int * address_of_2 = &ary[ 1 ];
int index_of_2 = address_of_2 - ary;
return 0;
}
The memory location will be unique for each element in the array. So yes, if you know the memory location, you can iterate through the array and simply find when the reference equals your value.
for (int i=0; i < arr_size; i++) {
if (&arr[i] == address && arr[i] == *address) {
cout << i << endl;
break;
}
}
If given an array, the size of the array and type of element(i.e. integer), than yes, given also the address of an element and the value, you could sort through the array and find its position. Note the significance that the array block is contiguous.
array = array;
n = sizeof(array)/sizeof(*array);
oAddress = array;
fAddress = array + n * sizeof(*array);
locOfElement = (elementAddress - oAddress) / (fAddress - oAddress) * n;

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

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}

tr1::array in C++ deleting all elements

how to delete all elements of a std::tr1::array?
For example I have defined the following array.
std::tr1::array <int, 5> a = { 1, 2, 3, 4, 5}
Just like in vectors I am looking for a method such as a.clear() or a.erase() but couldn't find one for arrays.
Thank you
arrays are static size, you can neither add nor remove elements, that's what vector is for.
Once defined, the size of an array cannot be modified.
Arrays have a fixed size. You can, however, keep track of the number of elements you use in the array, for a fixed-maximum-sized-vector:
array<int,5> arr;
int number_of_elements = 0;
for ( int i = 0; i < 4; ++i ) {
// arr.push_back(i)
arr[number_of_elements] = i;
number_of_elements++;
}
// arr.erase( arr.begin() + 2 )
for ( int i = 2; i < number_of_elements-1; ++i )
arr[i] = arr[i+1];
number_of_elements--;
// arr.clear()
number_of_elements = 0;
you can delete specific index information if want!
for(int i=0;i<n;i++) //for deletion
{
if(arr[i]==_delete)
{
arr[i]=arr[i+1];
--n;
}
}