I am trying to get difference between consecutive elements in a std::list. I attempted the following solution but as this thread says, I need to make a copy of iterator and increment it. Not sure what it mean since adding number to iterators also result in error. what am I missing here. I am using a previous version of C++ but not C++ 11
#include "stdafx.h"
#include <list>
#include <iostream>
using namespace std;
int main()
{
std::list<int> myList;
//for (int i = 10;i < 15;i++)
myList.push_back(12);
myList.push_back(15);
myList.push_back(18);
myList.push_back(19);
myList.push_back(25);
for (std::list<int>::const_iterator itr = myList.begin();itr != myList.end();++itr)
{
int x = *itr;
int y = *(itr + 1);
int diff = std::abs(x - y);
cout << diff << "\n";
}
return 0;
}
How about using adjacent_difference ?
std::adjacent_difference(myList.begin(), myList.end(), tempList );
See Here
If you're interested in implementation look how its implemented in Possible Implementation section in attached link. All you have to do is replace with list iterator and for output just display on screen, or store it.
Use increment operator to move iterator.
auto x = itr;
auto y = itr;
if(++y!=myList.end())
{
int diff = std::abs(*x - *y);
cout << diff << "\n";
}
You can copy the iterator and run two, but I think it's easier to get the first value outside of the loop and then use the loop to iterate through the second value, resetting the first value with the second before proceeding to the next.
Something like this:
#include <list>
#include <iostream>
int main()
{
std::list<int> myList;
myList.push_back(12);
myList.push_back(15);
myList.push_back(18);
myList.push_back(19);
myList.push_back(25);
std::list<int>::const_iterator itr = myList.begin();
if(itr != myList.end()) // is a first value
{
int last = *itr; // cache it
for (itr++; itr != myList.end(); itr++) // get next value
{
int current = *itr; //cache it
int diff = std::abs(last - current);
std::cout << diff << "\n";
last = current; // update last value
}
}
return 0;
}
You can use std::advance() to get to the next iterator
int x = *itr;
std::list<int>::const_iterator itr2 = itr;
std::advance(itr2,1);
if(itr2==myList.end())
break;
int y = *(itr2);
int diff = std::abs(x - y);
cout << diff << "\n";
EDIT: If c++ 11 available, see std::next
#include <list>
#include <iostream>
int main()
{
std::list<int> myList;
//for (int i = 10;i < 15;i++)
myList.push_back(12);
myList.push_back(15);
myList.push_back(18);
myList.push_back(19);
myList.push_back(25);
for (std::list<int>::const_iterator itr = myList.begin();
itr != std::prev(myList.end());
++itr)
{
std::list<int>::const_iterator nextIt = std::next(itr);
int diff = *itr - *nextIt;
std::cout << diff << "\n";
}
return 0;
}
Use std::next(itr) to get next iterator
and use std::prev(myList.end()) in for loop to get previous of last element in list.
Also you can change your for loop and use std::advance() to get next iterator without using std::next and std::prev
std::list<int>::const_iterator itr = myList.begin();
while (true)
{
int prevValue= *itr;
std::advance(itr, 1);
if (itr == myList.end())
{
break;
}
int diff = prevValue - *itr;
std::cout << diff << "\n";
}
Another way would be to simply keep track of the previous list element value, not the iterator, and to subtract that previous value from the element the iterator is currently pointing to; like so:
#include <list>
#include <cmath> // need cmath for std::abs
#include <iostream>
using namespace std;
int main()
{
std::list<int> myList;
//for (int i = 10;i < 15;i++)
myList.push_back(12);
myList.push_back(15);
myList.push_back(18);
myList.push_back(19);
myList.push_back(25);
int PreviousElement = 0;
bool Start = false;
for (std::list<int>::const_iterator itr = myList.begin(); itr != myList.end(); ++itr)
{
if (Start)
{
int diff = std::abs(*itr - PreviousElement);
cout << diff << "\n";
}
else
{
Start = true;
}
PreviousElement = *itr;
}
return 0;
}
I think you need two iterator to solve this question
Here's my code
#include "stdafx.h"
#include <list>
#include <iterator>
#include <iostream>
using namespace std;
int main()
{
std::list<int> myList;
//for (int i = 10;i < 15;i++)
myList.push_back(12);
myList.push_back(15);
myList.push_back(18);
myList.push_back(19);
myList.push_back(25);
int x = 0;
int y = 0;
std::list<int>::iterator itr;
std::list<int>::iterator it_next;
for (itr = myList.begin(), it_next = ++myList.begin();it_next != myList.end();itr++, it_next++)
{
x = *itr;
y = *it_next;
int diff = abs(x - y);
cout << diff << "\n";
}
system("PAUSE");
return 0;
}
I build it in VC++2005 but it should work fine in C++
Hope this will help you :)
Related
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "hello_world.h"
using namespace std;
class Solution1 {
public:
int removeDuplicates(vector<int>& nums) {
return distance(nums.begin(), removeDuplicates(nums.begin(), nums.end(), nums.begin()));
}
template<typename InIt, typename OutIt>
OutIt removeDuplicates(InIt begin, InIt end, OutIt output){
while(begin != end){
*output++ = *begin;
begin = upper_bound(begin, end, *begin);
}
return output;
}
};
class Solution2 {
public:
int removeDuplicates(vector<int>& nums) {
vector<int>::iterator output = nums.begin();
while(nums.begin() != nums.end()){
*output++ = *nums.begin();
nums.begin() = upper_bound(nums.begin(), nums.end(), *nums.begin());
}
return distance(nums.begin(), output);
}
};
int main()
{
//helloworld test;
//test.print();
int num[3] = {1,1,2};
vector<int> nums(num, num + 3);
Solution2 so;
int a = so.removeDuplicates(nums);
cout<<a<<endl;
return 0;
}
In main function, when i use the class solution1, the code can remove duplicates numbers from the arrary [1 1 2] ,to output [1 2]. In order to simplify the code, I changed the solution1 to solution2, but the solution2 can not execute right output, anybody know the reason?
In this while loop
while(nums.begin() != nums.end()){
*output++ = *nums.begin();
nums.begin() = upper_bound(nums.begin(), nums.end(), *nums.begin());
}
you are always using the iterator nums.begin() in the condition and in this statement
*output++ = *nums.begin();
because this statement
nums.begin() = upper_bound(nums.begin(), nums.end(), *nums.begin());
does not change the iterator returned by a new call of nums.begin().
You need to introduce a variable of the iterator type before the loop like
auto it = nums.begin();
while( it != nums.end()){
*output++ = *it;
it = upper_bound( it, nums.end(), *it );
}
Here is a demonstrative program
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
{
std::vector<int> v = { 1, 2 };
size_t i = 0;
while ( v.begin() != v.end() )
{
v.begin() = std::upper_bound( v.begin(), v.end(), *v.begin() );
if ( ++i == 10 ) break;
}
std::cout << "i = " << i << '\n';
i = 0;
auto it = v.begin();
while ( it != v.end() )
{
it = std::upper_bound( it, v.end(), *it );
if ( ++i == 10 ) break;
}
std::cout << "i = " << i << '\n';
return 0;
}
Its output is
i = 10
i = 2
To erase duplicates after the loop use the member function erase like
nums.erase( output, nums.end() );
The same can be done using the standard algorithm std::unique. For example
nums.erase( std::unique( nums.begin(), nums.end() ), nums.end() );
So here is my program with the error:
// ConsoleApplication42.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <list>
#include <cstdlib>
#include <time.h>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
const int numberOfStudents = 9;
string names[numberOfStudents] = {"Abe","Billy","Carl","Dillan","Eddie","Felix","Gill","Herald","Isaac"};
struct StudentInfo {
string name;
int grade;
bool operator< (int grade){
return grade < grade;
}
bool operator< (string name){
return name < name;
}
};
void populateStudentRecords(vector<StudentInfo>Students,vector<int>::iterator iter, int x){
for(auto iter = Students.begin(); iter != Students.end(); ++iter){
iter->name = names[x];
iter->name.push_back(x);
iter->grade = x++;
x = x++;
}
}
bool sortByName(const StudentInfo x, const StudentInfo y){
return x.name < y.name;
}
bool sortByGrade(const StudentInfo x, const StudentInfo y){
return x.grade < y.grade;
}
void displayRecords(vector<StudentInfo>Records,vector<int>::iterator iter){
for(auto iter = Records.begin(); iter != Records.end(); ++iter){
cout<<*iter->name<<" -"<<*iter->grade<<endl;
}
}
void displayMaxAndMinGrade(vector<StudentInfo>Records,vector<int>::iterator iter){
for(auto iter = Records.begin(); iter != Records.end(); ++iter){
cout<<*iter->name<<" - " <<*iter->grade<<endl;
iter = Records.end();
cout<<*iter->name<<" - " <<*iter->grade<<endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<StudentInfo>Records (numberOfStudents);
vector<int>::iterator iter;
populateStudentRecords(Records,iter,0);
sort(Records.begin(),Records.end(),sortByName);
displayRecords(Records,iter);
sort(Records.begin(),Records.end(),sortByGrade);
cout<<" "<<endl;
displayMaxAndMinGrade(Records, iter);
return 0;
}
In the displayRecords function and the displayMaxAndMin function, I have the * symbol next to the iterator. I want the computer to display the value of these variables within each occurrence of the structure in the vector. However, I get an error c2100 when I try to build the program. I have tried to run the program without including the * symbol, but that displays the address of each variable and also leads to a crash. How do I fix this? Thank you.
You need to read an introductory book on programming with C++. This code is full of errors. You don't know how to use pointers/references/iterators.
Learn about copying, references, and pointers from a good book. Follow the link at the end of this answer.
Variables should be limited to the scope in which they are used. Stop passing so many arguments to your function when they don't really need them.
You are using both the indirection and dereference operators at the same time when you only need one for the type you are applying the operators to. This is the reason for your error.
You are incrementing an array index twice per loop, which makes it go out of bounds.
You are using your container's end() member function with the assumption that it returns an iterator to the last element in the container.
You want to print the lowest and highest grades but loop through the whole container.
For your sake, I've fixed the most glaring errors:
#include <iostream>
#include <list>
#include <cstdlib>
#include <time.h>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
const int numberOfStudents = 9;
string names[numberOfStudents] = { "Billy", "Abe","Carl","Dillan","Eddie","Felix","Gill","Herald","Isaac" };
struct StudentInfo
{
string name;
int grade;
};
void populateStudentRecords(vector<StudentInfo>& Students)
{
int x{ 0 };
for (auto iter = Students.begin(); iter != Students.end(); ++iter)
{
iter->name = names[x];
iter->name.push_back(x);
iter->grade = ++x;
}
}
bool sortByName(const StudentInfo x, const StudentInfo y)
{
return x.name < y.name;
}
bool sortByGrade(const StudentInfo x, const StudentInfo y)
{
return x.grade < y.grade;
}
void displayRecords(vector<StudentInfo>Records)
{
for (auto iter = Records.begin(); iter != Records.end(); ++iter)
{
cout << iter->name << " -" << iter->grade << endl;
}
}
void displayMaxAndMinGrade(vector<StudentInfo>Records)
{
auto iter = Records.begin();
cout << iter->name << " - " << iter->grade << endl;
iter = Records.end() - 1;
cout << iter->name << " - " << iter->grade << endl;
}
int main()
{
vector<StudentInfo>Records(numberOfStudents);
populateStudentRecords(Records);
sort(Records.begin(), Records.end(), sortByName);
displayRecords(Records);
sort(Records.begin(), Records.end(), sortByGrade);
cout << " " << endl;
displayMaxAndMinGrade(Records);
return 0;
}
Please do yourself a favor and visit the following link:
The Definitive C++ Book Guide and List
I'm attempting to create an algorithm in C++ which will give me all of the possible combinations of a set of list items (input in a map format). I want to avoid duplicates and make sure to cover all possible combinations. To simplify the example, here's what the input may look like:
map<string, vector<string> > sandwichMap;
sandwichMap["bread"].push_back("wheat");
sandwichMap["bread"].push_back("white");
sandwichMap["meat"].push_back("ham");
sandwichMap["meat"].push_back("turkey");
sandwichMap["meat"].push_back("roastbeef");
sandwichMap["veggie"].push_back("lettuce");
sandwichMap["sauce"].push_back("mustard");
I'd feed this map into the algorithm, and it should spit out a vector with all of the possible combinations (using one of each key type):
wheat+ham+lettuce+mustard
wheat+turkey+lettuce+mustard
wheat+roastbeef+lettuce+mustard
white+ham+lettuce+mustard
white+turkey+lettuce+mustard
white+roastbeef+lettuce+mustard
It needs to work for any map of string vectors. So far I've tried and gotten close, but I end up with duplicate combinations and missed combinations:
sandwichList getCombinations(sandwichMap sMap)
{
locList retList;
int totalCombos = 1;
for (sandwichMapIt i = sMap.begin(); i != sMap.end(); ++i)
{
totalCombos *= i->second.size();
}
retList.resize(totalCombos);
int locCount;
for (sandwichMapIt a = sMap.begin(); a != sMap.end(); ++a)
{
locCount = 0;
for (locListIt l = a->second.begin(); l != a->second.end(); ++l)
{
for (unsigned int i = 0; i < totalCombos / a->second.size(); ++i)
{
retList[i + a->second.size() * locCount] += *l;
}
locCount++;
}
}
return retList;
}
Any help would be greatly appreciated!
Updated code:
#include <vector>
#include <map>
#include <list>
#include <iostream>
typedef std::vector<std::string> strVec;
typedef std::list<std::string> strList;
typedef std::map<std::string, strVec> sandwichMap;
int main()
{
sandwichMap sMap;
sMap["bread"].push_back("wheat");
sMap["bread"].push_back("white");
sMap["meat"].push_back("ham");
sMap["meat"].push_back("turkey");
sMap["meat"].push_back("roastbeef");
sMap["veggie"].push_back("lettuce");
sMap["sauce"].push_back("mustard");
strList finalSandwichList;
for (sandwichMap::iterator i = sMap.begin(); i != sMap.end(); ++i)
{
strList tmpSandwich;
for (strVec::iterator j = i->second.begin(); j != i->second.end(); ++j)
{
if (finalSandwichList.empty())
{
tmpSandwich.push_back(*j);
}
else
{
for (strList::iterator k = finalSandwichList.begin(); k != finalSandwichList.end(); ++k)
tmpSandwich.push_back(*k + "+" + *j);
}
}
tmpSandwich.swap(finalSandwichList);
}
for (strList::iterator i = finalSandwichList.begin(); i != finalSandwichList.end(); ++i)
{
std::cout << *i << std::endl;
}
return 0;
}
//solution
std::list<std::string> result;
for(auto i=sandwichMap.begin(); i!=sandwichMap.end(); ++i) {
std::list<std::string> new_result;
for(auto j=i->second.begin(); j!=i->second.end(); ++j) {
if(result.empty())
new_result.push_back(*j);
else
for(auto k=result.begin(); k!=result.end(); ++k)
new_result.push_back(*k + "+" + *j);
}
new_result.swap(result);
}
This should work :
#include<iostream>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
map<string, vector<string>> sMap;
vector<string> add;
int sett[200], countt;
void solve(map<string, vector<string>>::iterator itt, int ct, vector<string> addd){
vector<string> tmp = itt->second;
if(ct == countt){
for(int j=0;j<addd.size();j++){
cout<<addd[j]<<" ";
}
cout<<endl;
return;
}
itt++;
for(int i=0;i<tmp.size();i++){
//cout<<tmp[i]<<" ";
addd.push_back(tmp[i]);
solve(itt, ct+1, addd);
vector<string>::iterator tempIt = addd.end();
addd.erase(tempIt--);
}
}
int main(){
sMap["bre"].push_back("wh");
sMap["bre"].push_back("whi");
sMap["me"].push_back("ham");
sMap["me"].push_back("tur");
sMap["me"].push_back("rr");
sMap["veg"].push_back("let");
sMap["sau"].push_back("mus");
countt = sMap.size();
solve(sMap.begin(), 0, add);
return 0;
}
I have used backtracking to evaluate every possible combination.
Note : it is in c++11 you might need to change some part of the code for lower version of c++
link to output : http://ideone.com/Ou2411
The code is kinda long because of the helper methods, but it does the job:
#include <vector>
#include <string>
#include <map>
#include <iostream>
using namespace std;
template <class T>
vector<T> Head(const vector<T> &v) {
return vector<T>(v.begin(), v.begin() + 1);
}
template <class T>
vector<T> Tail(const vector<T> &v) {
auto first = v.begin() + 1;
auto last = v.end();
return vector<T>(first, last);
}
template <class T>
vector<T> Concat(const vector<T> &v1, const vector<T> &v2) {
vector<T> result = v1;
result.insert(result.end(), v2.begin(), v2.end());
return result;
}
vector<vector<string>> CombineVectorWithScalar(const vector<vector<string>> &v, const string &scalar) {
vector<vector<string>> result = v;
for (unsigned i = 0; i < v.size(); i++) {
result[i].push_back(scalar);
}
return result;
}
vector<vector<string>> CombineVectorWithVector(const vector<vector<string>> &v1, const vector<string> &v2) {
if (v2.empty()) {
return vector<vector<string>>();
}
else {
auto headCombination = CombineVectorWithScalar(v1, v2.front());
auto tailCombination = CombineVectorWithVector(v1, Tail(v2));
return Concat(headCombination, tailCombination);
}
}
vector<string> GetKeys(const map<string, vector<string>> &mp) {
vector<string> keys;
for (auto it = mp.begin(); it != mp.end(); ++it) {
keys.push_back(it->first);
}
return keys;
}
vector<vector<string>> CombineMapValues(const map<string, vector<string>> &mp) {
vector<string> keys = GetKeys(mp);
vector<vector<string>> result;
auto &firstVector = mp.begin()->second;
for (auto it = firstVector.begin(); it != firstVector.end(); ++it) {
vector<string> oneElementList;
oneElementList.push_back(*it);
result.push_back(oneElementList);
}
vector<string> restOfTheKeys = Tail(keys);
for (auto it = restOfTheKeys.begin(); it != restOfTheKeys.end(); ++it) {
auto ¤tVector = mp.find(*it)->second;
result = CombineVectorWithVector(result, currentVector);
}
return result;
}
void PrintCombinations(const vector<vector<string>> & allCombinations) {
for (auto it = allCombinations.begin(); it != allCombinations.end(); ++it) {
auto currentCombination = *it;
for (auto itInner = currentCombination.begin(); itInner != currentCombination.end(); ++itInner) {
cout << *itInner << " ";
}
cout << endl;
}
}
int main() {
map<string, vector<string> > sandwichMap;
sandwichMap["bread"].push_back("wheat");
sandwichMap["bread"].push_back("white");
sandwichMap["meat"].push_back("ham");
sandwichMap["meat"].push_back("turkey");
sandwichMap["meat"].push_back("roastbeef");
sandwichMap["veggie"].push_back("lettuce");
sandwichMap["sauce"].push_back("mustard");
auto allCombinations = CombineMapValues(sandwichMap);
PrintCombinations(allCombinations);
return 0;
}
void generate_all(std::map<std::string,std::vector<std::string>>::iterator start,
std::vector<std::string::iterator> accomulator,
std::map<std::string,std::vector<std::string>>& sMap){
for (auto it=start; it!=sMap.end(); ++it){
for (auto jt=it->second.begin(); jt!=it->second.end(); jt++){
generate_all(start+1,accomulator.pus_back[jt],sMap);
}
}
if (accomulator.size() == sMap.size()){
// print accomulator
}
}
Call with generate_all(sMap.begin(),aVector,sMap);
If the map is too big to go recursively, you can always generate an equivalent iterative code.
This solution is not recursive. Basically what it does is the following:
Compute how many combinations are actually possible
Know that for each key in the map, you're going to have to add nrCombinations/nrItemsInKey of them in total.
You can see it as a tree growing, branching more and more the more keys you have visited.
If you keep track of how many there are, how spaced they are and where they start you can automatically fill all combinations.
Code
#include <vector>
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<std::string, std::vector<std::string> > sandwichMap;
sandwichMap["bread"].push_back("wheat");
sandwichMap["bread"].push_back("white");
sandwichMap["meat"].push_back("ham");
sandwichMap["meat"].push_back("turkey");
sandwichMap["meat"].push_back("roastbeef");
sandwichMap["veggie"].push_back("lettuce");
sandwichMap["sauce"].push_back("mustard");
sandwichMap["sauce"].push_back("mayo");
// Compute just how many combinations there are
int combinationNr = 1;
for ( auto it : sandwichMap ) {
combinationNr *= it.second.size();
}
std::vector<std::vector<std::string>> solutions(combinationNr);
// We start with empty lists, thus we only have one cluster
int clusters = 1, clusterSize = combinationNr;
for ( auto category : sandwichMap ) {
int startIndex = 0;
int itemsNr = category.second.size();
int itemsPerCluster = clusterSize / itemsNr;
for ( auto item : category.second ) {
for ( int c = 0; c < clusters; ++c ) {
for ( int i = 0; i < itemsPerCluster; ++i ) {
// We sequentially fill each cluster with this item.
// Each fill starts offset by the quantity of items
// already added in the cluster.
solutions[startIndex+i+c*clusterSize].push_back(item);
}
}
startIndex += itemsPerCluster;
}
clusters *= itemsNr;
clusterSize = combinationNr / clusters;
}
for ( auto list : solutions ) {
for ( auto element : list ) {
std::cout << element << ", ";
}
std::cout << "\n";
}
return 0;
}
I've been playing with C++11 functional in order to do the same as python's itertools.combinations(input, 2), so far this is what I have:
EDIT removed outer lambda as suggested by #DavidRodrÃguez-dribeas
#include <iostream>
#include <functional>
#include <vector>
using namespace std;
template <class T>
function<pair<T*, T*>()> combinations(vector<T> & input) {
auto it1 = input.begin();
auto end = input.end();
auto it2 = next(it1);
return [=]() mutable {
if (it2 == end) {
it1++;
it2 = next(it1);
}
if (it2 != end)
return pair<T*,T*>(&(*it1), &(*it2++));
return pair<T*,T*>(&*end, &*end);
};
};
int main (void) {
vector<int> numbers{1,2,3,4,5,6};
auto func = combinations(numbers);
while ( true ) {
auto i = func();
if (i.first == &*(numbers.end())) break;
cout << *(i.first) << ',' << *(i.second) << endl;
}
return 0;
};
I'm not happy with the method used to iterate over the combinations any advice on cleaning it up?
Here is documentation and code on my favorite way of doing this. And here is how that library would be used for your example:
#include <iostream>
#include <vector>
#include "combinations"
using namespace std;
int main (void) {
vector<int> numbers{1,2,3,4,5,6};
for_each_combination(numbers.begin(), numbers.begin()+2, numbers.end(),
[](vector<int>::const_iterator b, vector<int>::const_iterator e)
{
if (b != e)
{
cout << *b;
for (auto i = b+1; i != e; ++i)
cout << ',' << *i;
cout << endl;
}
return false;
});
}
1,2
1,3
1,4
1,5
1,6
2,3
2,4
2,5
2,6
3,4
3,5
3,6
4,5
4,6
5,6
Should the need arise, it is trivial to change the example use to consider 3 or 4 items at time instead of 2. One can also deal with various permutations k out of N at a time.
Update
Adding a level of indirection to illustrate how you would deal with a vector of items that were not efficient at moving/swapping around in the vector:
#include <iostream>
#include <vector>
#include "combinations"
using namespace std;
int main (void) {
vector<int> numbers{1,2,3,4,5,6};
vector<vector<int>::const_iterator> num_iters;
num_iters.reserve(numbers.size());
for (auto i = numbers.begin(); i != numbers.end(); ++i)
num_iters.push_back(i);
for_each_combination(num_iters.begin(), num_iters.begin()+2, num_iters.end(),
[](vector<vector<int>::const_iterator>::const_iterator b,
vector<vector<int>::const_iterator>::const_iterator e)
{
if (b != e)
{
cout << **b;
for (auto i = b+1; i != e; ++i)
cout << ',' << **i;
cout << endl;
}
return false;
});
}
I found out that Oliver Kowalke's coroutine library has been accepted by Boosts peer review and should be included hopefully in the next version. Jumping the gun a bit I gave it a go by using the coroutine branch of the boost-dev repo (https://gitorious.org/boost-dev/boost-dev).
g++ -I path/to/boost-dev -std=c++11 test_code.cpp -o run_test_code -static -L path/to/boost-dev/stage/lib/ -lboost_context
#include <boost/coroutine/all.hpp>
#include <boost/bind.hpp>
#include <boost/range.hpp>
#include <iostream>
#include <vector>
using namespace std;
using namespace boost;
template <typename T>
using coro_pairT_void = coroutines::coroutine<pair<T&,T&>(void)>;
template <typename T>
void combinations(typename coro_pairT_void<T>::caller_type & self, vector<T> & input ) {
for (auto it1 = input.begin(), itend = input.end(); it1 != itend; it1++) {
for (auto it2 = std::next(it1); it2 != itend; it2++) {
self(pair<T&, T&>(*it1,*it2));
}
}
};
int main( void ) {
vector<int> numbers{1,2,3,4,5,6};
coro_pairT_void<int> func(bind(combinations<int>, _1, numbers));
for (auto it(begin(func)), itend(end(func)); it != itend; ++it) {
cout << it->first << ',' << it->second << endl;
}
return 0;
};
i have an STL map ;
i would like to get the first non NULL value in the map;
is there an efficient/quick way to do that?
#include <map>
#include <algorithm>
#include <iostream>
using namespace std;
bool IsNotNull(const pair<const int, int>& i)
{
return i.second != 0;
}
int main() {
map<int, int> m;
m[0] = 0;
m[1] = 1;
map<int, int>::const_iterator it = find_if(m.begin(), m.end(), IsNotNull);
cout << it->second << endl;
return 0;
}
Ideone demo
There's nothing quicker than just looping through and finding what you're looking for
for (map<X,Y>::const_iterator i = m.begin(); i != m.end(); ++i)
{
if (i->second != NULL)
{
// do something with first non-NULL value
break;
}
}