How do you delete and append values to an array in c++? - c++

I am a beginner in c++ and I am wondering how do you delete and append values to arrays.
What I mean is like this:
int arr[] = {1, 2, 3, 4}
I want to turn it into:
int arr[] = {1, 2, 3}
by deleting the last value of the array.
Also,
I would like to know how to append the a value to the end of an array. Like this:
int arr[] = {1, 2, 3, 4}
Into this:
int arr[] = {1, 2, 3, 4, 5}
Can anyone help me.
Thanks.

You can't, without new/delete, but std::vector is better. Here's an example of both.
#include <iostream>
#include <vector>
int main() {
// With new/delete:
int *array = new int[3];
array[0] = 1;
array[1] = 2;
array[2] = 3;
// `array` processing...
int *array2 = new int[4];
for (int i = 0; i < 3; i++) {
// copy old data into new array (array2)
array2[i] = array[i];
}
array2[3] = 4;
delete []array;
// `array2` processing...
delete []array2;
// With STL vector:
std::vector<int> array3;
array3.resize(3);
array3[0] = 1;
array3[1] = 2;
array3[2] = 3;
// `array3` processing...
// Add any number of elements
array3.push_back(4);
// resized `array3` processing...
return 0;
}

Related

set multiple array variables at the same time (c++)

