Which method is to access Pairs? [closed] - c++

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
just to clear this doubt of fine i just want to ask that which method is faster or more efficient to access pairs while iterating over a contiguous block of pairs.
I used two method to iterate over a block.
1st
pair<int, char> arr[3] = {{1, 'a'}, {2, 'b'}, {3, 'c'}};
for (int i = 0; i < 3;i++){
cout << get<0>(arr[i]) << " " << get<1>(arr[i]) << endl;
}
2nd
for(const auto &x:arr){
cout << x.first << " " << x.second << endl;
get<0>(arr[0]);
}
which one is better and more efficient pls explain if u can.

You can compare them here: https://godbolt.org/z/4dPzKaPWr
As you will see, both have the same assembly code.

Efficiency takes many forms. I don't expect huge runtime differences in either case (you will have to measure/profile and expect std::cout to slow things down a lot, so be careful what you measure!).
But in terms of maintainability (which is also an efficiency).
I would use structured bindings on pairs (or not use pairs at all and use my own struct with clearly readable names)
#include <iostream>
#include <utility>
// don't use : using namespace std
struct my_data_t
{
int number;
char character;
};
int main()
{
std::pair<int, char> arr[]{{1, 'a'}, {2, 'b'}, {3, 'c'}};
my_data_t arr2[]{{1, 'a'}, {2, 'b'}, {3, 'c'}};
// using structured bindings for readabiliey
for(const auto& [number, character] : arr)
{
// for speed, don't use std::endl though
std::cout << number <<", " << character << "\n";
}
// or using own datastructure
for(const auto& entry : arr2)
{
std::cout << entry.number <<", " << entry.character << "\n";
}
return 0;
}

They are the same. The template arguments 0 and 1 in get<> must be compile-time constants, An implementation of get<>() refers to first or second for 0 or 1 respectively. The function call to get<>() gets inlined when optimized.

Related

having trouble passing lower_bound a fourth argument [closed]

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 4 years ago.
Improve this question
I am not sure how to pass a comparison function to the lower_bound function. When I try to pass 4 arguments, I get an error. I would greatly appreciate an example of how to pass a comparison function in the lower_bound function.
In the overload of lower_bound you are using, Compare must meet the requirements of BinaryPredicate.
The example you have asked for can be found online.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool ignore_case(char a, char b) {
return(tolower(a) == tolower(b));
}
int main(void) {
vector<char> v = {'A', 'b', 'C', 'd', 'E'};
auto it = lower_bound(v.begin(), v.end(), 'C');
cout << "First element which is greater than \'C\' is " << *it << endl;
it = lower_bound(v.begin(), v.end(), 'C', ignore_case);
cout << "First element which is greater than \'C\' is " << *it << endl;
it = lower_bound(v.begin(), v.end(), 'z', ignore_case);
cout << "All elements are less than \'z\'." << endl;
return 0;
}
Demo here.

