Using "find" to access a value in vector - c++

So I have been brushing up a bit on c++ and found out I am very rusty in comparison to my other languages. I have been working on this problem from codewars.com
Given a list lst and a number N, create a new list that contains each number of lst at most N times without reordering. For example if N = 2, and the input is [1,2,3,1,2,1,2,3], you take [1,2,3,1,2], drop the next [1,2] since this would lead to 1 and 2 being in the result 3 times, and then take 3, which leads to [1,2,3,1,2,3].
To accomplish this task I wanted to create a multidimentional vector to hold unique values of the provided list in the first dimension and corresponding number of occurences in the second dimension. However, I was unfamiliar with c++'s syntax to accomplish this, so I just made 2 separate vectors.(instances, countOfInstance)
Essentially what my algorithm will do is:
loop through the provided array(arr)
check to see if the value in "arr" does not exists in "instances"
If not found then push the value in "arr" to "instances",
add a counting value of 1 that corresponds to this index in "countOfInstance"
and then add the value in "arr" to the nFilteredVector.
If the value in "arr" is found in "instances" then:
Find the index value of "arr" in "instances"
Use this index to find its corresponding count value in "countOfInstances"
Determine if the count is less than the provided "N"
if less than "N" add to "nFilteredVector"
Then increment the value in "countOfInstances"
However, when I try to access the index of "CountOfInstances" with index of "instances" i get an odd error
no viable overloaded operator[] for type 'std::vector'
if (countOfInstances[std::find(instances.begin(), instances.end(),arr[i])] <=2){
Correct me if I am wrong, but it is my understanding that the find function returns the index value of the found element. I was wanting to use that index value to access "countOfInstances" vector.
Can someone please help me figure out the correct syntax of what I am looking for. Bonus points for integrating "instances" and "countOfInstance" as a multidimentional vector!!
#include <algorithm>
std::vector<int> deleteNth(std::vector<int> arr, int n)
{
std::vector<int> nFilteredVector;
std::vector<int> instances;
std::vector<int> countOfInstances;
for (int i =0; i < arr.size();i++){
if(std::find(instances.begin(), instances.end(),arr[i])==instances.end()){//value not found need to add corresponding value to instances vector then add an element of 1 to the correpeonding index of the countOfInstance vector.
instances.push_back(arr[i]);
countOfInstances.push_back(1);
nFilteredVector.push_back(arr[i]);
}else{ // value is found just need to increment the value in countOfInstances
//find the instance of the value in arr in the instance vector, use that value to find the corresponding value in countOfInstance
if (countOfInstances[std::find(instances.begin(), instances.end(),arr[i])] <=n){
nFilteredVector.push_back(arr[i]);
}
countOfInstances[std::find(instances.begin(), instances.end(),arr[i])]++;
}
return nFilteredVector;
}
Here are some examples of what codewars will be testing for
{
Assert::That(deleteNth({20,37,20,21}, 1), Equals(std::vector<int>({20, 37, 21})));
Assert::That(deleteNth({1,1,3,3,7,2,2,2,2}, 3), Equals(std::vector<int>({1, 1, 3, 3, 7, 2, 2, 2})));
}

If what you are trying to achieve is get the index of the found item in a std::vector, the following does this job using std::distance:
#include <algorithm>
#include <vector>
auto iter = std::find(instances.begin(), instances.end(),arr[i]);
if ( iter != instances.end())
{
// get the index of the found item
auto index = std::distance(instances.begin(), iter);
//...
}

I believe std::find return an iterator on instances. You cannot use an iterator from one list on another and you cannot use an iterator as an index.
What you could do is use
std::find(instances.begin(), instances.end(), arr[i]) - instances.begin()
as your index. This is a bit ugly, so you might also want to look a bit more at iterators and how to use them.

Related

recursive function in vector passed by reference

i am learning data structure on c++ and i have come through one thing which is hard for me to understand or get concept.
I am just putting question to give better context.
https://leetcode.com/problems/frequency-of-the-most-frequent-element/
The frequency of an element is the number of times it occurs in an array.
You are given an integer array nums and an integer k. In one operation, you can choose an index of nums and increment the element at that index by 1.
Return the maximum possible frequency of an element after performing at most k operations.
Example 1:
Input: nums = [1,2,4], k = 5
Output: 3
Explanation: Increment the first element three times and the second element two times to
make nums = [4,4,4].
4 has a frequency of 3.
this is the code given to complete:
class Solution {
public:
int maxFrequency(vector<int>& nums, int k) {
}
};
i want to solve this problem by recursive first but my problem here is that the function is getting reference of a vector as a parameter so if i change the value inside the function, it will change the original vector.
I am not able to think how can i make different recursion with different choices because it is not pass by value.
Any help please !!

Iterating over a column of a multidimensional array with std::count_if()?

I have a multidimensional array of type double (double someArray[10][20]). I'd like to:
a) use std::count_if() to iterate over a single column of that array, returning the number of values greater than some number
b) also require that the row index of that number is within a certain range.
I know the basics of using std::count_if (i.e. I know how to iterate over, say, some vector and return values greater than/less than/equal to some value, for example), but I'm not sure how to do this over a column of a multidimensional array, or how to check that the index of the element also satisfies some condition.
If you are willing to use boost::range, you can use the count_if with a stride count.
The reason why this will work is that an array, regardless of the number of dimensions, will store its data in contiguous memory, thus random-access iteration will work exactly as it would a one-dimensional array.
Thus the goal is to figure out the starting column (easy), and instead of iterating one element at a time forward as you would with the "normal" std::count_if, you want to iterate (in your case) 20 elements, since iterating that many will take you to the next row of the column you're interested in.
For a 2D array of M x N size, the starting and ending addresses you would use for the STL algorithm functions would be:
start: &array2D[0][0]
end (one item passed the end): &array[M-1][N]
Given this information, here is an example using boost:
#include <boost/range/adaptor/strided.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm.hpp>
#include <algorithm>
#include <iostream>
#include <numeric>
int main()
{
using namespace boost::adaptors;
using namespace boost::assign;
// declare and fill in the array with numbers starting from 0
double someArray[10][20];
std::iota(&someArray[0][0], &someArray[9][20], 0.0);
// let's get the address of the start of the third column
const double* startAddr = &someArray[0][2];
// here is the address of the end of the 2-dimensional array
const double* endAddr = &someArray[9][20]; // add up the third column
// create a SinglePass range consisting of the starting and ending address
// plus the stride count
auto str = std::make_pair(startAddr, endAddr) | strided(20);
// count how many items in the third column are less than 60
auto result = boost::range::count_if(str, [&](double val) { return val < 60; });
std::cout << result;
}
Output:
3
Divide and conquer.
Use count_if to iterate over a single column of a multidimensional array, checking that the index of the row is within a certain range.
Break the problem into smaller pieces, until they are small enough to solve.
Use count_if
iterate over a single column of a multidimensional array
checking that the index of the row is within a certain range
Hmm... that first task looks doable. Maybe the last. Back to division.
Use std::count_if
iterate:
over an array
but it's multidimensional
only one column matters
checking that the index of the row is within a certain range
Iterating over an array is not hard, given std::begin and std::end. The multidimensional aspect looks scary, so let's wait on that and see how far we can get. For now, just plug "iterate over an array" into "use count_if".
std::count_if(std::begin(someArray), std::end(someArray), [](auto & element)
{ return ???; });
Hmm... the name element is not accurate is it? When std::begin is applied to double [][20], only one dimension is consumed. The result of de-referencing is not double but double [20], so row would be a more accurate name.
std::count_if(std::begin(someArray), std::end(someArray), [](auto & row)
{ return ???; });
The multidimensional aspect might have just taken care of itself. Can we focus on just one column? Let's assume a variable named column is the desired column index, and target can be the "some number" from the problem description.
std::count_if(std::begin(someArray), std::end(someArray), [column, target](auto & row)
{ return row[column] > target; });
So that leaves restricting the row index to a certain range. That is, iterate over the restricted range instead of over the entire array. Looks like a job for std::next and std::prev. We'll just need two more variables to give us the range; let's use from and to.
// Check only the desired rows
auto start = std::next(std::begin(someArray), from);
auto stop = std::prev(std::end(someArray), 9 - to);
return std::count_if(start, stop, [column, target](auto & row)
{ return row[column] > target; });
(I don't like that magic number 9. Better would be ROWS-1, assuming suitable constants have been declared so that the array's declaration can become double someArray[ROWS][COLS].)