I'm trying to make an ASCII art using C++, and having some problems in arrays.
Is there any way to set multiple array variables at the same time?
Let me be more specific.
When you initialize an array, you can do this way.
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
By the way shown above, you can set 10 array variables at the same time.
However, I want to (re) set some of the array variables like this?
a[1] = 3;
a[4] = 2;
a[5] = 2;
a[7] = 2;
Since there is NO rule in the variables, I can't do
for(int i=0; i<10; i++) a[i] = i+1;
fill(n);
I can't use an for statement or the fill, fill_n function, since there is no regularity.
To sum up,
Is there any way to set more than 1 array variables at the same time? (Like the second code snipplet above?
Given a index-value mapping list, and assign it one by one.
template<typename T, size_t N>
void Update(T(&arr)[N], const std::vector<std::pair<size_t, T>>& mappings)
{
for (const auto& mapping : mappings)
if(mapping.first < N)
arr[mapping.first] = arr[mapping.second];
}
int main()
{
int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Update(arr, { {1, 3}, {4, 2}, {5, 2}, {7, 2} });
return 0;
}
As far as I'm aware without a pattern a control structure is kind of redundant, you might be better served reading from a file.
// for user input
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
for (int i = 0; i < 10; i++) {
cout << "Please input your value for array index " << i << endl;
cin >> arr[i];
}
// for manual input in initalization
int arr[10] = { 0, 3, 2, 2, 2, 5, 6, 7, 8, 9 };
However a better approach might be to read it from a file, http://www.cplusplus.com/forum/general/58945/ Read "TheMassiveChipmunk"'s post there for exactly how to do it.
Assuming you know which indices you will be changing upfront you can use a separate index array:
int ind[4]= {1,4,5,7};
..and an accompanying array with values
int new_val[4] = {3,2,2,2};
The you can use the following for loop to assign the values:
for (int i=0; i<4; i++)
arr[ind[i]] = new_val[i];
You should also use some variable signifying the number of indices to be changed like int val_num = 4 instead of plain number 4.
Changes that are defined in runtime to an array can be easily implemented by using a list to save tuples that represent the changes you want to make. As an example, we can write:
#include <tuple>
#include <list>
#include <iostream>
using namespace std;
typedef tuple <int, int> Change;
int main() {
int a[5] = {1,2,3,4,5};
list<Change> changes;
//represents changing the 2-th entry to 8.
Change change(2,8);
changes.push_back(change);
for(auto current_change: changes)
a[get<0>(current_change)] = get<1>(current_change);
cout << a[2] << '\n';
}
Prints 8.

Passing a reference to an offset position in an STL vector

I'm trying to convert some old C functions to C++. My original programme stores a matrix in a single array, and I just pass a pointer to the first element to a function so that I am working on the correct row, e.g.
double f1(int *a){
return a[0] + a[1];
}
int main(void){
int x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for(i = 0; i < 5; i++){
printf("%d\n", f1(&x[2 * i]));
}
I would like to be able to do something similar using the STL without copying. So my programme would look something like this
double f1(vector<int>& a){
return a[0] + a[1];
}
int main(void){
int x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
vector<int> y(x, x + 10);
for(i = 0; i < 5; i++){
cout << f1(y) << endl; // This is clearly wrong
}
How would I do this? I could change my function to receive a reference to a vector::iterator I guess, but is there another way?
You could simply pass an iterator to the function. Random access iterators are very similar to pointers (in fact, pointers qualify as random access iterators.) For example,
#include <vector>
double f1(std::vector<int>::const_iterator a)
{
return a[0] + a[1];
}
#include <iostream>
int main()
{
vector<int> y{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto it = y.cbegin();
for(int i = 0; i < y.size()/2; ++i)
std::cout << f1(it + 2*i) <<std::endl;
}
Write array view. An array view is a pair of pointers with begin end size empty, operator[], front and back methods, and constructors from C arrays, std::array<T,N>&, std::vector<T,A>&, std::vector<non_const_T,A>const&, std::array<non_const_T,N>const&, std::initializer_list<non_const_T>, etc.
Oh, and T*,size_t and T*,T* ctors, which are great for slicing (use forwarding ctors: T*,size_t->T*,T*, and everything else to those 2).
It does not own its data, so all of its methods are const except operator=. (non-const methods would be methods that change the view range -- changing the elements is a const operation on a view).
Then
double f1(array_view<const int> a){
return a[0] + a[1];
}
You don't need to make so many changes:
double f1(int *a)
{
return a[0] + a[1];
}
int main(void)
{
vector<int> y = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i = 0; i < 5; i++) {
cout << f1(&y[2 * i]) << endl;
}
}

Array Split in C++

I am trying to split an array, and this is how I am doing it:
int arr1[] = {1, 2, 3, 4, 5};
int *arr2 = arr1 + 1;
Now I need to do this in a loop. In every iteration, I am trying to decrease the size of the array by 1 element or 2 elements based on a condition. For obvious reasons I can't declare int arr2[some_variable] .
But I want a new array to be created in every iteration of the loop whose size is 1 less than its parent array. I am not sure how I can achieve this. Can anyone help please?
In Java, there is a function which can do this: int newArr[] = Arrays.copyOfRange(arr, 1, arr.length); I wanted something similar to this in C++.
Use std::vector<int> from the C++ standard library:
#include <string>
#include <iostream>
#include <vector>
void dump(std::vector<int> &v)
{
for (std::vector<int>::iterator it = v.begin(); it != v.end(); it++)
std::cout << *it << " ";
}
int main()
{
int a[] = { 1, 2, 3, 4, 5 };
std::vector<int> v(a, a + 5);
std::vector<int> v2(v.begin() + 1, v.begin() + 4);
dump(v);
std::cout << std::endl;
dump(v2);
}
And if you really-really-really can't use vector (why, seriously?), then just memcpy.
int arr[] = { 1, 2, 3, 4, 5 };
int cp[3];
memcpy(cp, arr + 1, sizeof(cp));
I'm not sure exactly why you want to have a new one each time, but you can use a standard container, like std::vector:
std::vector<int> arr1{1, 2, 3, 4, 5}; //std::iota is another option
int index{};
/*loop header*/ {
//make sure arr1.size() is at least 1
std::vector<int> arr2(std::next(std::begin(arr1), ++index), std::end(arr1));
}
I use std::next because it works in more scenarios. All this does is create a vector from two iterators: as far past the beginning as necessary, and the end (one past because it's exclusive).
Though C++11 is nice, it's not always a reality. In that case, this should work:
int arr1temp[] = {1, 2, 3, 4, 5};
std::vector<int> arr1(arr1temp, arr1temp + sizeof(arr1temp)/sizeof(arr1temp[0]));
int index = 0;
/*loop header*/ {
//make sure arr1.size() is at least 1
std::vector<int>::iterator start = arr1.begin();
std::advance(start, ++index);
std::vector<int> arr2(start, arr1.end());
}
/why/ do you think you need to make a copy of the array? Pointers and arrays are somewhat interchangeable, so all you need to do is track size and modify that.
void doSomethingWithArray(int* array, size_t arraySize) {
....
}
const size_t arraySize = 5;
int arry1[arraySize] = { 1, 2, 3, 4, 5 };
int* array = arr1;
int* arrayEnd = arr1 + arraySize;
for (int i = 0; i < 10; ++i) {
if ((*array) & 1 == 1) {
array += 1;
} else {
array += 3;
}
if(array >= arrayEnd)
break;
size_t howBigIsMySlice = arrayEnd - array;
if(howBigIsMySlice > && (rand() % 1) == 0)
howBigIsMySlice -= 1;
doSomethingWithArray(array, howBigIsMySlice);
}
You made no copies of data, and as far as "doSomethingWithMyArray" is concerned, the array is as big as we tell it.

Why won't this array initialize?

This is essentially what I'm trying to do, but not the actual source code.
namespace namespace {
int array [3];
}
namespace::array={1,2,3}
my gcc asks for an expression, and I'm not sure of what to do. Must I namespace::array[1]; each individual element?
You can only use an initializer list in a definition:
int array[3] = { 1, 2, 3 };
If you use:
int array[3];
then you need to initialize the array in a function, using
array[0] = 1;
array[1] = 2;
array[2] = 3;
Although it an odd mixture of C99 and C++, gcc allows this:
#include <string.h>
int a[3];
int main()
{
memcpy(a, (int[3]){ 1, 2, 3}, sizeof(a));
}
!
How about namespace ns { int array[3] = {1, 2, 3}; }?
There are several ways:
1) Explicitly set values for each element:
namespace ns {
int array [3];
}
ns::array[0]=1;
ns::array[1]=2;
ns::array[2]=3;
\\ or if they should contain consequtive values:
\\ for (size_t i = 0; i < 3; ++i)
\\ ns::array[i] = i + 1;
2) If you want initialize static array in place of its declaration, then you could move it initializer list as follows:
namespace ns {
int array[3] = {1, 2, 3};
}
3) Use typedef:
namespace ns {
typedef int array_t[3];
}
ns::array_t array = {1, 2, 3};
3) Also you can make some research of std::tr1::array, which may be used as such:
std::tr1::array<int, 3> arr = {1, 2, 3};

