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;
}
}
Related
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.
This question already has answers here:
Sorting zipped (locked) containers in C++ using boost or the STL
(5 answers)
Closed 7 years ago.
I'm coding in C++ (with c++11 standards) and I have two big arrays of built-in type that I want to sort the second one based on the first.
here is an example:
A = {1, 5, 4, 3, 6, 2};
B = {1, 2, 3, 4, 5, 6};
after sorting:
A = {1, 2, 3, 4, 5, 6};
B = {1, 6, 4, 3, 2, 5};
It's as if each element B[i] is attached to element A[i] and you just sort array A. So elements in B move according the corresponding element in A. I know this questions has been asked over and over, yet the only solution I've come across with is to use pair<type 1, type 2>. But considering the arrays are big, it takes quite a while to allocate the memory for pairs array and copy arrays back and forth.
But I believe the sorting can be done in-place, i.e., using only O(1) memory. In fact if std::sort allowed for costume swap it would have been fine. Because I assume that's the only thing beyond comparator that sorting algorithms use.
A = vector<double>(1e6); // some random numbers
B = vector<double>(1e6); // some random numbers
Comp comp(&A,&B);
Swap swap(&A,&B);
costume_sort(A,B,comp,swap); // some sort function that can take costume swap and compare
class Comp {
vector<double> *A;
vector<double> *B;
Comp(vector<double> *A, vector<double> *B) : A(A),B(B) {};
bool compareTo(size_t i, size_t j) { return A->at(i) < A->at(j); };
};
class Swap {
vector<double> *A;
vector<double> *B;
Swap(vector<double> *A, vector<double> *B) : A(A),B(B) {};
void swapFnc(size_t i, size_t j) { swap(A->at(i), A->at(j));swap(B->at(i), B->at(j)); };
};
Is there any function in STL or other libraries available that can do that? This is a sort of pseudo-code of the idea I'm trying to explain here. Obviously it's not precise but I hope it's clear what I mean.
You can sort based on indices similar to the related post: std::sort and custom swap function.
It is not a custom swap function and allocateds some more memory, but should perform well.
If you are defining the types, then you can overload std::swap to do what you want: How to overload std::swap().
No there is not an std:: function that meets your requirements.
Although it's possible to provide its custom comparison (so Q&A) and swap (so Q&A) functor, those take a (constant) reference to the items to compare or swap, not an index on an hypothetical container. Indeed those functors should have meaning for comparisons and swaps of non-contained objects.
Example of reorder a[] and b[] in place according to a sorted array of pointers to a[]. Since an array of pointers is used, the compare function only needs to know the type of elements being compared. The reorder in place code time complexity is O(n), every store places a value in its sorted location. Note that the array of pointers is restored to it's original state (&a[0] ... &a[n-1]) during the reorder.
bool compare(const int *p0, const int *p1)
{
return *p0 < *p1;
}
int main()
{
int a[8] = {7,5,0,6,4,2,3,1};
char b[8] = {'h','f','a','g','e','c','d','b'};
int *pa[8];
size_t i, j, k;
int ta;
char tb;
// create array of pointers to a[]
for(i = 0; i < sizeof(a)/sizeof(a[0]); i++)
pa[i] = &a[i];
// sort array of pointers to a[]
std::sort(pa, pa+sizeof(a)/sizeof(a[0]), compare);
// reorder a[] and b[] according to the array of pointers to a[]
for(i = 0; i < sizeof(a)/sizeof(a[0]); i++){
if(i != pa[i]-a){
ta = a[i];
tb = b[i];
k = i;
while(i != (j = pa[k]-a)){
a[k] = a[j];
b[k] = b[j];
pa[k] = &a[k];
k = j;
}
a[k] = ta;
b[k] = tb;
pa[k] = &a[k];
}
}
for(i = 0; i < sizeof(a)/sizeof(a[0]); i++)
std::cout << a[i] << ' ';
std::cout << std::endl;
for(i = 0; i < sizeof(b)/sizeof(b[0]); i++)
std::cout << b[i] << ' ';
std::cout << std::endl;
return 0;
}
In C++ you can initialize a one dimensional array with 0 with a code like this:
int myarray[100] = {0};
Is there a similar way for multidimensional arrays? Or am i forced to initialize it manually with for loops?
You do it exactly the same way
int marr[10][10] = {0};
Edit:
This is a C solution. For a C++ solution you can go for:
int marr[10][10] = {};
These 2 solutions do not work for arrays that have size defined via variables. e.g.:
int i, j = 10;
int marr[i][j];
To initialize such an array in C++ use std::fill.
A multidimensional array is an array of arrays.
The same general array initialization syntax applies.
By the way you can just write {}, no need to put an explicit 0 in there.
use vector instead of array it will give you more flexibility in declaration and in any other operation
vector<vector<int> > myarray(rows,vector<int>(columns, initial_value));
you can access them same as you access array,
and if u still want to use array then use std::fill
You could use std::memset to initialize all the elements of a 2D array like this:
int arr[100][100]
memset( arr, 0, sizeof(arr) )
Even if you have defined the size via variables this can be used:
int i=100, j=100;
int arr[i][j]
memset( arr, 0, sizeof(arr) )
This way all the elements of arr will be set to 0.
Using 2 vector containers:
std::vector<std::vector<int>> output(m, std::vector<int>(n, 0));
This way one can declare a 2D vector output of size (m*n) with all elements of the vector initialized to 0.
For "proper" multi-dimensional arrays (think numpy ndarray), there are several libraries available, for example Boost Multiarray. To quote the example:
#include "boost/multi_array.hpp"
#include <cassert>
int
main () {
// Create a 3D array that is 3 x 4 x 2
typedef boost::multi_array<double, 3> array_type;
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);
// Assign values to the elements
int values = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
A[i][j][k] = values++;
// Verify values
int verify = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
assert(A[i][j][k] == verify++);
return 0;
}
See also: High-performance C++ multi-dimensional arrays
In C++, simply you can also do this way:-
int x = 10, y= 10; int matrix[x][y] = {};
and then the 2d-array will be initialized with all zeroes.
I'm currently trying to write a script so that I can add an item to the last index the array has an item in. For example, if I initialized an array int a[5] and a[0], a[1], a[2] all have something, then the integer would be added to a[3]Here is what I have :
int main(){
int a[5];
a[0] = 10;
a[1] = 20;
a[2] = 30;
for (int i = 0; i < 5; i++){
if (a[i] < 0){
a[i] = 40; //Just an example for what it would be like.
}
}
}
I can't help but feel that there is a better way to do this, maybe a different if condition. I want to know if there's another way to check if the next index is empty.
You could use an array index counter. Say, int counter = 0;
Use the counter as an index when you store integers to the array a, like a[counter] = 5 After you add an integer to your array, increment the counter, counter++.
This way you could make sure that the next value being added to the array is always added the way you described in the question
A few things to probably clear up what looks like a misunderstanding around what an array is:
When you declare an array say
int main()
{
int a[5];
for (int i = 0; i < 5; i++)
{
printf("a[%d] = %d", i, a[i]);
}
}
All elements in the array exist already. Namely, you can access a[0] ... a[4] without hitting an error. All values of the array have already been set implicitly and you can see this by seeing the output of the printf. Note that those are values that you haven't set yourself and will vary. If you're curious about why they vary, you can see this: Variable initialization in C++
To set those values explicitly, you can initialize all values in the array to 0 like so:
int main()
{
int a[5] = {0};
for (int i = 0; i < 5; i++)
{
printf("a[%d] = %d", i, a[i]);
}
}
or through use of a static initializer
int main()
{
int a[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++)
{
printf("a[%d] = %d", i, a[i]);
}
}
However because all values of the array already exist on creation, there isn't really such a state as "uninitialized array" in C++ as they are . The value of a[3] is either set implicitly or explicitly depending on how you created the array.
std::vector is a dynamically growing array, based on how much space you need. In order to have this effect, std::vector keeps track of how much of the array is "used" through use of a size variable. If you wanted to reimplement that to get an idea of how it might be done, you would probably want a class like:
class MyArray
{
public:
MyArray() : m_size(0)
{
}
void AddVal(int data)
{
if (m_size < 5)
{
m_array[m_size++] = data;
}
}
int GetSize()
{
return m_size;
}
private:
int m_array[5];
int m_size;
}
If you initialize the array to 0, you can check if the value is 0.
Initilize:
int array[5] = {0};
Check for 0:
array[4] == 0;
I would like to sort an array by increasing order of frequency. For example, if I had an array
int arr[] = { 3, 3, 10, 2, 5, 10, 10, 2, 2, 2 };
or another array would have the following sequence in it:
int arr[] = {5, 3, 3, 10, 10, 10, 2, 2, 2, 2};
However, I cannot use hashing or maps – I can only use arrays. What I have thought of is sorting the array using a quick sort algorithm, scanning the sorted array and performing the count in a 2d array so that for each element, there is a count associated with it, and then sorting by count. If two counts are same then I would merely print out the one with the lower value first. I'm having trouble implementing the last two steps. I'm not sure how to "map" a count to an index in the 2d array, nor am I sure on how to sort the 2d array by a count. Could anyone help me out? Thanks!
Scan your array (sort first to optimize, but not needed), and generate an array of the struct below. Now sort the array of these structs, then regenerate your original array.
struct ElemCount {
int Elem;
int count;
bool operator<(const ElemCount& other) {
if (count!=other.count)
return count<other.count;
return Elem<other.Elem;
}
};
That's how I'd code it without STL (requires additional O(n) memory):
// Represents a bunch of equal numbers in an array
struct Bunch
{
int x; // value of numbers
int n; // count of numbers
};
int cmp_int(const void *x, const void *y)
{
return *static_cast<const int*>(x) - *static_cast<const int*>(y);
}
int cmp_bunch(const void *x, const void *y)
{
const Bunch* bx = static_cast<const Bunch*>(x);
const Bunch* by = static_cast<const Bunch*>(y);
return (bx->n != by->n) ? bx->n - by->n : bx->x - by->x;
}
void sort_by_freq(int arr[], int arr_size)
{
// Buffer array to store counted bunches of numbers
Bunch* buf = new Bunch [arr_size];
int buf_size = 0;
// Sort input array
qsort(arr, arr_size, sizeof(int), cmp_int);
// Compute bunches
Bunch bunch;
bunch.x = arr[0];
bunch.n = 1;
for (int i = 1; i < arr_size; ++i)
{
if (arr[i] > bunch.x)
{
buf[buf_size++] = bunch;
bunch.x = arr[i];
bunch.n = 1;
}
else
{
++bunch.n;
}
}
buf[buf_size++] = bunch; // Don't forget the last one!
// Sort bunches
qsort(buf, buf_size, sizeof(Bunch), cmp_bunch);
// Populate bunches to the input array
int i = 0;
for (int k = 0; k < buf_size; ++k)
for (int j = 0; j < buf[k].n; ++j) arr[i++] = buf[k].x;
// Don't forget to deallocate buffer, since we cannot rely on std::vector...
delete [] buf;
}