implementing BFS using STL in c++

I am trying to write a code for BFS in c++ using STL. This is the section of the code i am having trouble with
std::list<int> li=*i;
for (std::list<int>::iterator iter=li.begin(); iter!=li.end();++iter)
{
if (arr[iter]==0)
{
myQ.push(iter);
arr[iter]=1;
Here arr is the array that stores whether or not i have seen the node .i am getting the error
"No match for operator arr[] in arr[iter]
iter is an iterator, so a kind of pointer, not an integer. THis is whiy arr[] does not work, because it expects an integer.
Try with arr[*iter] instead, and your breadth first search will avoid the cycles succesfully.
Please note that you have the same potential issue with your push(iter), if myQ is supposed to contain nodes as well.
You could further improve your design, by defining arr as a set instead of an array/vector.
Your condition would then look like:
if (arr.count(*iter) == 0) {
myQ.push_back(*iter);
arr.insert(*iter); // works for int, but also other data types
}
Iam answering by assuming arr in an integer array.
Any array elemet can be accessed by its integer index only,but not address of integer index.
Here iter is the pointer which can store the address of an integer.
So you have to use '*' to retrieve the value stored at the address to get integer value.
So change array[iter] to array[*iter]..
Hope this will fix your problem.
Here iter is an iterator which is pointer to the list, so for accessing its value you have to write *iter(access value which it is pointing) instead of iter(it is reference).
Try this
std::list<int> li=*i;
for (std::list<int>::iterator iter=li.begin(); iter!=li.end();++iter)
{
if (arr[*iter]==0)
{
myQ.push(*iter);
arr[*iter]=1;

Get index of element in C++ map

I have a std::map called myMap in my C++ application, and I want to get an element using either myMap.find(key) or myMap[key]. However, I would also like to get the index of that element in the map.
std::map<string, int> myMap;
// Populate myMap with a bunch of items...
myElement = myMap["myKey"];
// Now I need to get the index of myElement in myMap
Is there a clean way to do that?
Thank you.
I came here seeking for this answer but i found this
distance function takes 2 iterators and returns an index
cout << distance(mymap.begin(),mymap.find("198765432"));
hope this helps :D
A std::map doesn't really have an index, instead it has an iterator for a key / value pair. This is similar to an index in that it represents a position of sorts in the collection but it is not numeric. To get the iterator of a key / value pair use the find method
std::map<string, int>::iterator it = myMap.find("myKey");
Most of the time when you are working with indices and maps, it usually means that your map is fixed after some insertions. If this assumption holds true for your use case, you can use my answer.
If your map is already fixed (you wouldn't add/delete any key afterward), and you want to find an index of a key, just create a new map that maps from key to index.
std::map<string, int> key2index; // you can use unordered_map for it to be faster
int i = 0;
for (pair<K, V> entry : yourMap) {
key2index[entry.first] = i++;
}
From this key2index map you can query the key as often as you can. Just call key2index['YourKey'] to get your index.
The benefit of this method over distance function is access time complexity. It's O(1) and very fast if you do query often.
Extra Section
If you want to do the opposite, you want to access key from index then do the following.
Create an array or vector that stores keys of your entire map. Then you can access the key by specifying the index.
vector<int> keys;
for (pair<K,V> entry : yourMap) {
keys.push_back(entry.first);
}
To access an index i of your map, use yourMap[keys[i]]. This is also O(1) and significantly faster because it's using only an array/vector, not a map.
Well - map is keeping the key and the data as a pair
so you can extract key by dereferecing the map's iterator into pair or directly into pair's first element.
std::map<string, int> myMap;
std::map<string, int>::iterator it;
for(it=myMap.begin();it!=myMap.end();it++)
{
std::cout<<it->first<<std::endl;
}
Use
int k = distance(mymap.begin(), mymap.find(mykey));
It will give you the index of the key element.
There is no such thing as an index in a map. Maps are not stored (not necessarly, at least; and indeed they are not in most implementations) as a sequence of "pairs".
Regardless of the implementation, however, std::map does not model a container having an index.
Depending on what you are asking this question for, the "index" can be an iterator (as suggested by others) or the key itself.
However, it sounds strange you asked this question. If you could give us a bit more details we would probably be able to point you to a better solution to your problem.
The semantic of a map does not include indexes. To understand that, you can note that Maps are typically implemented as trees. Therefore, elements in it do not have an index (try to define an index in a natural way for a tree).
Map is a key-value data structure which internally data in a tree structure. There are O(n) solution stated above.
" distance(mymap.begin(),mymap.find("198765432")) " will not bring you the correct answer.
For your requirement, you have to build your own segment tree type data structure for O log(n) competitive operations.
A use case: if you want to know how many items are smaller or equal as you progress on a vector. Constraint : i < = j, how many v[i]'s are smaller or equal to v[j]). let's insert it into a map or set.
vector<int> v={1, 4, 2, 3};
set<int> s;
s = {1}; // 1's position is 1 (one based)
s = {1,4}; //4's positon is 2
s = {1, 2, 4} ;//2's position is 2
s = {1 , 2, 3, 4}; //3's positon is 3
it seems std:distance would need a O(n) time.
I could achieve same affect using set.lower_bound() and counting backward till set.begin(). Does anyone have a better solution than requiring O(n) , perhaps using additional data structures?
OK, on a second thought here is a solution to store index (1 based) for this specific problem. However it may not solve the problem for get the correct index of items in the finished map.
vector<int> arr={1 , 1 , 2, 4, 2};
multimap<int, int> track;
for(auto a:arr)
{
auto it = track.insert(make_pair(a, 1)); //first item is 1
if(it!=track.begin())
{
--it;
int prev=it->second;
it++;
it->second+=prev;
}
cout<<a<<','<<it->second-1<<endl;
}

Check if array index exists

Is there any way to check if a given index of an array exists?
I am trying to set numerical index but something like 1, 5, 6,10. And so I want to see if these indexes already exist and if they do just increase another counter.
I normally work with php but I am trying to do this in c++, so basically I am trying to ask if there is an isset() way to use with c++
PS: Would this be easier with vectors? If so, can anyone point me to a good vector tutorial? Thanks
In C++, the size of an array is fixed when it is declared, and while you can access off the end of the declared array size, this is very dangerous and the source of hard-to-track-down bugs:
int i[10];
i[10] = 2; // Legal but very dangerous! Writing on memory you don't know about
It seems that you want array-like behavior, but without all elements being filled. Traditionally, this is in the realms of hash-tables. Vectors are not such a good solution here as you will have empty elements taking up space, much better is something like a map, where you can test if an element exists by searching for it and interpreting the result:
#include <map>
#include <string>
// Declare the map - integer keys, string values
std::map<int, std::string> a;
// Add an item at an arbitrary location
a[2] = std::string("A string");
// Find a key that isn't present
if(a.find(1) == a.end())
{
// This code will be run in this example
std::cout << "Not found" << std::endl;
}
else
{
std::cout << "Found" << std::endl;
}
One word of warning: Use the above method to find if a key exists, rather than something like testing for a default value
if(a[2] == 0)
{
a[2] = myValueToPutIn;
}
as the behavior of a map is to insert a default constructed object on the first access of that key value, if nothing is currently present.
My personal vote is for using a vector. They will resize dynamically, and as long as you don't do something stupid (like try and access an element that doesn't exist) they are quite friendly to use.
As for tutorials the best thing I could point you towards is a google search
To do this without vectors, you can simply cross-check the index you are tying to access with the size of array. Like: if(index < array_size) it is invalid index.
In case the size is not known to you, you can find it using the sizeof operator.
For example:
int arr[] = {5, 6, 7, 8, 9, 10, 1, 2, 3};
int arr_size = sizeof(arr)/sizeof(arr[0]);
It sounds to me as though really a map is closest to what you want. You can use the Map class in the STL (standard template library)(http://www.cppreference.com/wiki/stl/map/start).
Maps provide a container for objects which can be referenced by a key (your "index").