Stl unordered multimaps with tuple - c++

Basically ,I want hash table with link list which stores 3 int type variable so I am using unordered multimap with int and tuple .But its giving me compile time error WHERE I AM DOING WRONG .And is there any other efficient way of doing this . And further i want to find min on imposing some conditions on b and c in all the list contained in the buckets.For this I am thinking to use stl min method of algorithms but I am not able to figure out how to send second and third data of tuple as an argument for lambda function.
#include <iostream>
#include <iterator>
#include <bits/stdc++.h>
#include <vector>
#include <tuple>
#include <algorithm>
#include <numeric>
using namespace std;
int main()
{
std::unordered_multimap<int, std::tuple<int, int, int>> um;
int t;
cin >> t;
while (t--)
{
int n, d;
cin>>n>>d;
for (int i = 0; i < n; ++i) {
int a, b, c;
cin >> a >> b >> c;
um.insert(make_pair(a, std::make_tuple(a, b, c)));
}
}
for (std::unordered_multimap<int, std::tuple<int, int, int>>::const_iterator i = um.begin(); i != um.end(); ++i) {
cout << i->second->get<1> << endl;
}
}
this the error when i am just trying to print values
main.cpp: In function 'int main()':
main.cpp:34:18: error: base operand of '->' has non-pointer type 'const std::tuple'
cout<second ->get<1><main.cpp:35:3: error: expected declaration before '}' token
}}
^

In
cout << i->second->get<1> << endl;
i is an iterator to a std::unordered_multimap<int, std::tuple<int, int, int>>. That means that i->second gives you the std::tuple<int, int, int> part of the key/value pair. Since it is not a pointer you do not use -> to access it's members but instead you use ..
That said get is not a member function of std::tuple. std::get is a global function and you pass the tuple to it to get its element. That would make you code look like
std::cout << std::get<1>(i->second) << std::endl;

Related

std::string::insert doesn't work with to_string(). CPP

I am writing a code to insert an integer at an index of the string, but after providing the integer to add as string, insert function is not giving the correct output.
It is giving the error that :
no matching member function to call for insert string
This is my code:
#include <iostream>
using namespace std;
int main()
{
string s = "45564528";
int x = 8;
s.insert(s.begin()+5,to_string(x));
cout<<s<<endl;
return 0;
}
The expected output is 455648528.
Looking at the documentation for std::string::insert() shows that it takes a char or an iterator range, not a std::string, which std::to_string() naturally returns. At least, this is the case for the overloads that take an iterator for the first argument.
#include <iostream>
#include <string> // CHANGED: Include what you use
// using namespace std; // CHANGED: Bad practice
int main()
{
std::string s = "45564528";
int x = 8;
// CHANGED: Create string from the int, and use the iterator range overload
// to account for multi-digit numbers
auto tmp = std::to_string(x);
s.insert(s.begin()+5, tmp.begin(), tmp.end());
std::cout << s << '\n'; // CHANGED: std::endl is rarely actually needed
return 0;
}
There is an overload that lets you insert another std::string, but the first argument must be an index and not an iterator. So this would work as well:
#include <iostream>
#include <string>
int main()
{
std::string s = "45564528";
int x = 8;
s.insert(5, std::to_string(x));
std::cout << s << '\n';
return 0;
}

how do i iterate the pair array arguments passed as a pointer?

