int numSubarraysWithSum(vector<int>& A, int S) {
unordered_map<int, int> c({{0, 1}});// Line 1
int psum = 0, res = 0;
for (int i : A) {
psum += i;
res += c[psum - S];
c[psum]++;
}
return res;
}
What does line 1 mean? I'm confused as there are two curly braces.
It's something called an Initilizer list. According to this website:
Initializer List is used in initializing the data members of a class.
The list of members to be initialized is indicated with constructor as
a comma-separated list followed by a colon.
Basically it adds elements into your std::map (or in this case your std::unordered_map) right while you're creating it.
More specifically, from #Aconcagua comment above :
The outer braces define
the initializer list itself, the inner braces are shorthand for
constructing std::pairs, which are used in the std::map to store the keys
and corresponding values.
You can see this from this piece of code:
#include <iostream>
#include <map>
#include <unordered_map>
using namespace std;
int main()
{
map<int, int> c({{0, 1}, {1, 7}});
for (auto it = c.begin(); it!=c.end(); it++)
{
cout << it->first << " " << it->second << "\n";
}
}
Output:
0 1
1 7
There's also other data types that support this, for example std::vector :
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> test({0, 7, 9, 11, 3});
for (auto x : test) {cout << x << "\n";}
}
Output:
0
7
9
11
3
There's a lot of question regarding this:
Initializing a static std::map<int, int> in C++
What would a std::map extended initializer list look like?
And more info: https://en.cppreference.com/w/cpp/utility/initializer_list
*Cautions : As #Aconcagua mentioned below, using namespace std is not considered a good practice, although it might save some typing time.
It simply just add elements into your map. There are many different ways to do this:
unordered_map<int, int> c{ {0, 1} }; similar to your question
2 unordered_map<int, int> c;
c[0]=1;
assign key and value
3.
unordered_map<int, int> c;
c.insert(std:: make_pair (key, vale) ); use make_pair
... You can refer more here map
Related
The vector constructor calls in the statement below construct vectors with 50 elements of identical values in each vector as values in the sviMap. The statement repeats vector<int> three times. Is there a more concise way to achieve this overall initialization of the sviMap where vector<int> appears only once in the statement?
map<string, vector<int>> sviMap { {"Leo", vector<int>(50, 101)} , {"Brad", vector<int>(50, 201)} };
Strictly speaking, no. You need to have template specialization and two instances of the vector.
But if you need to have "this text once", this workaround could work for you:
using vi = vector<int>;
map<string, vi> sviMap{ {"Leo", vi(50, 101)} , {"Brad", vi(50, 201)} };
Formally, this is not "the statement", but two statements, but the vector appears only once. If your goal is to have one point for changes, this could work.
I wanted to correct my mistake, so here's another solution.
And this one will result in vectors of the correct length.
I just used inheritance to create a vector type with a constructor that has the desired behavior, so you can then use initializer lists without extra specifics
#include <cassert>
#include <map>
#include <vector>
#include <string>
template<typename type_t>
class my_vector :
public std::vector<type_t>
{
public:
my_vector() = default;
my_vector(const size_t size, const type_t value) :
std::vector<type_t>(size, value)
{
}
};
int main()
{
std::map<std::string, my_vector<int>> sviMap{ { "Leo", {50, 101}}, { "Brad", {50, 201}} };
auto vec = sviMap["Leo"];
auto value = vec[23];
}
You can do it like this, just use nested initializers
#include <map>
#include <vector>
#include <string>
int main()
{
std::map<std::string, std::vector<int>> sviMap
{
{"Leo", {50, 101}},
{"Brad", {50, 201}}
};
auto vec = sviMap["Leo"];
}
I reached the last element of the vector of a class from within main() function. But I am not sure if it was the correct way to do this. Here is the code part:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class myClass
{
public:
std::vector <wstring> Vec;
std::vector <wstring> Vec2;
std::vector <wstring> Vec3;
// ...
std::vector <wstring> Vec35;
myClass();
};
myClass::myClass() : Vec{ L"Init" }, Vec2{ L"Init" }, Vec3{ L"Init" }, Vec35{ L"Init" } {}
void func(std::vector<wstring>& v)
{
v.push_back(L"The Last Element");
}
int main()
{
myClass mC;
func(mC.Vec);
wstring last = *(((std::vector <wstring>&) mC.Vec).rbegin()); // Is it the correct way to do this?
std::wcout << L"Last element reached from inside of main() function is : " << last << std::endl;
return 0;
}
The output is:
Last element reached from inside of main() function is : The Last Element
Using rbegin is indeed one way. The cast is however unnecessary.
But a more direct way is using back. Unlike rbegin which gives you an iterator that must be dereferenced, back gives you a reference to the last item.
wstring last = mC.Vec.back();
Either way you should first check that the vector is not empty.
Yes. Though it's a descriptive way of saying that.
Just
wstring last = *mC.Vec.rbegin();
should suffice. No need of explicit casting required.
This question already has answers here:
Initializing a static std::map<int, int> in C++
(12 answers)
Closed 5 years ago.
So for some reason this works in a class contructor but not outside a class I was wondering as to why and how could I get my map to work outside a class.
#include <iostream>
#include <string>
#include <map>
typedef std::map <std::string, int> idMap;
idMap type_id;
type_id["Moon"] = 1;
type_id["Star"] = 2;
type_id["Sun"] = 3;
int main()
{
std::cout << type_id["Moon"] << std::endl;
}
The compiler errors I get are as follows
11:1: error: 'type_id' does not name a type 12:1: error: 'type_id' does not name a type 13:1: error: 'type_id' does not name a type
I am looking for an example like this that would work, also if you can tell me why this won't work.
Your main should look like this:
int main()
{
type_id["Moon"] = 1;
type_id["Star"] = 2;
type_id["Sun"] = 3;
std::cout << type_id["Moon"] << std::endl;
}
You cannot put these statements outside of a function (in that case main()).
Or if you really want to populate your map outside main(), you could it by using a list initializer constructor, like this:
idMap type_id { {"Moon", 1}, {"Star", 2}, {"Sun", 3} };
This approach works for a header file as well, like this:
myHeader.h
#include <string>
#include <map>
typedef std::map <std::string, int> idMap;
idMap type_id { {"Moon", 1}, {"Star", 2}, {"Sun", 3} };
main.cpp
#include <iostream>
#include "myHeader.h"
int main() {
std::cout << type_id["Moon"] << std::endl;
}
I want my own class can be list-initialized like vector:
myClass a = {1, 2, 3};
How can I do that using C++11 capabilities?
C++11 has a notion of initializer lists. To use it, add a constructor which accepts a single argument of type std::initializer_list<T>. Example:
#include <vector>
#include <initializer_list>
#include <iostream>
struct S
{
std::vector<int> v_;
S(std::initializer_list<int> l)
: v_(l)
{
std::cout << "constructed with initializer list of length " << l.size();
}
};
int main()
{
S s = { 1, 2, 3 };
return 0;
}
An initializer_list can be (like other STL containers) iterated and the size can be queried. This allows you to do as pointed in the other answer by yuyoyuppe to immediately feed it to a vector. But you may have other intents for your initialization and do something like execute an operation directly on the items of the list without copying.
#include <initializer_list>
#include <iostream>
#include <algorithm>
struct S
{
int thesum;
int items;
S(std::initializer_list<int> l) :
thesum(std::accumulate(l.begin(), l.end(), 0)),
items(l.size())
{}
};
int main()
{
S s = { 1, 2, 3 };
std::cout << s.items << std::endl;
std::cout << s.thesum << std::endl;
return 0;
}
This prints
3
6
See:
http://www.cplusplus.com/reference/initializer_list/initializer_list/?kw=initializer_list
http://en.cppreference.com/w/cpp/utility/initializer_list
-
I have two arrays, as follows:
std::array<int,6> A,B;
//Fill A with random data
//File B with random data
For whatever reason, I'd like some kind of container object which lets me access both of the vectors individually, but also to iterate over their union, allowing for actions such as follows:
union_container uc(A,B);
for(unioned::iterator i=uc.begin();i!=uc.end();++i)
*i+=1;
uc.first()[2]=4;
uc.second()[4]=5;
I could code this unioned class myself, but perhaps there is already a library which allows this?
Using Boost zip iterators is one way to do this.
#include <array>
#include <functional>
#include <iostream>
#include <boost/tuple/tuple.hpp>
#include <boost/iterator/zip_iterator.hpp>
template<typename T>
using ZipIt = boost::zip_iterator< boost::tuple<T*, T*> >;
template<typename T>
using ZipRef = decltype(*ZipIt<T>());
template<typename T>
void operator+=(ZipRef<T> z, T const& v)
{
z.template get<0>() += v;
z.template get<1>() += v;
}
int main()
{
std::array<int, 6> a = { 1, 3, 5, 7, 9, 11 };
std::array<int, 6> b = { 2, 4, 6, 8, 10, 12 };
std::for_each(
boost::make_zip_iterator(boost::make_tuple(std::begin(a), std::begin(b))),
boost::make_zip_iterator(boost::make_tuple(std::end(a), std::end(b))),
[](ZipRef<int> z){ z += 1; }
);
std::copy(std::begin(a), std::end(a), std::ostream_iterator<int>(std::cout, ",")); std::cout << "\n";
std::copy(std::begin(b), std::end(b), std::ostream_iterator<int>(std::cout, ",")); std::cout << "\n";
a[2] = 4;
b[4] = 5;
}
Online output.
Note that the code above is not as general as I've would liked, since the jump to variadic templates and general iterator types proved a bit hairy (left as an exercise!) This has mainly to do with the fact that boost::zip_iterator uses some tricky internal facades around boost::tuple. For this reason I also used decltype in the template alias for ZipRef to avoid having to write such nasty types inside the std::for_each lambda expression.