I have a 2D vector of strings and want to count how many times a certain word is repeated. For example:
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
vector< vector<string> > vec(4, vector<string>(4, "word") );
count( vec.begin(), vec.end(), "certain word" );
}
But the above gives errors. How can I do this?
You need to run count on search individual vector and sum the results:
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
vector< vector<string> > vec(4, vector<string>(4, "string of words") );
size_t sum = 0;
for(auto& v: vec) {
sum += count( v.begin(), v.end(), "certain word" );
}
}
Related
I have a vector of elements of type uint8 which I am copying into one std::array. After some operations again I need to copy the elements from std::array to a vector.Please find the code below
/******************************************************************************
Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, Java, PHP, Ruby, Perl,
C#, VB, Swift, Pascal, Fortran, Haskell, Objective-C, Assembly, HTML, CSS, JS, SQLite, Prolog.
Code, Compile, Run and Debug online from anywhere in world.
*******************************************************************************/
#include <iostream>
#include <vector>
#include <array>
#include <cstdint>
#include <limits>
#include <algorithm>
std::array<std::uint32_t, 5> elem_arr ;
void copy_from_vector(std::vector<std::uint32_t> elem_vec)
{
std::copy(elem_vec.begin(),elem_vec.end(),elem_arr.begin());
}
std::vector<std::uint32_t> copy_from_array()
{
std::vector<std::uint32_t> ele_vec_copy {elem_arr.begin(),elem_arr.end()};
return ele_vec_copy;
}
int main()
{
std::vector<std::uint32_t> ele_vec {1,2,3};
copy_from_vector(ele_vec);
auto ele_vec_copy = copy_from_array();
for(auto ele : ele_vec_copy)
std::cout << ele << std::endl;
return 0;
}
output:
======
1
2
3
0
0
Now the problem is my array size is 5 but vector having only 3 elements. when I copy the elements from the array to a new vector I am getting extra 2 zeros. How can I get the output as below
output:
======
1
2
3
You could copy by size of vector.
#include <iostream>
#include <vector>
#include <array>
#include <cstdint>
#include <limits>
#include <algorithm>
int main()
{
std::array<std::uint32_t, 5> elem_arr ;
std::vector<std::uint32_t> ele_vec {1,2,3};
std::copy(ele_vec.begin(),ele_vec.end(),elem_arr.begin());
std::vector<std::uint32_t> ele_vec_copy { elem_arr.begin() , elem_arr.begin() + ele_vec.size() };
for(auto ele : ele_vec_copy)
std::cout << ele << std::endl;
return 0;
}
run online
After you edited the question
It is not possible to know how many elements used/set in std::array but this feature could be mimic by choosing a unique value which represents the element is null or not set like nullptr. But it comes with a constraint, you must not use the unique value at somewhere else in the array.
So the possible implementation is :
#include <iostream>
#include <vector>
#include <array>
#include <cstdint>
#include <limits>
#include <algorithm>
#include <limits>
std::array<std::uint32_t, 5> elem_arr;
void copy_from_vector(std::vector<std::uint32_t> elem_vec)
{
std::copy(elem_vec.begin(),elem_vec.end(),elem_arr.begin());
}
std::vector<std::uint32_t> copy_from_array()
{
std::vector<std::uint32_t> ele_vec_copy;
std::copy_if( elem_arr.begin() , elem_arr.end() ,
std::back_inserter( ele_vec_copy ) ,
[]( std::uint32_t val ) {
return val != std::numeric_limits<std::uint32_t>::max();
} );
return ele_vec_copy;
}
int main()
{
elem_arr.fill( std::numeric_limits<std::uint32_t>::max() );
std::vector<std::uint32_t> ele_vec {1,2,3};
copy_from_vector(ele_vec);
auto ele_vec_copy = copy_from_array();
for(auto ele : ele_vec_copy)
std::cout << ele << std::endl;
return 0;
}
run online
Or store the elements as std::optional and don't copy null elements.
Possible implementation is :
#include <iostream>
#include <vector>
#include <array>
#include <cstdint>
#include <limits>
#include <algorithm>
#include <limits>
#include <optional>
std::array<std::optional<std::uint32_t>, 5> elem_arr;
void copy_from_vector(std::vector<std::uint32_t> elem_vec)
{
std::transform( elem_vec.begin() , elem_vec.end() ,
elem_arr.begin() ,
[]( auto val ) { return std::optional<std::uint32_t>{ val }; }
);
}
std::vector<std::uint32_t> copy_from_array()
{
std::vector<std::uint32_t> ele_vec_copy;
std::vector<std::optional<std::uint32_t>> non_null_elements;
std::copy_if( elem_arr.begin() , elem_arr.end() ,
std::back_inserter( non_null_elements ) ,
[]( auto val ) {
return val;
} );
std::transform( non_null_elements.begin(), non_null_elements.end() ,
std::back_inserter( ele_vec_copy ) ,
[]( auto val ) { return *val; }
);
return ele_vec_copy;
}
int main()
{
std::vector<std::uint32_t> ele_vec {1,2,3};
copy_from_vector(ele_vec);
auto ele_vec_copy = copy_from_array();
for(auto ele : ele_vec_copy)
std::cout << ele << std::endl;
return 0;
}
run online
I am trying to declare a multidimensional vector with variable number of dimensions (user input).
here is what I have:
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
vector< double > data;
int main() {
int numberDimensions = 4;
for (int it = 0; it < numberDimensions; it++){
// Nor sure what to put here
}
return 0;
}
Another solution is by using an if statement at the begining but I was wondering if another solution exists ?
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int main() {
int numberDimensions = 4;
if (numberDimensions==0)
cout << 'error' << endl;
else if (numberDimensions==1)
vector< double> data;
else if (numberDimensions==2)
vector< vector< double> > data;
else if (numberDimensions==3)
vector< vector< vector< double> > > data;
else if (numberDimensions==4)
vector< vector< vector< vector< double> > > > data;
return 0;
}
Thanks for any suggestions,
As suggested in the comments here is the solution I followed:
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
vector< double > data;
int main() {
std::vector<int> parameter1 {34,23,58};
std::vector<int> parameter2 {1,2,3};
data = vector< double > (parameter1.size()*parameter2.size());
calculateResult(data);
// If I want to access the result for Parameter1 = 58 and Parameter = 2 I do:
int index1 = 2
int index2 = 1
double selectedResult = data[index1*parameter1.size()+index2];
return 0;
}
int main()
{
map<string, int> M;
vector<string> V;
set<string> S;
ifstream inFile("sample_doc.txt");
copy( istream_iterator<string>(inFile), istream_iterator<string>(), back_inserter(V) );
ifstream inFile2("stopwords.txt");
copy( istream_iterator<string>(inFile2), istream_iterator<string>(), inserter( S, S.begin() ) );
for_each( V.begin(), V.end(), [&](string & s){ S.count(s) == 0 ? M[s]++ : true; } );
}
in the for_each statement, when I pass in the lambda function above, it gives me the following error.
error: no matching function for call to ‘for_each(std::vector<std::basic_string<char> >::iterator, std::vector<std::basic_string<char> >::iterator, main()::__lambda0)’
for_each( V.begin(), V.end(), [&](string & s){ S.count(s) == 0 ? M[s]++ : true; } );
can someone tell me how to fix it? thanks a lot.
This here built on VS2017, maybe you have forgot some header?
#include <map>
#include <algorithm>
#include <set>
#include <iterator>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
void foo()
{
using namespace std;
map<string, int> M;
vector<string> V;
set<string> S;
ifstream inFile("sample_doc.txt");
copy(istream_iterator<string>(inFile), istream_iterator<string>(), back_inserter(V));
ifstream inFile2("stopwords.txt");
copy(istream_iterator<string>(inFile2), istream_iterator<string>(), inserter(S, S.begin()));
for_each(V.begin(), V.end(), [&](string & s) { S.count(s) == 0 ? M[s]++ : true; });
}
I have a map like std::map<std::string, std::vector<int> >. I want to create one vector out of all the sub-vectors from values of the map. I can do it using the loops but I wanted to use the boost::range library where I can pipe the input of one transform to another so that the code is more readable and succinct. I tried something like below but needed some help to do it correctly.
Thank you
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <iterator>
#include <vector>
#include <map>
#include <iostream>
struct GetMapValue
{
template<typename T1, typename T2>
const T2& operator()( const std::pair<T1,T2>& key_val ) const
{
return key_val.second;
}
};
struct GetINTs
{
GetINTs(std::vector<int> aVec1)
{
aMyVec = aVec1;
}
void operator()( const std::vector<int>& val )
{
aMyVec.insert( val.end(), val.begin(), aMyVec.end() );
}
private:
std::vector<int> aMyVec;
};
int main(){
std::map<std::string, std::vector<int> > x;
std::vector<int> y, z;
std::vector<int> temp;
temp.push_back(1);
temp.push_back(1);
x.insert(std::make_pair("one", temp));
temp.clear();
temp.push_back(2);
temp.push_back(2);
x.insert(std::make_pair("two", temp));
temp.clear();
temp.push_back(3);
temp.push_back(3);
x.insert(std::make_pair("three", temp));
boost::copy( x | boost::adaptors::transformed(GetMapValue), std::back_inserter(y) );
boost::copy( y | boost::adaptors::transformed(GetINTs), std::back_inserter(z) );
}
The adaptor already exists and is called
boost::adaptors::map_keys
boost::adaptors::map_values
Here's a sample:
Live On Coliru
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <iostream>
#include <iterator>
#include <vector>
#include <string>
#include <map>
int main() {
std::map<std::string, std::vector<int> > x {
{ "hello", { 1,2,3 } },
{ "world", { 4,5,6 } },
};
boost::copy(x | boost::adaptors::map_keys, std::ostream_iterator<std::string>(std::cout << "Keys: ", " "));
for (auto& vec : x | boost::adaptors::map_values)
boost::copy(vec, std::ostream_iterator<int>(std::cout << "\nValues: ", " "));
}
Prints
Keys: hello world
Values: 1 2 3
Values: 4 5 6
I would like to copy first N elements of a std::map to another map. I tried copy_n but failed miserably. How can I achieve that?
#include <iostream>
#include <map>
#include <algorithm>
#include <iterator>
using namespace std;
int main(){
map<int,int> Map;
for ( int i=0;i<10;i++) Map[i]=i*i;
map<int,int> Map2;
std::copy_n(Map.begin(), 5, Map2.end());
return 0;
}
Use copy_n? It works as it should:
#include <algorithm>
#include <iterator>
#include <iostream>
#include <map>
int main() {
std::map<int, int> m1 { { 1, 2 }, { 2, 9 }, { 3, 6 }, { 4, 100 } }, m2;
std::copy_n(m1.begin(), 2, std::inserter(m2, m2.end()));
for (auto const & x : m2)
std::cout << x.first << " => " << x.second << "\n";
}
If you're constructing the other map from scratch, you can simply pass it the iterators that it needs to the constructor:
std::size_t n = ...;
std::map<K, V> m1 = { ... };
std::map<K, V> m2(m1.begin(), std::next(m1.begin(), n));
If you want to create a new map, you can use the range constructor. Inserting into an existing map can be done with range std::map::insert.
// copy 3 elements from map source
std::map<K,V>::iterator first = source.begin();
// can also use std::next if available
std::map<K,V>::iterator last = source.begin();
std::advance(last, 3);
std::map<K,V> m1( other.begin(), last);
m1.insert(first, last);
std::copy can also be used, but then you must use an std::inserter as output iterator.