How to get indexes for values in array - c++

I need to write a function that takes as argument 2d array. Each element of array has an Integer value.
As input i have a 2D array for example:
[1][1][2][2]
[2][1][2][2]
[3][3][3][3]
[22][.......
and as output I need to store indexes for each value :
value = 1 : [0,0] ; [0,1] ; [ 1,1]
value = 2 : [1,0] ; ....
value = 3 : [2,0] ; .......
value = 22 : [.........
Size of array may be various, same as number of values.
Is it somehow possible to save that data to vector, or any other data type so later i could read those values and their indexes?
Sorry if something is unclear, Its my 1st post here:)
Cheers
Edit:
so ok what I tried to do: I created a class Indexes
class Indexes
{
public:
int x;
int y;
};
and later i created a vector vect;
and i tried to add indexes to that vector. The problem was when i tried to keep values separated for examlpe
for(int i=0 ; i<size ; i++){
for(int i=0 ; i<size ; i++){
if(array[i][j].value = 1)
Indexes ind(i,j);
vect.push_back(ind);
}
}
but all I could get is vector with only 1 values and its indexes stored;

You can store this index in a map of vectors of pairs, for example.
Here's some sample code:
typedef std::pair<int, int> ElementIndex;
typedef std::vector<ElementIndex> IndexList;
typedef std::map<int, IndexList> ValuesIndexMap;
So ValuesIndexMap is a map from value to a vector of all indices in which this value is stored in, where an index (type ElementIndex) is a pair of ints - row and column.

Related

C++: Store mapping between old int handles and new ones

I have an array with struct elements. I need to remove some elements from the array and store mapping between old values ​​and new ones.
I.e, fill std::map, the key of which is the old index of the element from the array and Its value is the new index from the array. (Because when values ​​are removed from the vector, it is shifted to the left.)
I will show what I need with an example:
0 1 2 3 4 5 6
arr0 = {a, b, c, d, e, f, g}
0 1 2 3 4 5
arr1 = {a, b, c, e, f, g} //after delete d
map[0]=0 // a
map[1]=1 // b
map[2]=2 // c
map[4]=3 // e
map[5]=4 // f
map[6]=5 // g
Help me to implement this.
I have an array from structures:
struct HalfEdgeHandle { int64_t index = -1; };
std::vector<HalfEdgeHandle> halfEdges = {};
I need to remove the elements of the array which halfEdges[i].index == -1
As long as I have understood your question, this should be the solution:
struct HalfEdgeHandle {};
std::vector<HalfEdgeHandle> halfEdges = {};
// Here store your data into the vector
std::map<int, int> map;
std::vector<HalfEdgeHandle> copy;
int j = 0;
for(int i = 0; i < halfEdges.size(); i++)
{
if(halfEdges[i].index != -1)
{
copy.append(halfEdges[i]);
map[i] = j++;
}
}
copy should be the std::vector without any element which has index == -1. map will look like as you described.
Let me point out two things:
Consider changing the map and copy variable names into something that makes more sense in your code
Consider changing how you store the previous indexes and the new ones. I would swap the key-value pair, so you have continuous indexes. If you do this, you can use std::vector instead of std::map (I usually tend to avoid using std::map when not mandatory).

How can I insert multiple numbers to a particular element of a vector?

I am quite new to C++ and vector. I am calculating two things say 'i' and 'x' and I want to add 'x' that belongs to a particular vector element 'i'. I learned that if I have one 'x' value, I can simply do that by 'vec.at(i) = x'. But what if I want to add several 'x' values to a particular 'i' index of a vector?
Let's try to make it clear: Let's say I am searching for number '5' and '3' over a list of numbers from 1 to 10 (5 and 3 can occur multiple times in the list) and each time I am looking for number 5 or 3 that belong to index '2' of 'vec' I can do 'vec.at(2) = 5' or 'vec.at(2) = 3'. Then what if I have two '5' values and two '3' values so the sum of the index '2' of 'vec' will be '5+5+3+3' = 16?
P.S: using a counter and multiply concept will not solve my problem as the real problem is quite complicated. This query is just an example only. I want a solution within vector concept. I appreciate your help in advance.
If you know how many indices you want ahead of time, then try std::vector<std::vector<int>> (or instead of int use double or whatever).
For instance, if you want a collection of numbers corresponding to each number from 0 to 9, try
//This creates the vector of vectors,
//of length 10 (i.e. indices [0,9])
//with an empty vector for each element.
std::vector<std::vector<int>> vec(10, std::vector<int>());
To insert an element at a given index (assuming that there is something there, so in the above case there is only 'something there' for elements 0 through 9), try
vec.at(1).push_back(5);
vec.at(1).push_back(3);
And then to take the sum of the numbers in the vector at index 1:
int sum = 0;
for (int elem : vec.at(1)) { sum += elem; }
//sum should now be 8
If you want it to work for arbitrary indices, then it should be
std::map<int, std::vector<int>> map;
map[1].push_back(5); //creates an empty vector at index 1, then inserts
map[1].push_back(3); //uses the existing vector at index 1
int sum = 0;
for (int elem : map.at(1)) { sum += elem; }
Note that for std::vector and std::map, using [] do very different things. Most of the time you want at, which is about the same for both, but in this very specific case, [] for std::map is a good choice.
EDIT: To sum over every element in every vector in the map, you need an outer loop to go through the vectors in the map (paired with their index) and an inner loop like the one above. For example:
int sum = 0;
for (const std::pair<int, std::vector<int>>& index_vec : map) {
for (int elem : index_vec.second) { sum += elem; }
}

Does anyone know how to solve problems on variable length arrays?

Input Format
The first line contains two space-separated integers denoting the respective values of (the number of variable-length arrays) and (the number of queries).
Each line of the subsequent lines contains a space-separated sequence in the format k a[i]0 a[i]1 … a[i]k-1 describing the -element array located at.
Each of the subsequent lines contains two space-separated integers describing the respective values of (an index in the array ) and (an index in the array referenced by ) for a query.
Output Format-
For each pair of and values (i.e., for each query), print a single integer denoting the element located at an index of the array referenced by. There should be a total of lines of output.
Sample Input
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
Sample Output
5
9
Somebody has solved this problem by -
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int n,q; //n number of variable lenght arrays
// q no of queries asked
cin >>n >>q;
int ** Vectors = new int *[n];//no of length of var. arrays
int j;
for (int i=0;i<n;i++)
{
cin>>j;
Vectors[i] = new int [j];
for (int y=0;y<j;y++)
cin>>Vectors[i][y];
}
int q1,q2;
for (int i=0;i<q;i++)
{
cin >>q1 >> q2;
cout<<Vectors[q1][q2]<<endl;
}
return 0;
}
Can somebody explain me this code? Or if anyone has a better approach to solve this problem. Then please explain it in detail.
This shouldn't be hard to understand, that code is basically initializing dynamic 2D array at run time then inserting values to the 2D array and then accessing it by giving index:
int ** Vectors = new int *[n];//no of length of var. arrays
int j;
for (int i=0;i<n;i++)
{
cin>>j;
Vectors[i] = new int [j]; // initialzing inner array.. consider it as 2D array with n rows and j columns
for (int y=0;y<j;y++)
cin>>Vectors[i][y]; // insert element at specified index
}
cout<<Vectors[q1][q2]<<endl; // access element from 2D array
What you might want to use is a Matrix class.
Using
vector<vector<int>>
should do it.
Alternatively the snipet code should be refactored into a Matrix class with a constructor and a destructor.
The example you give present a memory leak since the allocated memory is not freed.

