I am writing a C++ program that will take 2 lists, L and P, and am trying to write a method that will print the elements in L that are in positions specified in P. Here is the code:
#include <iostream>
#include <list>
#include <iterator>
#include <stdlib.h>
using namespace std;
void printLots( list L, list P );
int main()
{
list< int > numList = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000};
list< int > indexList = {2, 4, 6, 8, 10};
printLots( numList, indexList );
return 0;
}
void printLots( list L, list P )
{
int count;
list::iterator itrIndex;
list::iterator itrValue;
for( itrIndex = P.begin(); itrIndex != P.end(); ++itrIndex )
{
count = 1;
for( itrValue = L.begin(); itrValue != L.end(); ++itrValue )
{
if( count == *itrIndex )
{
cout << "Value in list L at index " << *itrIndex << " = " << *itrValue << endl;
}
++count;
}
}
}
For some reason when I try to compile, I am getting an error saying: "error: variable or field 'printLots' declared void
void printLots( list L, list P ) I mean, yes the function is void but thats because it is supposed to be. This function doesn't return anything so I have no clue why its giving me an error for this function being void. I have no clue how to fix this. Any help?
In your parameters for the method, the data type for the two parameters is some arbitrary list with no data type. You have to define a data type for the list as well.
list<int>, list<double>, list<...>
Your void printLots( list L, list P ) method doesn't specify the type of list. Try void printLots(list<int> L, list<int>P); You'll also have to specify the list type where you instantiate the iterators.
You could make printLots a templated function if you need it to handle multiple types.
Also you probably want to pass const list<int>& to avoid copying the lists since you aren't changing them.
Related
Looking for a way to sort an optional container Like the following...
#include <optional>
#include <vector>
using optional = std::optional<int>;
std::vector<optional> cont;
int main()
{
auto min_iter = std::min_element(cont.begin(), cont.end());
std::sort(cont.begin(), cont.end());
}
to get a guaranteed max/min element that passes has_value()
using optional = std::optional<int>;
std::vector<optional> cont = {2, 1, 4, {}, 7};
std::sort(cont.begin(), cont.end());
// Find first which passes has_value(), as sorted this should be minimum.
auto min_iter = std::find_if(cont.cbegin(), cont.cend(),
[](const auto& element) {
return element.has_value();
}
);
// Find last which passes has_value(), as sorted this should be maximum.
auto max_iter = std::find_if(cont.crbegin(), cont.crend(),
[](const auto& element) {
return element.has_value();
}
);
auto min_value = min_iter->value();
auto max_value = max_iter->value();
I am a simple man who likes simple solutions, so yes it can go through the container up to 2x.
I want the output to be: 1 2 2 2
But why is the output: 1 2 3 4
What's wrong with this code?
#include <iostream>
using namespace std;
int arr[] = {0};
int pluss(int ar[],int a){
ar[0]++;
cout<<ar[0]<<endl;
if(a==0){
pluss(ar,a+1);
pluss(ar,a+1);
pluss(ar,a+1);
}
}
int main() {
pluss(arr,0);
return 0;
}
EDIT: So, the "ar" is global and not local to one child function? how to make it so the "ar" is only local to one child function? I mean: the "ar" in the first pluss(ar,1) is different from the "ar" in the second pluss(ar,2)?
Your code is equivalent of :
int main() {
pluss(arr,0);
pluss(arr,1);
pluss(arr,1);
pluss(arr,1);
return 0;
}
Since each call to pluss definitely increments the array element, before printing it, expected output is 1, 2, 3, 4.
how to make it so the "ar" is only local to one child function?
If you don't like to pass each array element as integer value, you could wrap the array in a struct, since structures are passed by value rather than by reference.
#include <iostream>
using namespace std;
struct s { int a[1]; } arr = {0};
int pluss(struct s ar, int a)
{
ar.a[0]++;
cout <<ar.a[0] <<endl;
if (a==0)
{
pluss(ar, a+1);
pluss(ar, a+1);
pluss(ar, a+1);
}
}
int main()
{
pluss(arr, 0);
return 0;
}
I want to create a heap data structure to be able to update the value .
but my simple code below throw an exception. why it gives the following:
109 : 3 terminate called after throwing an instance of 'std::bad_function_call' what(): bad_function_call
#include <set>
#include <algorithm>
#include <functional>
#include <boost/heap/fibonacci_heap.hpp>
int main() {
// Creating & Initializing a map of String & Ints
std::map<int, vector<int> > mapOfWordCount = { { 1000, {0,1,10,8} }, { 10001, {1,5,99} }, { 1008, {7,4,1} } , { 109, {1,5,3} }};
// Declaring the type of Predicate that accepts 2 pairs and return a bool
typedef std::function<bool(std::pair<int, vector<int> > v1, std::pair<int, vector<int> > v2)> Comparator;
// Defining a lambda function to compare two pairs. It will compare two pairs using second field
Comparator compFunctor =
[](std::pair<int, vector<int> > elem1 ,std::pair<int, vector<int> > elem2)
{
return elem1.second.size() > elem2.second.size();
};
boost::heap::fibonacci_heap <std::pair<int, vector<int> >, boost::heap::compare<Comparator> > pq;
typedef boost::heap::fibonacci_heap< std::pair<int, vector<int> >, boost::heap::compare<Comparator> >::handle_type handle_t;
handle_t* tab_handle = new handle_t [mapOfWordCount.size()];
unsigned iter(0);
for( auto& element : mapOfWordCount) {
tab_handle[iter++]=pq.push(element);
std::cout << element.first << " : " << element.second.size() << std::endl;
}
}
std::bad_function_call exception is caused (in this case) when calling a std::function that is empty.
I have made this work by making Comparator a functor.
struct Comparator
{
bool operator()(std::pair<int, std::vector<int> > elem1, std::pair<int, std::vector<int> > elem2) const
{
return elem1.second.size() > elem2.second.size();
}
};
This can then be used in the declarations of pq and handle_t.
Output:
109 : 3
1000 : 4
1008 : 3
10001 : 3
See demo here.
You can figure out how to make it work with a lambda.
Hint: It involves using the lambda compFunctor as an argument for construction.
Why are my array of static bools not initialized properly? Only the first one is initialized - I suspect this is because the array is static.
The following MWE was compiled with GCC and is based on a function that I am writing that I have transferred into a main program to illustrate my problem. I have tried with and without c++11. My understanding is because this array is static and initialized to true this should always print the first time I enter my function. So in this MWE it should print once.
#include <iostream>
using namespace std;
const int arraysize = 10;
const int myIndex = 1;
static bool firstTimeOverall = true;
int main()
{
static bool firstCloudForThisClient[arraysize] = {true};
cout.flush();
if (firstCloudForThisClient[myIndex])
{
cout << "I never get here" << endl;
firstCloudForThisClient[myIndex] = false;
if (firstTimeOverall)
{
firstTimeOverall = false;
cout << "But think I would get here if I got in above" << endl;
}
}
return 0;
}
You may need to invert your conditions to take advantage of default initialisation:
#include <iostream>
using namespace std;
const int arraysize = 10;
const int myIndex = 1; // note this index does not access the first element of arrays
static bool firstTimeOverall = true;
int main()
{
static bool firstCloudForThisClient[arraysize] = {}; // default initialise
cout.flush();
if (!firstCloudForThisClient[myIndex])
{
cout << "I never get here" << endl;
firstCloudForThisClient[myIndex] = true; // Mark used indexes with true
if (firstTimeOverall)
{
firstTimeOverall = false;
cout << "But think I would get here if I got in above" << endl;
}
}
return 0;
}
static bool firstCloudForThisClient[arraysize] = {true};
This initializes the first entry to true, and all others to false.
if (firstCloudForThisClient[myIndex])
However, since myIndex is 1 and array indexing is zero-based, this accesses the second entry, which is false.
Your are initializing only first element on an array using array[size] = {true} , if arraysize variable is bigger then 1, the initial value of other elements depends on platform. I think it is an undefined behavior.
If you really need to init your array, use loop instead:
for(int i=0; i < arraysize; ++i)
firstCloudForThisClient[i] = true;
You should access the first element of the array so use:
const int myIndex = 0;
I have a std::vector<std::string> v; (initialized). How can I use the range-for loop for accessing all elements except the first one (on index zero). For all elements:
for (const string & s: v)
process(s);
Instead of the v a range expression can be used. How can I write the range expression to skip the first element (or skip the first n elements)?
I know how to get the effect using v.begin() + 1 and using the classic loop. I am searching for the new, more readable, recommended alternative to do that. Possibly something similar to Python slicing? ...like:
for s in v[1:]:
process(s)
Until ranges make it into the standard library, you won't get any better than a vanilla for loop in plain C++ :
for(auto i = begin(v) + 1, e = end(v); i !=e; ++i)
// Do something with *i
Create a wrapper for which begin() and end() return the correct iterators and then you can use that as the second argument.
#include <iostream>
#include <vector>
template< typename Collection >
class FromNth
{
Collection& coll_;
size_t offset_;
public:
FromNth( Collection& coll, size_t offset )
: coll_( coll ), offset_( offset )
{
}
// will nicely resolve to const_iterator if necessary
auto begin() const -> decltype( coll_.begin() )
{ return coll_.begin() + offset_; }
auto end() const -> decltype( coll_.end() )
{ return coll_.end(); }
};
template< typename Collection >
FromNth<Collection> makeFromNth( Collection& collection, size_t offset )
{
return FromNth<Collection>( collection, offset );
}
template< typename Collection >
auto begin( const FromNth<Collection> & wrapper ) -> decltype( wrapper.begin() )
{
return wrapper.begin();
}
template< typename Collection >
auto end( const FromNth<Collection> & wrapper ) -> decltype( wrapper.end() )
{
return wrapper.end();
}
int main()
{
std::vector< int > coll { 2, 3, 5, 7, 11, 13, 17, 19, 23 };
for( auto x : makeFromNth( coll, 1 ) )
{
std::cout << x << '\n';
}
return 0;
}
Note that my fromNth "begin" is undefined behaviour if the size of the input is less than the offset. (If it's equal then it's well defined and begin == end). Therefore do a size check first.
Note: if you are using a recent enough version of boost then iterator_range may already provide you such a "collection" that is similar to my "FromNth".
for( auto const& s : boost::make_iterator_range( v.begin() + 1, v.end() ) )
{
process( s );
}
Note: the code above worked on CodingGround using C++11 GNU 4.8.3. (That site is very slow though). From C++14 you will not need the ->decltype statements (which are needed in C++11 for templates).
Output:
sh-4.3$ g++ -std=c++11 -o main *.cpp
sh-4.3$ main
3
5
7
11
13
17
19
23