Let's say I have a 2D array and I want to pass it's i th column to a sort function that takes in a 1D array and sorts it.
Can it be done without copying the column to another array in C/C++ language. I am concerned about reducing time and space used. (Ofcourse the complexity remains same)
I suppose that by sort you mean std::sort from STL, which takes random access iterators. So all you need to do is provide column iterators.
You can either implement one by yourself (example), use some iterator library (ie. Boost.Iterator) or use some matrix implementation which provides row/column iterators.
If you can write your own sort function, it's rather easy; you just make the interface like this:
void Sort (T a [], size_t n, size_t stride);
The key is in the stride parameter, which is the distance between the elements of this "virtual" array. For example, if you have a float x [10][20]; and you want to send its column #2, you'd do this: (some casts omitted for clarity)
Sort (x[0] + 2, 10, 20); // Usually, stride is the width of the 2D array
Inside the Sort function, you access the ith element of an array that has a stride like this:
a[i * stride] = 42;
That's it.
You can use the same principle to write your own MatrixColumnView class that wraps up this concept and can be passed into templated functions that take arrays.
If you want to work with STL or STL-like libraries, you can simply write your own MatrixColumnIterator iterator class that essentially uses an stride internally and gives iteration over a column of a 2D array.
As far as i know, the multidimensional array storage in C/C++ is actually a 1D-arrary,
which you can refer a very good explanation in this post : How to get column of a multidimensional array in C/C++?
Therefore I do not think there's any default / easy method to extract a particular column of a 2D array and pass it to another function.
Related
I am new to C++ and wanted to create a class for matrix and found two methods:
allocating one block of memory (which is faster as I read)
allocating multiple blocks (one for each line which is slower)
But what is better?
on the one hand I can use the second like mat[i][j] which doesn't work with the first method.
and I need to write a function that multiplies matrixes and I'm afraid that the first method will make things really hard when trying to access members
Where did you read that? 2-dimensional matrix can be represented both as a 1-dimensional array or 2-dimensional array. It's just a matter of references with 2 index. So for an element of having index row and col you can get its 1-dimensional index like this: row * matrix_width + col. So there's no impact on the speed besides calculating this index formula.
I am working on clustering problem where I have something called distance matrix. This distance matrix is something like:
the number of nodes(g) are N (dynamic)
This matrix is Symmetric (dist[i,j]==dist[j,i])
g1,g2,.... are object (they contain strings , integers and may even more..)
I want to be able to reach any value by simple way like dist[4][3] or even more clear way like dist(g1,g5) (here g1 and g5 may be some kind of pointer or reference)
many std algorithm will be applied on this distance matrix like min, max, accumulate ..etc
preferably but not mandatory, I would like not to use boost or other 3rd party libraries
What is the best standard way to declare this matrix.
You can create two dimensional vector like so
std::vector<std::vector<float> > table(N, std::vector<float>(N));
don`t forget to initialize it like this, it reserves memory for N members, so it does not need to reallocate all the members then you are adding more. And does not fragment the memory.
you can access its members like so
table[1][2] = 2.01;
it does not uses copy constructors all the time because vector index operator returns a reference to a member;
so it is pretty efficient if N does not need to change.
So I want to create an array of nine elements, but I want the indices to be specified by me, that is, instead of accesing elements of my array,
std::array<bool,9> myarray
using myarray[0], myarray[1], myarray[2]... I want to access them, for example, as
myarray[21], myarray[34], myarray[100], myarray[9], myarray[56]...
But still conserving the properties of standard library array and storing only 9 elements.
More specifically, I need an easy access to the elements of a boolean matrix.
That is, suppose I have the matrix:
Array<array<bool,100>,100> mymatrix;
And that it is going to be used for checking certain positions (Say position x,y) easily simply using mymatrix[x][y]. I also know that some of the elements are never going to be checked, so they are not really needed. In order to save the most memory possible, the idea is to get rid of those not needed elements, but still conserving the structure to check my elements.
Such an array is best represented with one of the associative containers provided by the Standard C++ Library - i.e. either a std::map<int,bool> or an std::unordered_map<int,bool>. These containers provide an idiomatic way of doing this in C++.
One added benefit of using an associative container is the ability to iterate the values along with their external "indexes".
If you insist on using an array to store the values, you would have to make your own class that builds a "mapping" between external and internal indexes. This would either take a significant amount of memory for an O(1) access time, use CPU cycles for binary search plus an index-to-index map, use linear search, or hard-code the external indexes.
On the first glance, what you want is an std::map<int, bool>, which allows you to have your own indices. But, map is not fixed in size.
In order to get both fixed size and custom indices, you may combine a map and an array with a custom add and access functions:
map<int, bool> indices; // fill it with custom indices mapped onto the array
array<bool, n> data;
bool get(int index) {
return data[map(index)]
}
What is the complexity of boost::multi_array reshape() function? I expect it to be O(1) but I can't find this info in the documentation. The documentation for this library is actually pretty scarce.
The reason I'm asking is that I would like to iterate through a multi_array object using a single loop (I don't care about array indices). It seems like the library doesn't provide a way of iterating through an array using a single iterator. So, as a workaround, I'd like to reshape the array along a single dimension first (with other dimensions set to 1). Then I can iterate through the array using a single loop. However, I'm not sure how efficient the reshape() operation is.
Hence my second question: Is there an easy way to iterate through all the elements of a multi-array object using a single loop?
Below is the implementation of reshape function in multi_array_ref.hpp file.
template <typename SizeList>
void reshape(const SizeList& extents) {
boost::function_requires<
CollectionConcept<SizeList> >();
BOOST_ASSERT(num_elements_ ==
std::accumulate(extents.begin(),extents.end(),
size_type(1),std::multiplies<size_type>()));
std::copy(extents.begin(),extents.end(),extent_list_.begin());
this->compute_strides(stride_list_,extent_list_,storage_);
origin_offset_ =
this->calculate_origin_offset(stride_list_,extent_list_,
storage_,index_base_list_);
}
It looks like the function just re-indexes the elements in extents object associated with array size. The function is linear in the number of elements in extends. But I think it's complexity is constant in the total number of elements in the array.
I have an assignment in which I must read a list of 4000 names from a text file and sort then into a C style array as they're being read in (rather than reading them all then sorting). Since this is going involve a lot elements changing indices would it be possible to use bitshifting to rearrange large quantities of elements simultaneously?For example,
declare a heap based array of 20 size
place variable x index 10
perform a bitshift on index 9 with the size of the array data type so that x is now in index 11
Also, if you have any tips on the task in general I'd appreciate it.
No, that doesn't sound at all like something you'd use bitshifting for.
You will have distinct elements (the names) stored in an array, and you need to change the order of entire elements. This is not what bitshifting is used for; it is used to move the bits in a single integer to the left or to the right.
You should just learn qsort().
Not sure about the "sort as they're being read in" requirement, but the easiest solution would be to just call qsort() as each name is added. If that's not allowed or deemed too expensive, think about how to do a "sorted insert" against an array.
By the way, a typical approach in C would be to work with an array of pointers to strings, rather than an array of actual strings. This is good, since sorting an array of pointers is much easier.
So you would have:
char *names[4000];
instead of
char names[4000][64 /* or whatever */];
This would require you to dynamically allocate space for each name as it's loaded though, which isn't to hard. Especially not if you have strdup(). :)
If using qsort() is not allowed(would be pretty stupid to do so after every insert), you could write your own insertion sort. It's not exactly a very efficient way of sorting large arrays but I suppose it's what your teacher is expecting for.