how do i iterate the pair array arguments passed as a pointer ?
i had tried to use as reference pair &arr . but it doesnt worked either . can i pass pair<lli,lli> a[n]; as reference ??
#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#define LOCAL
#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
typedef long long int lli;
typedef unsigned long long int ulli;
void yeah( pair<lli,lli> *arr ){
// cout << arr[0].ff; 100
//this doesnt work :(
for(auto e : arr){
cout << e.ff << " " << e.ss << endl;
}
}
int main() {
int n = 10;
pair<lli,lli> a[n];
a[0].ff = 100;
a[1].ss = 150;
yeah(a);
}
this is the error im getting
prog.cpp: In function 'void yeah(std::pair)':
prog.cpp:13:18: error: no matching function for call to 'begin(std::pair&)'
for(auto e : arr){
^
^
A possible solution with fixed-size arrays:
template<std::size_t size>
void foo(std::pair<int, int> (&arr)[size]) {
for (auto e : arr) {
...
}
}
constexpr std::size_t n = 10; // should be known at compile time
std::pair<int, int> a[n];
foo(a);
I would recommend ditching the VLA (which is not part of C++ anyway) and use std::vector instead. Include <vector> and change the declaration to this:
std::vector<std::pair<lli, lli>> a(n);
And the function's signature to:
void yeah(std::vector<std::pair<lli, lli>> &arr)

C++ search a tuple in map error: cannot bind 'int' lvalue to 'int&&'

I always get this error.
#include <bits/stdc++.h>
using namespace std;
#define mt make_tuple<int,int>
int main(){
map<tuple<int,int>,int> l;
l[mt(5,4)] = 3;
cout << l.count(mt(9,8));
}
1. What should I change to accept values from my file?
2. Where is the mistake?
int main(){
map<tuple<int,int>,int> l;
l[mt(5,4)] = 3;
int a,b;
cin >> a >> b;
cout << l.count(mt(a,b));
}
The whole point of make_tuple is having it deduce the tuple's type for you. If you invoke it explicitly specifying <int, int>, you prevent deduction from correctly taking place.
Just let make_tuple do its job and don't define macros just because you want to save a few keystrokes - you'll regret it.
int main(){
std::map<std::tuple<int, int>, int> l;
l[std::make_tuple(5,4)] = 3;
int a,b;
cin >> a >> b;
cout << l.count(std::make_tuple(a,b));
}
live example on wandbox.org

char and char& no matching function for call

In order to compare if two string contain a same char, I was trying to loop through a string a and put the chars into a map.
So this is what I did.
string a = "abc";
unordered_map<char,int> m;
for (auto i:a){
m.insert(i,1);
}
But then there is an error:
no matching function for call to ‘std::unordered_map<char, int>::insert(char&, int)’
I don't quite understand what can I do here. Hope someone can help!
The problem in your code is that you try to insert a which is a std::string into an std::unordered_map<char, int> - you should be inserting i which is a char (each char from std::string a).
Moreover, even if you correctly used
m.insert(a,1);
it wouldn't compile because std::unordered_map::insert accepts a std::pair not 2 arguments from the template type. So you would need:
std::unordered_map<char, int> char_map;
char_map.insert(std::make_pair(c, 1));
Want you want to achieve can be done with std::set (if you don't care about the order of objects - chars - stored inside it)
#include <iostream>
#include <string>
#include <unordered_set>
int main()
{
std::string a = "abc";
std::unordered_set<char> char_set;
for (auto c : a)
char_set.insert(c);
for (auto c : char_set)
std::cout << c << ' ';
}
http://cpp.sh/3zrgr
Unfortunately you need to call std::make_pair first:
#include <iostream>
#include <unordered_map>
int main()
{
std::string a = "abc";
std::unordered_map<char,int> m;
for (int i = 0; i < a.size(); ++i)
m.insert(std::make_pair(a[i],1));
}

C++ how to push_back an array int[10] to std::vector<int[10]>?

#include <vector>
using namespace std;
vector<int[60]> v;
int s[60];
v.push_back(s);
This code in Visual Studio 2015 community report a compile error:
Error (active) no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back [with _Ty=int [60], _Alloc=std::allocator]" matches the argument list
Error C2664 'void std::vector>::push_back(const int (&)[60])': cannot convert argument 1 from 'int' to 'int (&&)[60]'
Use std::array, instead:
#include <vector>
#include <array>
using namespace std;
int main()
{
vector<array<int, 10>> v;
array<int, 10> s;
v.push_back(s);
return 0;
}
But I also have to question the purpose of having a vector containing an array. Whatever is the underlying reason for that, there's likely to be a better way of accomplishing the same goals.
You can do it like this:
#include <iostream>
#include <vector>
int main()
{
int t[10] = {1,2,3,4,5,6,7,8,9,10};
std::vector<int*> v;
v.push_back(t);
std::cout << v[0][4] << std::endl;
return 0;
}
To be more specific in this solution you do not actually store values of array t into vector v you just store pointer to array (and to be even more specific to first element of array)
I am not sure are you saying initialize a vector from an array, if yes here is a way to do it using vector's constructor:
int s[] = {1,2,3,4};
vector<int> v (s, s + sizeof(s)/sizeof(s[0]));