Handling duplicate values while merging k sorted arrays

I am trying to merge k sorted array of structs into a single one. I know the algorithm of using a min heap to merge the arrays. I am using priority_queue in C++ to implement the heap. My code looks like below.
struct Num {
int key;
int val;
}
// Struct used in priority queue.
struct HeapNode
{
Num num; // Holds one element.
int vecNum; //Array number from which the element is fetched.
int vecSize; // Holds the size of the array.
int next; // Holds the index of the next element to fetch.
};
// Struct used to compare nodes in a priority queue.
struct CompareHeapNode
{
bool operator()(const HeapNode& x, const HeapNode& y)
{
return (x.num.key < y.num.key) || ( (x.num.key == y.num.key)&&(x.num.val < y.num.val) );
}
};
vector<vector<Num>> v;
priority_queue< HeapNode, vector<HeapNode>, CompareHeapNode> p_queue;
//Insert the first element of the individual arrays into the heap.
while(!p_queue.empty())
{
Num x = p_queue.top();
cout << x.num.key << ' ' << x.num.val << '\n';
p_queue.pop();
if(x.next != x.vecSize) {
HeapNode hq = {v[x.vecNum][x.next], x.vecNum, x.vecSize, ++x.next};
p_queue.push(hq);
}
}
Let's consider 3 sorted arrays as shown below.
Array1: Array2: Array3:
0 1 0 10 0 0
1 2 2 22 1 2
2 4 3 46 2 819
3 7 4 71 3 7321
Now the problem is there can be some elements common among the arrays as show above. So while merging the arrays, duplicate values appear in the sorted array.
Are there any ways to handle duplicate keys?
So your question is that is there a way to check if the value you were inserting into the list were already in the list. Only if you could check that.
One solution is to use a hash table (unordered_set). Before inserting, check if element exists in it. If not, then insert that element in list and hash table.
But you can do better. Since you are merging sorted arrays, the output is also sorted. So, if duplicates exists, they will be together in the output array. So, before inserting, check the value with the last value of the output.