Mapping an action name to a class type in C++ [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I want to link a bunch of 'action' strings to single 'parent' string but there could be multiple strings that own 'action' strings.
map<string, string> ctType;
ctType.insert(pair<string, string>("1")("default"));
ctType.insert(pair<string, string>("2")("register"));
ctType.insert(pair<string, string>("2")("addaddress"));
ctType.insert(pair<string, string>("3")("request"));
What is the best way to complete this?
You could either (1) use std::multimap, or you could (2) use a map with containers as its elements. Variant (1) is rather short, but has the drawback that it is harder to control how the "multiple entries" behave in terms of, for example, duplicates; and its probably harder to implement a "nested loop" over the keys and each of its values. Decide on your own:
int main() {
std::multimap<int, std::string> m;
m.insert({1,"First0"});
m.insert({1,"First0"});
m.insert({1,"First1"});
m.insert({3,"Third"});
for (auto& p : m) {
auto key = p.first;
auto val = p.second;
cout << key << ":" << val << endl;
}
std::map<int,std::set<std::string>> m2;
m2[1].insert("First0");
m2[1].insert("First0");
m2[1].insert("First1");
m2[3].insert("Third");
for (auto& p : m2) {
auto key = p.first;
auto set = p.second;
cout << key << ":" << endl;
for (auto &val : set) {
cout << " " << val << endl;
}
}
}
Output:
1:First0
1:First0
1:First1
3:Third
1:
First0
First1
3:
Third

C++ container (or fuction) that can store numbered integer values [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
is there a container or a faction that allows me to store integer values while also having a set number or name on each value. What I need exactly is a way to sort for, example, the following values: [12, 3, 8, 32, 13] but keep track of which is which, eg. that 12 is v1, 8 is v3 ect.
What you are trying to implement is a mapping (i.e. a list of ways in which thing A maps to thing B), and C++ provides plenty of map containers for you.
For example:
#include <map>
int main()
{
// Map of integer values to version number
std::map<int, int> values{
{12, 1},
{3, ?},
{8, 3},
{32, ?},
{13, ?}
};
}
Your book will explain how to use this properly.
just a simple example :
#include <map>
#include <string>
#include <iostream>
int main()
{
std::map<int, std::string> m;
m[1] = "un";
m[123] = "a lot";
std::cout << "1 : " << m[1] << std::endl;
std::cout << "0 : " << m[0] << std::endl; // that add a new entry for 0 in 'm' with an empty string and returns that empty string
std::cout << "123 : " << m[123] << std::endl;
return 0;
}
the execution is :
1 : un
0 :
123 : a lot

Modify the vector class in STL c++, is this possible? [duplicate]

This question already has answers here:
C++ Erase vector element by value rather than by position? [duplicate]
(4 answers)
Closed 7 years ago.
I would like to modify a member function of the vector class. Is this possible? For example I would like to be able to delete with respect to value, and not the integer of the vector.
I think this does what you are looking for. This example removes all the occurrences of the number 6 from a vector using std::remove. xs.erase is to make sure the vector removes the elements and shrinks the vector to the new size.
I generally avoid modifying the STL containers as the people who implemented them are likely far smarter than me when it comes to this kind of thing. I recommend you learn the standard library algorithms, there generally is one suited to most kinds of general container operations.
#include <iostream>
#include <algorithm>
int main(int argc, char** argv)
{
std::vector<int> xs{1, 3, 6, 2, 6, 5};
std::cout << "xs size: " << xs.size() << std::endl; // xs.size() == 6
auto value_to_remove = 6;
xs.erase(std::remove(xs.begin(), xs.end(), value_to_remove), xs.end());
for (const auto& x : xs)
std::cout << x << ", ";
std::cout << std::endl; // 1, 3, 2, 5,
std::cout << "xs size: " << xs.size() << std::endl; // xs.size() == 4
return 0;
}
In this case, as with most other STL algorithms value_to_remove can be replaced with a (unary) lambda predicate opening up a whole world of exotic value finding.
You could wrap the above in a function as follows:
template <typename T>
void erase_by_value(std::vector<T>& xs, const T& value_to_remove)
{
xs.erase(std::remove(xs.begin(), xs.end(), value_to_remove), xs.end());
}

Remove an element from vector and change the size [closed]

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 try to remove elements from a vector and it works fine with the erase() methode, but after removing the element the size of the vector still the same.
std::vector<int> myvector;
myvector.push_back (1);
myvector.push_back (2);
myvector.push_back (3);//here the size is 3
myvector.erase(myvector.begin()+1);//I think normally the size should be 2 after removing the element
is there a function that can do that or should I do it manually, I'm new to c++ I checked the documentation and I didn't found a solution for this.
The size is changed then an element of a vector is removed with using member function erase. If you mean capacity then it will not be changed.
Here is a demonstrative program
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v { 1, 2, 3 };
std::cout << "v.size() = " << v.size() << std::endl;
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
v.erase( v.begin() + 1 );
std::cout << "v.size() = " << v.size() << std::endl;
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
return 0;
}
The output is
v.size() = 3
1 2 3
v.size() = 2
1 3