Map with a vector as a parameter [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
For the Leetcode:
There are n people whose IDs go from 0 to n - 1 and each person belongs exactly to one group. Given the array groupSizes of length n telling the group size each person belongs to, return the groups there are and the people's IDs each group includes.
You can return any solution in any order and the same applies for IDs. Also, it is guaranteed that there exists at least one solution.
Example 1:
Input: groupSizes = [2,1,3,3,3,2]
Output: [[1],[0,5],[2,3,4]]
class Solution {
public:
vector<vector<int>> groupThePeople(vector<int>& groupSizes) {
unordered_map<int,vector<int> > myMap;
int n=groupSizes.size();
vector<vector<int>> answer;
for(int i=0;i<n;i++){
myMap[groupSizes[i]].push_back(i); // myMap key/value ; key= group, value=index
cout<<i<<endl;
if(myMap[groupSizes[i]].size()==groupSizes[i]){
cout<<"pushed "<<i<<endl;
answer.push_back(myMap[groupSizes[i]]);
myMap[groupSizes[i]]={};
}
}
return answer;
}
};
Does the map contain a bunch of different vectors, or is there only 1 vector?
Could you explain what exactly is being pushed? When you have map<int,vector<int>>; are you pushing the groupsize as the key, and then the value is the index?
Thus, would the map look like map[groupsize value, vector of indexes]?
How did the output get its first vector [1]? If the value 2 should of been pushed the vector first?

Does the map contain a bunch of different vectors, or is there only 1
vector?
For each key in your map, there exists one vector as a value. In your example, there are 3 vectors:
Key "1", Vector ( 1 )
Key "2", Vector ( 0, 5 )
Key "3", Vector ( 2, 3, 4 )
Could you explain what exactly is being pushed? When you have
map<int,vector<int>>; are you pushing the groupsize as the key, and
then the value is the index?
What you are pushing and where is dependent on the current value of i and n. n is set to the size of groupSizes, so 6. i ranges from 0 to 5. On the first iteration, push_back is called the following way:
myMap[groupSizes[0]].push_back(0);
groupSizes[0] has value "2", as the index 0 for [2,1,3,3,3,2] is "2"
myMap[groupSizes[0]] searches for value "2" in the map. If the key does not exist yet, it is inserted. It then returns the value; if it did not exist yet, it is created -> an empty vector will be returned.
push_back(0) the value "0" is added to the vector for value "2"
Thus, would the map look like map[groupsize value, vector of indexes]?
Yes, but note that the groupsize values are grouped within the map. There are only the values 1, 2 and 3 in it and not 2, 1, 3, 3, 3 and 2.
How did the output get its first vector [1]? If the value 2 should of
been pushed the vector first?
I think you final output code is missing, but I would guess that your output just iterates over your result vector. If that is the case, the order is just a happy coincidence. The groupSize value tells you, how many elements there will be in the vector. So the lower the groupSize value, the sooner it will be finished and pushed into the result vector. So "1" only contains one element and will be pushed first into the result vector, as if(myMap[groupSizes[i]].size()==groupSizes[i]).

Related

Retrieving values from vector at specific index through size of vector in C++

Is there any other way to access or retrieve the data/values that are in vector at a specific index through the size of the vector? I am currently looping through the vector starting at a desired index all the way to the size of vector or stopping at
lets say the values in the vector include 1 2 3 4 5 6 7 8
and I want to retrieve 3 4 5 6 7 8.
Is there any other way of sufficient way to obtain these values other than looping through the vector?
If you are trying to access and operate on values at index 2 through index 7, (3 4 5 6 7 8)
then looping through the vector to retrieve the values is the most efficient way. If you are trying to group this sub-data and keep a hard copy of your original vector then looping is still most efficient.
Example 1
std::vector<int> myVec{1,2,3,4,5,6,7,8};
for (int i = 2; i < vec.size(); i++)
{
// Do your operation on myVec[i]
// Push myVec[i] to a new list ?
}
If you are trying to obtain a new vector from your original vector which contains only the values you are interested in, then there is a better way. Note that the values 1 and 2 are now lost.
Example 2
myVec.erase (myVec.begin(),myVec.begin() + 2);
//myVec[0] now contains 3
//myVec.size() == 6
Putting Examples 1 and 2 together, if you are trying to obtain a new vector with the values at index 2 through index 7, you can use the assignment operator (=) to assign the data from an existing vector to a new one. Note that this is actually not any more efficient than looping through the vector yourself, but might look a little cleaner. After doing this then you can reference Example 2 to edit the new vector to your liking.

Counting Occurrences of integers in map c++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I am trying to see if there are any duplicates of integers as I am inserting them using map because it`s auto sorting them when the numbers are inserted.
For example when I insert integers in the following order : 2 3 2 4 5
I want an output like : at least a number is duplicated , ` I have tried many things but no success, any ideas?
The problems I am facing is this: You have a array of type integers and you have to find if there are any duplicates using map .
Use map::find
int keyToInsert = 2;
std::map<int, int>::iterator it;
it = yourMap.find(key);
if(it != yourMap.end()){
//alert user key exists
}
else {
//key doesn't exist
}
See docs: http://www.cplusplus.com/reference/map/map/find/
The way you are approaching the problem seems fundamentally wrong. std::map is a data structure used to "map" logical entities in a container.
for example it can be used to map names to phone numbers. like this:
{ ("Tom", 2344556), ("Amanda", 545654), ...}
that would be an example of std::map<std::string,int> .
a map is NOT used for keeping seperate int values together. if you want that functionality you should look into other containers.
If you want to use a container that keeps values in order (and keeps duplicates) you can use std::list or std::vector, if you want a data structure where order is not guaranteed but access is fast and duplicates are generally avoided, you can use std::set
I think you want something like (untested code):
bool check_for_duplicate(const std::map<my_key_type, int>& my_map)
{
std::set<int> my_set;
for (auto& i : my_map)
{
if (!my_set.insert(i.second).second) // If it failed to insert
return true;
}
return false;
}
Idea is to take "integers" as key and "number of repetition " as value of map .By doing so , you will not only able to figure out whether it a number was repeated but you would also figure out "how many times was it actually repeated " .I am sharing below code snippet .
#include <iostream>
#include <map>
using namespace std;
int main ()
{
int arr[10] = {1,2,3,4,1,2,2,1,4,5};
std::map<int,int> dup_map;
for(int i=0;i<=9;i++)
{
if(dup_map.find(arr[i])!=dup_map.end())
{
//key exist and hence update the dulpicate count;
dup_map[arr[i]]++;
}
else{
//it doesn't exist in map
dup_map.insert(std::pair<int,int>(arr[i],1));//single count of current number
}
}
for(std::map<int,int>::iterator it =dup_map.begin();it!=dup_map.end();it++)
{
cout<<"\n Number "<<it->first<<" is repeated "<<it->second<<" times ";
}
}
Output of the program is as below :
Number 1 is repeated 3 times
Number 2 is repeated 3 times
Number 3 is repeated 1 times
Number 4 is repeated 2 times
Number 5 is repeated 1 times

How to count number of pairs in a array? Need explanation for the given code [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Need explanation for the given code, I want to know what are the return types. Here the freq map is returning what? And what's the need to increment freq[p[i]]++;
#include <map>
#include <utility>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
#define ll long long int
map<int,int> freq;
int CountPairs(int P[], int L, int R) {
int count = 0;
for (int i = L; i <R; ++i) {
count += freq[P[i]];
++freq[P[i]];
}
return count;
}
int main()
{
int n,a[2000];
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
cout<<CountPairs(a,0,n);
return 0;
}
Thanks in advance.
map[K] will return the value corresponding to key K from the map.
If map[K] does not exist, it will call the default initializer for the value type and create a mapping. In this case, the type is int, so it will initialize the mapping to 0. On subsequent accesses, you will always get the current value of the mapping, which is incremented each time a value is found.
So for each duplicate, you're adding the number of occurrences of that value found in the array so far.
If you sum that up, the result will be:
where L is the left limit, R the right limit and Ni the number of occurrences of i in the array.
The code has multiple issues, though. You're reading n values into a statically sized array. If n is larger than 4000, you will overwrite the stack. Also, a global variable is used to keep the number of pairs for each value. If you call CountPairs multiple times, the numbers will increase. This is probably not what you want.
map<int,int> freq;
count += freq[P[i]];
freq[P[i]] // create a pair within map with value 0 and key with `P[i]`
++freq[P[i]] increments the value with key as P[i] by 1.
So after first iteration value will be 1 and count will be zero.
So if there is pair, or triplet or quadruplet or etc, we will increment count+1.
By taking some insight from onitake, if there are 2 elements with same value, there will be one pair, if there are 3 elements with same value there will be 2 pairs.
Key cnt value
1 0 1
2 1 2
3 2 3
4 3
As said, if you are using it to count distinct pairs, it will fail, if there are same data repeats more than twice.

Which dataset should I use?

The title may have been a bit vague, but I will appreciate some ideas for the current problem I have.
Here is a dataset:
1 1/1/2013
2 1/1/2013
3 1/1/2013
1 1/2/2013
2 1/2/2013
1 1/3/2013
2 1/3/2013
3 1/3/2013
So, I begin with the first record, and see if there is another 1 in my list. If there is, I ignore it, and go back to the second record. If there is another 2 in my list, I ignore it, and go back to the 3rd record, and so on and so forth.
Now, the desired result of this list, that I am looking for is <1, 1/3/2013>, since no other record of 1 exists below it.
Similarly, in this dataset:
1 1/1/2013
2 1/1/2013
3 1/1/2013
1 1/2/2013
2 1/2/2013
3 1/2/2013
4 1/2/2013
1 1/3/2013
2 1/3/2013
3 1/3/2013
The desired result would be <4, 1/2/2013>, since there is no other occurrence of 4 down the list.
My question is, how would I go about doing this, what standard STL container can I use? Further more, these are the results returned by a query.
I am sorry I don't use boost or any of the other libraries, and looking to get this done with std variables.
You can use two maps - one map to store mapping from the key (your first column) to the value (your second column) and second map to store mapping from the key (your first column) to the record number:
std::map<int, std::string> m1;
std::map<int, int> m2;
int counter = 0;
while (...)
{
<...get record...>
m1[record.key] = record.value;
m2[record.key] = counter++;
}
Then you need to scan the second map m2 in order to find the key with minimal position:
int keyMin = <...big number...>, posMin = <...big number...>;
for (std::map<int, int>::const_iterator it = m2.begin(); it != m2.end(); ++it)
{
if (it->second < posMin)
{
keyMin = it->first;
posMin = it->second;
}
}
The result will be the first key, for which there are no records with this key down the road. Using this key and the first map m1 you'll be able to find its corresponding value.
You can check from the bottom, and remember the first(last when counting from the top) appearance of each index. And after You've done this (in time O(n)) You can take the last You found.
What does query return? You can choose std::vector<some-structure> if it returns a known structure, or std::vector<std::vector<std::string> > if it returns a string list.
Then going from bottom and remembering all unique ids that you see you are able to get the last good value in o(n) time and o(n) memory.

Vector of pairs to map

I have a little problem.
I have a vector of pairs patternOccurences. The pairs are <string,int>, where string is the pattern(name) and int the index where it appears. My problem is that patternOccurences has multiple pairs with the same .first(same pattern) but different int values.
For example: The vector has 10 entries. 5 of pattern "a" and 5 of pattern "b". all have different indices. Now i want to have a map (or something similar) so that i have a vector/list with each pattern(in my example "a" and "b") as a key and a vector of their indices as the value. The indices are in the different pairs in my vector of pairs and i want all indices for pattern "a" in a int vector as value for key "a".
I tried the following:
std::map<std::string,std::vector<int>> occ;
for(int i = 0;i<patternOccurences.size();i++){
if(occ.find(patternOccurences.at(i).first)==occ.end()){
occ[patternOccurences.at(i).first]=std::vector<int>(patternOccurences.at(i).second);
}
else{
occ[patternOccurences.at(i).first].push_back(patternOccurences.at(i).second);
}
}
patternOccurences is the vector of pairs and occ the desired map. First i check if there is already an entry for the string(pattern) and if not i create one with a vector as value. If there is already one I try to push_back the vector with the index. However it doesnt seem to be working right. For the first pattern i get a vector with 0 only as values and for the second there are only 3 indices which are right and the other ones are 0 as well.
I hope you can help me.
Kazoooie
You are calling the constructor for the vector in the wrong way:
std::vector<int>(patternOccurences.at(i).second);
This creates a vector with N default constructed elements, not a vector with one element with value N. You need:
std::vector<int>(1, patternOccurences.at(i).second);
That should fix the problem, but your code doesn't have to be that complicated. The following would work just fine:
for(int i = 0;i<patternOccurences.size();i++){
occ[patternOccurences.at(i).first].push_back(patternOccurences.at(i).second);
}
or with C++11, the even simpler:
for(auto& p:patternOccurences) {
occ[p.first].push_back(p.second);
}
What you are asking for already exists in STL and it's called std::multimap (and std::unordered_multimap).
Take a look here. Basically it's a map which allows more values to have the same key.
std::multimap<std::string, int> occ;
occ.insert(std::pair<std::string,int>("foo", 5));
occ.insert(std::pair<std::string,int>("foo", 10));
std::pair<std::multimap<std::string,int>::iterator, std::multimap<std::string,int>::iterator> group = occ.equal_range("foo");
std::multimap<std::string,int>::iterator it;
for (it = ret.first; it != ret.second; ++it) {
..
}
Change this statement
occ[patternOccurences.at(i).first]=std::vector<int>(patternOccurences.at(i).second);
to
occ[patternOccurences.at(i).first]=std::vector<int>(1, patternOccurences.at(i).second);