sort n-dimension point and keep track of original index

I have a set of n- dimension point store in vector< vector<double> >
ex A[0][1].............[N], and A[0][0] = X, A[0][1] = Y, A[0][2] = Z
and I want to sort the vector of all of the dimension
ex sort X, Y, Z ,.........N in ascending order
ex A[0] = (1,5,3), A[1] = (3,2,1) A[2] = (2,8,4) after sorting
index: 0 1 2
A[0] = (1,5,3), A[1] = (2,8,4) A[2] = (3,2,1)
original index : 0 2 1
I find that sort(vector.begin(), vector.end()) can sort it but how can I record the original index with a additional vector?
Is there a algorithm or C++ feature can solve it?
Thx in advance.
You need to somehow keep the information about the index.
I can see two ways of doing this :
1-Since you represent your point by a vector, you can had another dimension that will represent the orginal index :
//Adding index info, inportant that your index be the last dimension , otherwise the sort is incorrect
for(auto point = vector.begin(),unsigned int index=0;point != vector.end(); ++point,++index){
point->push_back(index)
};
Then sort the same way you are doing now :
sort(vector.begin(), vector.end())
and you access the original index with A[0][n]
The cool thing about that is that it allow you to keep track of the index in a very convenient way, but you need to be able to modify the representation of your point.
2- The other way is to have an external table of indices and sort that using custom comp. operator :
you start by creating a vector of indices
std::vector indices(vector.size());
for(unsigned int index =0;index != indicies.size(); ++point){
indicies[index] = index ;
};
//and sort...
std::sort(indices.begin(),indices.end(),[&](unsigned int i,unsigned int j) { return vector[i] < vector[j]})
now you need an additional level of indirection to go trough your points in the sorted order :
A[indices[0]],A[indices[1]],...
So the original position of A[indices[x]] is simply x
The main to remember between those two ways of doing it is that in the first you move your data around and not in the second , depending on what you are doing on your points, one might be better that the order