How to skip a index in an array C++ - c++

I am trying to write a function that loops through an array, and skips over a given index. For example.
If have the array:
int Array[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
I want the output to skip over a given index. For example index 5, would skip "4". And output an array of smaller size, by skipping the "4", or index 5.
0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
My current function to skip over an index looks like this:
void deleteArray(int original[], int origLen, int newArray[], int index){
for(int i = 0; i < origLen--; i++){
newArray[i] = original[i];
if(original[i] == index){
newArray[i] = original[i-1];
}
}
}
I'm trying to iterate through the original array and copy its indexes until it gets to a certain index, and then skip over that given index, and creating a new array. Essentially, shifting all the arrays items to the left while skipping over a given index in a new array copied from the original array.
However, in my if statement, I'm not sure how to skip over the index. My current code substitutes the index with the previous index. Outputs:
0, 1, 2, 3, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
Desired output:
0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19

For a start, your condition is incorrect:
if(original[i] == index){
You're comparing the value of the element with the desired index, rather than the index itself (which in this case should be i).
Once past the desired index, you actually want every element in the new array to be the same as the previous element in the original array - not just one - so you need to deal with this somehow. I would suggest that you keep a boolean flag to track whether you've gone past the index, and in that case, assign original[i-1] to newArray[i]; if the flag is false, then assingn original[i] to newArray[i] (as you already do) instead.

You can simplify the function by using two loops instead of using one loop and performing check for every run of the loop.
void deleteArray(int original[], int origLen, int newArray[], int index){
// Get everything up to index.
// When index is 5, get everything until i = 3
for(int i = 0; i < index-1; i++) {
newArray[i] = original[i];
}
// Now get everything after index.
for(int i = index; i < origLen; i++) {
newArray[i-1] = original[i];
}
}

std::copy it:
auto newArrayPosition = std::copy(original, original + index, newArray);
std::copy(original + index + 1, original + origLen, newArrayPosition);

If you always know that your new array would be one element smaller than the original i suggest you doing like this:
int Array[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
int newArray[19];
then
void deleteArray(int original[], int origLen, int newArray[], int index){
j = 0;
for(int i = 0; i < origLen; i++){
if(i == index){
continue;
}
newArray[j] = Array[i];
j++;
}
or even you can write in the boby of your loop smth like this (if you don't want to use j):
for(int i = 0; i < origLen; i++){
if(i == index){
continue;
}
if (i < index){
newArray[i] = Array[i];
}
else {
newArray[i-1] = Array[i];
}
}

I would just keep two counters, one for the insert position and one for the reading position:
void deleteArray(int original[], int origLen, int newArray[], int index){
int insertPos = 0;
for(int readPos = 0; readPos < origLen; readPos++){
// If this position is equal to the index we want to skip
if (readPos == index)
{
// continue onto next loop iteration
continue;
}
// Copy over the data
newArray[insertPos] = original[readPos];
// increment the counter
insertPos++;
}
}
Like others have said, avoid i < origLen-- as that is very complicated and you actually ended up not even parsing through your whole array because you kept decrementing.

Related

How to store values from a normal array to a 2D array in C++?

I want to store the Values to the CustomValues array. How can I do this?
Any code and explanation would be great.
int main() {
int CustomValues[4][3];
int Values[3] = {234, 98, 0};
int Values1[3] = {21, 34, 5};
int Values2[3] = { 12, 6, 765 };
int Values3[3] = { 54, 67, 76 };
}
The CustomValues array should look like:
{{234, 98, 0}, { 21, 34, 5 }, { 12, 6, 765 }, { 54, 67, 76 }}
There's a few different ways you can do this. Since we already know your constraints, I've taken liberties to not do this dynamically.
The first is memcpy, which is in the <cstring> header:
memcpy(CustomValues[0], Values, sizeof(Values));
memcpy(CustomValues[1], Values1, sizeof(Values1));
memcpy(CustomValues[2], Values2, sizeof(Values2));
memcpy(CustomValues[3], Values3, sizeof(Values3));
Another is to loop through the array and store the values individually:
for (int i = 0; i < sizeof(CustomValues)/sizeof(CustomValues[0]); i++) {
for (int j = 0; j < sizeof(CustomValues[0])/sizeof(CustomValues[0][0]); j++) {
if (i == 0) {
CustomValues[i][j] = Values[j];
}
else if (i == 1) {
CustomValues[i][j] = Values1[j];
}
else if (i == 2) {
CustomValues[i][j] = Values2[j];
}
else if (i == 3) {
CustomValues[i][j] = Values3[j];
}
}
}
There is probably a better way to handle the logic for selecting which Values array you want, but that was just a quick solution to demonstrate.
EDIT: Example of 2D Vector usage
This example doesn't contain the logic for actually controlling the number of elements in a vector, but you can simply do that by following the for loop logic. Basically, you just need something to check the size of your vector with size(), and then move to a different one.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<vector<int>> CustomValues; //2D vector
//1D vectors
vector<int> Values;
vector<int> Values1;
Values.push_back(234); //to insert a value individually
Values.insert(Values.end(), {98, 0}); //to append multiple values
Values1.insert(Values1.end(), {21, 34, 5});
//inserting the 1D arrays to the 2D arrays
CustomValues.push_back(Values);
CustomValues.push_back(Values1);
//example of getting # of elements
int countOfInnerVectors = 0;
for (int i = 0; i < CustomValues.size(); i++)
countOfInnerVectors++;
cout << "The number of 1D vectors in CustomValues is: " << countOfInnerVectors;
}
An example of checking for the correct amount of vectors would be:
//check if we have less than 10 inner vectors
int maxCustomValuesSize = 10;
if (CustomValues2.size() < maxCustomValuesSize)
In this example, you would have something like int index = 0, and when that if is no longer satisfied, you could do index++ or some other logic to start inserts at your new index, like CustomValues2[index].push_back(Values);.
You can follow the same logic for the inner vectors as well, you would just be changing to a new 1D array instead of changing to a new "row" like the outer vector does.

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.

Reinitialising an array on if statement

I'm writing class that manages dynamic array of objects. Right now I got stuck on method that should insert element at given index, but before it checks if that index isnt bigger than array capacity. Then it should resize array first.
template <class T>
void MyVector<T>::insertAt(int index, const T &m_element) {
if(p_size == p_capacity) extendArray();
if(index >= p_capacity) extendArray(index);
p_size++;
p_array[index] = m_element;
}
template <class T>
void MyVector<T>::extendArray(int new_capacity) {
std::unique_ptr<T[]> temp_array = std::make_unique<T[]>(new_capacity);
for (int i = 0; i <= p_size; i++) {
temp_array[i] = p_array[i];
}
p_array.reset();
p_array = std::make_unique<T[]>(new_capacity);
for (int i = 0; i <= p_size; i++) {
p_array[i] = temp_array[i];
}
}
extendArray()just extends array capacity 2 times, extendArray(int) extends array capacity to the number given by the index. First method works fine, second not so really.
int main(){
MyVector<int> test;
test.insertAt(0, 5);
test.insertAt(1, 3);
test.insertAt(2, 1);
test.insertAt(6, 11);
cout <<"Size " << test.getSize() << "\n";
for(int i = 0; i < test.getCapacity(); i++) {
cout << test.get(i) << ", ";
}
}
Id expect something like 5, 3, 1, 0, 0, 0, 11, 0
But I get just 5, 3, 1, 0 so it never extends array but it increases size (number of elements).
You did not post your extendArray() function but even though you say it's a copy of extendArray(int) first seems to be updating p_capacity when the latter you provided doesn't.
Fixing that would gain you couple of extra zeros in the output 5, 3, 1, 0, 0, 0 since you extending only to the index, not to the index+1. Furthermore, in insertAt(int index, const T &m_element) you are incrementing the p_size, instead of assigning it to index+1
Extending to p_size+1 and fixing the p_size assignment, prints 5, 3, 1, 0, 0, 0, 11 and I am not quite sure how you came to the conclusion that it should have an extra trailing 0 as p_capacity ends up being 7, regardless if the initial value is 1, 2 or 4 as in the code snippet I put a link to.
I also noticed couple of bugs I without looking too close: your loops shouldn't go to the p_size, but rather to p_size-1, so instead for (size_t i = 0; i <= p_size; i++) it should be for (size_t i = 0; i < p_size; i++)
I would also suggest using unsigned int (or size_t) instead of int for indexing as that allows to get compiler warnings when you do something which potentially can result in a negative index.
Lastly, you should be able to use unique_ptr::swap to avoid two allocations in extendArray(..).
Good luck with learning!

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.

C++ insertion sorting elements

Other way for elements to be in function instead of main program?
void insertionSort(int array[], int number)
{
int j, temp;
for (int i = 1; i<number; i++)
{
j = i;
while (j>0 && array[j - 1]>array[j])
{
temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
j--;
}
}
}
int main()
{
int number = 8;
int array[] = { 2, 7, 5, 6, 4, 8, 1, 3 };
insertionSort(array, 8);
for (int i = 0; i<number; i++)
cout << array[i] << " ";
cout << endl;
system("PAUSE");
return 0;
}
While the data to be sorted could be moved into the sort function, doing so creates a function that's pretty much useless--since it only ever sorts one set of data, it's equivalent to return {1, 2, 3, 4 5, 6, 7, 8};
Your insertion sort is also a bit of a mess. Pseudo-code for an insertion sort normally looks something like this:
for i in 1 to size do
temp = array[i]
for j in i downto 0 and array[j-1] > temp do
array[j] = array[j-1]
array[j] = temp
I would suggest that you do not do this. A function is supposed to be a reusable piece of code. If you hardcode the array into the function then that function could only ever sort the array that is in the function and you would have to edit the array in the function to sort something different. By passing the array to the function now you have the ability to pass any array to the function and it will get sorted. You could even call the function multiple times with different arrays in the same program and they will be sorted.
I will also mention that if you move the array to be in the sort function then it won't be in main() and you won't be able to print out the array in main() as you have it now.