Initializing an array before initializing a pointer to that same array

I want to initialize an array and then initialize a pointer to that array.
int *pointer;
pointer = new int[4] = {3,4,2,6};
delete[] pointer;
pointer = new int[4] = {2,7,3,8};
delete[] pointer;
How can I do this?
Why not use
int array[4] = {3, 4, 2, 6};
Is there a reason you want to allocate memory for the array from heap?
Suggestion after comment:
int arrays[32][4] = {{3, 4, 2, 6}, {3, 4, 1, 2}, ...}
int *pointers[4];
pointers[0] = arrays[0];
pointers[1] = arrays[12];
pointers[2] = arrays[25];
pointers[3] = arrays[13];
...
pointers[0] = arrays[13];
pointers[1] = arrays[11];
pointers[2] = arrays[21];
pointers[3] = arrays[6];
int *pointer = new int[4]{3,4,2,6};
EDIT: As pointed out in the comments, this is C++0x syntax. To do this in earlier versions, write a function that takes a stack array + size, allocates a new array on the heap, loops through the stack array populating the heap array, and then returning a pointer to the heap array.
int* foo( const int size, int *array )
{
int *newArray = new int[size];
for( int index = 0; index < size; ++index )
{
newArray[index] = array[index];
}
return newArray;
}
The call would look like this:
int a[] = { 1, 2, 3, 4 };
int *ptr = foo( 4, a );
It takes two lines, but it at least is easier than initializing line by line.
//initialize the array
int array[] = {3,4,2,6};
// initialize a pointer to that array
int *pointer = array;
As others have pointed out, you can initialize non heap arrays, e.g.:
static const int ar1[4] = { ... };
static const int ar2[4] = { ... };
Then initialize your dynamically allocated array from the static data:
void func()
{
int *pointer = new int[4];
...
memcpy(pointer, ar1, sizeof(ar1));
...
memcpy(pointer, ar2, sizeof(ar2));
...
You can do something like this with a standard container and boost::assign.
std::vector vect = list_of(3)(4)(2)(6);
...
vect = list_of(2)(7)(3)(8);