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

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

Related

Issue with leet code problem 3 Longest substring [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 3 months ago.
Improve this question
Essentially we are asked to find, given a string, the longest substring with no repeating characters, below I am using the sliding window approach.
Examples:
Input: s = "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
Input: s = "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Input: s = "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
My attempt:
class Solution {
public:
int lengthOfLongestSubstring(std::string s){
int count{0};
std::map<char,int> char_map;
std::vector<char> char_vec;
auto left{char_vec.begin()};
auto right{char_vec.begin()};
for(int i = 0; i < s.length(); i++){
char_vec.push_back(s[i]);
if(char_map.find(s[i]) != char_map.end()){
char_map[s[i]]++;
}
else{
char_map.insert(std::pair<char,int>{s[i],1});
}
while(++right != char_vec.end() && char_map[*(right)] > 1){
char_map[*(left++)]--;
}
count = (count < std::distance(left,right)) ? std::distance(left,right) : count;
}
return count;
}
};
However, there is an issue in the while loop near the end of the code block that is causing
compiler error and am very confused about how to solve it.
So your code is suffering from iterator invalidation. Here you have a vector
std::vector<char> char_vec;
and here you create two iterators to that vector
auto left{char_vec.begin()};
auto right{char_vec.begin()};
and then here you add an item to that vector
char_vec.push_back(s[i]);
When you add an item to a vector you may invalidate any iterators to that vector, and any use of such iterators causes your program to have undefined behaviour.
Instead of using iterators you could try using offsets (i.e. integer variables which you use to index the vector). These have the advantage that they are not invalidated as the vector grows.
For more information on iterator invalidation see the table on this page. Different containers have different behaviour wrt iterator invalidation.

How to optimise this code of sorting,this is not exeuting within the time limits.This question is from hackerrank [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 2 years ago.
Improve this question
How to reduce the time compexity of this code,this is not exeuting within the time
exact ques from hackerrank--
Complete the circularArrayRotation function in the editor below. It should return an array of integers representing the values at the specified indices.
circularArrayRotation has the following parameter(s):
a: an array of integers to rotate
k: an integer, the rotation count
queries: an array of integers, the indices to report
vector<int> circularArrayRotation(vector<int> a, int k, vector<int> queries) {
int i,temp;
vector<int> ans;
//to perform number of queries k
while(k--)
{ //shift last element to first pos and then move rest of elements to 1 postion forward
temp=a[a.size()-1]; //last element
for(i=a.size()-1;i>0;i--)
{
a[i]=a[i-1];
}
a[0]=temp;
}
for(i=0;i<queries.size();i++)
{
ans.push_back(a[queries[i]]);
}
return ans;
}
The vector a is being rotated by k in the while loop. The whole loop can be removed by adding k and using modulo when accessing elements in a:
ans.push_back(a[(queries[i]+k)%a.size()]);
Note: you might need handling of negative values of k.
Note: Maybe it should be minus instead of plus.
An alternative could be to use std::rotate.
Furthermore, the ans vector should be pre-allocated to reduce the number of allocations to one:
ans.reserve(queries.size());

How to iterate over unique elements in an array in c++ [closed]

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 4 years ago.
Improve this question
Suppose I have the following array:
int arr[7] = {18,16,5,5,18,16,4}
How can I iterate over unique elements(18, 16, 5 and 4) in a loop in the same order in which they occur?
I could use a set but then the order of the iteration would change(set stores elements in ascending order).
What is the fastest solution to this problem?
Iterate over the array and store the numbers you have already seen in a set. For each iteration you check whether the number is already in the set or not. If yes, skip the current element. If not, process it and insert it into the set.
Also note that you want an std::unordered_set and not a std::set which is ordered. Order doesn't matter for your filtering set.
If the values are in a known limited range, you can use a lookup table. Create an array with bool elements, sized to maximum value + 1. Use the values of the first array as index into the bool array.
#include <iostream>
int main() {
int arr[7] = {18,16,5,5,18,16,4};
constexpr int maxValue = 18;
bool lookup[maxValue + 1]{};
for( auto i : arr )
{
if( ! lookup[ i ] )
{
std::cout << i << ' ';
lookup[ i ] = true;
}
}
}
Live Demo
A std::bitset would be more space efficient but also slower, because individual bits cannot be directly addressed by the CPU.
Simply replace the bool array like so:
std::bitset<maxValue + 1> lookup;
The remaining code stays the same.
Live Demo

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.

How to get sorted elements from an starting index to a ending index in an array? [closed]

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 9 years ago.
Improve this question
Given an array of t integers we need to answer x queries.Each query describes an starting index and a ending index ,we need to print the sorted elements in the sub-array.
For Example-
Array={16,9,10,19,2}
for query 1 3 ,the answer would be
9 10 16
for query 2 5,the answer would be
2 9 10 19
Please suggest an optimal solution?Are there any advanced data structures involved?
The number of elements can be upto 10^5 .
Tag each element with it's position:
16 1, 9 2, 10 3, 19 4, 2 5
Sort it:
2 5, 9 2, 10 3, 16 1, 19 4
For each query walk through the result and return the elements which are within the range.
After preprocessing each query takes O(N) work.
Are there any advanced data structures involved?
Nope, not at all. First you obtain the range given by those indexes, then you sort the resulting range. Then you print it. Seems pretty simple!
In fact, it's so simple, I'm going to show you an example:
#include <algorithm>
#include <vector>
#include <iostream>
#include <cassert>
template <typename T, size_t N>
size_t len(T (&)[N])
{
return N;
}
int main()
{
int array[] = {16,9,10,19,2};
const int START = 1; // user input ( 1-based index,)
const int END = 3; // user input (inclusive range)
assert((START-1) >= 0 && (START <= len(array)));
assert((END-1) >= 0 && (END <= len(array)));
// These two lines do the work.
// Everything else is just exposition.
//
// First construct a vector from the requested subrange,
// then sort that resulting vector.
//
std::vector<int> v(array+(START-1), array+END);
std::sort(std::begin(v), std::end(v));
// Output the results to console for demo.
// Uses C++ ranged-for syntax; replace with more
// verbose equivalent if required, or do something
// else with `v`.
//
for (auto elm : v) {
std::cout << elm << ' ';
}
}
// Output: 9 10 6
Live demo
You could make the code even terser (and possibly more efficient) by copying the subrange into an std::set rather than a std::vector, so sorting happens during insertion rather than after-the-fact. I hardly think either is ever going to be as much as O(n^2), contrary to your claims.
Can you do sufficient preprocessing to share information between individual queries and get your complexity down still further? I don't know. I don't think so.
If I understood your question: Sort it.
You can use any sorting algorithm you want, Wikipedia lists a few.
Depending on which algorithm you choose, you may need extra memory / data structures.
If sorting should come later, copy the array and sort the copy. Makes more sense, than sorting over and over again for every query.