Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am using this code to insert some elements to the map.
raw.insert({ std::string(name), new raw_resource(data, length) });
First element inserts succesfully, but second one does not.
Map type is
std::map<std::string, raw_resource*, compare> raw;
Comparator code
class compare
{
public:
bool operator()(std::string s1, std::string s2)
{
return (s1.compare(s2) == 0);
}
};
See the reference:
template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T> >
> class map;
http://en.cppreference.com/w/cpp/container/map
An std::map takes a comparator that tells if the first argument is less than the second. Not if they are equal. Otherwise it could not build a binary tree.
You don't need to write your own comparator for std::string at all. All the comparison operators are already defined for you: http://en.cppreference.com/w/cpp/string/basic_string/operator_cmp.
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
Is there template in C++ , which allows to find in a sorted vector the value nearest to the key, and returns its index (iterator). What I found, returns only a boolean.
Edited: The question was motivated by the fact that the binary search returns a boolean. I conclude that at the time returning the boolean, also the iterator is known. Returning it, I could find out which element is found. What is the reason that no such binary search is provided?.
I don't know if you want to avoid sorting yourc container / array, so I'm going to post most universal way. And the answer is – no. If you don't want to sort container, there's no ready template, but you can simply write your own function, like this:
template<typename iterator_t, typename value_t, typename comparator_t>
iterator_t nearest_element(iterator_t begin, iterator_t end, value_t value, comparator_t comparator) {
return std::min_element(begin, end, [value, &comparator](double lhs, double rhs) {
return comparator(std::abs(lhs - value), std::abs(rhs - value));
});
}
template<typename iterator_t, typename value_t>
iterator_t nearest_element(iterator_t begin, iterator_t end, value_t value) {
return nearest_element(begin, end, value, std::less<value_t>());
}
It's just simple math, nearest element is one with smallest absolute value of subtracting it from searched value. Code above still lets you change comparator (but hides subtraction / std::fabs) so it can be also used to find farthest value.
Usage (without specified comparator) is simple, like any other standard function:
std::vector<double> vec {2., 5., -4.};
auto it = nearest_element(vec.begin(), vec.end(), -10.);
std::cout << *it << std::endl;
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to create a template class that will allow me to print the contents of an object, however, being new to this, I am struggling to set the values of the data.
If, for example, I have a template that takes two typename parameters, how would I go about setting the values? Must I treat every instance of a template in a similar manner to an array or vector?
Pair<int, double> first, second;
Obviously first = 10 does not work. What am I doing wrong?
You create two Pair objects, so you cannot assign 5 to one of them, since 5 is not a Pair.
Pair<int, double> first, second; // means that you have TWO pairs!
// it was equal to:
// Pair<int, double> first;
// Pair<int, double> second;
first.first = 5;
first.second = 3.14f;
second.first = 3;
second.second = 7.421f;
You probably wanted something like this:
Pair<int, double> myPair; // only 1 pair
myPair.first = 5;
myPair.second = 3.14f;
Hopefully you are using std::pair and not writing your own pair class.
other than what has already been answered to you, you must also be familliar with std::make_pair which creates a pair and deducts the types from the arguments, thus making your code smaller and more readable.
example:
auto myPair = std::make_pair(4,5.6);
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
using line_nm = vector<string>::size_type;
map<string, set<line_nm>> m;
On the above code, why can't I use the code below?
map<string, set<vector<int>>> m1;
Test:
string str;
word[str].insert(5);
I got an error when I am using "m1" version.
vector<string>::size_type is an integral type.
Hence,
map<string, set<line_nm>> m;
is analogous to:
map<string, set<size_t>> m;
m[str] returns a reference to a set<size_t>, whose insert() method is expecting a size_t. That's why you can use:
m[str].insert(5);
When you use:
map<string, set<vector<int>>> m1;
m1[str] returns a reference to a set<vector<int>>, whose insert() method is expecting a vector<int>, not an int. That's why you cannot use:
m1[str].insert(5);
you can use
m1[str].insert(arg);
where arg is a vector<int> or something which can be converted to a vector<int>.
m1[str].insert(std::vector<int>{5, 10, 30});
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Basically I have a edgeCostMap of type
map<pair<int, float>, int>
and a vector of 42 vertices. I loop through the vector of vertices and add values to the map as follows:
for(int vertexIndex = 0; vertexIndex < V.size(); vertexIndex++)
{
pair<int, float> toAdd;
toAdd.first = vertexIndex;
toAdd.second = V[vertexIndex].edgeCollapseCost;
edgeCostMap[toAdd] = vertexIndex;
}
However after the loop has been finished and I print out the map contents as follows:
for(map<pair<int, float> ,int>::iterator it = edgeCostMap.begin(); it != edgeCostMap.end(); it++)
{
logFile<<"Vertex "<<it->second<<" has cost "<<it->first.second<<" has "<<mapVF[it->second].size()<<"neighbors"<<endl;
}
I only get back 12 statements. Is my mapping done incorrectly?
Compare function:
class comparator {
public:
bool operator()(const std::pair<int, float>& a, const std::pair<int, float>& b) const {
return a.second < b.second;
}
};
Your comparator considers two keys equal (neither less than the other) if their floats are equal. You cannot put two equal keys in a map. You probably want to use the default comparator but put the float first in the set. This will sort first on the float and second on the integer, ensuring the keys are not equal if their integers differ.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Is there a code that will check if a certain string is inside an array?
For example I have a string "John" then I need to check if "John" is already in the array names[10].
std::find does exactly that:
auto i = std::find(std::begin(a), std::end(a), "John");
if (i != std::end(a)) … // item found!
However, beware that this does a linear pass over the elements. That’s not a problem for 10 items but it becomes inefficient quickly with larger number. For very large sets, use std::unordered_set instead of an array, to attain (theoretically) constant runtime. Alternatively, if you know that the array is sorted you may employ std::binary_search to attain logarithmic runtime.
Here’s the same code, wrapped inside a convenience function:
template <typename It, typename T>
bool contains(It begin, It end, T const& value) {
return std::find(begin, end, value) != end;
}
And here’s a convenience overload for C arrays:
template <typename T, typename U, std::size_t N>
bool contains(T (&arr)[N], U const& value) {
return std::find(arr, arr + N, value) != arr + N;
}
(The syntax for passing arrays to functions is a bit weird.)
If you want to go archaic:
function in_array(String my_array[], String findthis){
len=sizeof my_array;
for(int i=0;i<len;i++){
if(my_array[i]==findthis){
return true;
}
}
return false;
}
then
in_array(array_of_strings, "john");
I wrote this hastily and I'm very tired, but hopefully it can be of some use.