How to use std::transform() function - c++

Ok basically i need to use the std::transform() function. I am trying however to pass an object function in as the last argument though and it doesnt seem to work.
class isprime {
public:
// declares the constructor and the operator() overloading
isprime(){ number = 0, primes.push_back(2);};
bool operator()(int);
private:
// various private functions and variables
int number;
list<int> primes; //creats a list via the stl library
void morePrimes(int); //function to generate more prime numbers
bool it; // Iterator for the morePrimes list
bool primeCheck; // Bool used in the morePrimes function
};
bool isprime::operator()(int number)
{
if(number == 1) //returns false for 1
return false;
if(number > primes.back()){ //Tests to see if the list of primes range would include the number, if not it runs the morePrimes function
morePrimes(number);
}
it = binary_search(primes.begin(),primes.end(),number); //uses stl find to see if the number is in the list of primes.
if(it) //if the returned iterator points to a value = to number then number is prim.
return true;
return false; //returns false if the number wasnt found
};
transform(random_list.begin(), random_list.end(), isprime_list.begin(), test());
Above i have included the class, the function and the call i used for transform. Anyone know why this doesnt work? I cant figure it out.

If you provide void isprime::more_primes(int) somewhere, removing the parentheses in test() is likely enough:
int main()
{
auto gen = bind(uniform_int_distribution<>(), mt19937());
list<int> random_list;
for (int i=0; i<5; i++) random_list.push_back(gen());
list<int> isprime_list(random_list.size());
isprime test;
transform(random_list.begin(), random_list.end(), isprime_list.begin(), test);
}
See it 'running' (well, compiling) on Coliru: http://coliru.stacked-crooked.com/a/3d908cb5cdc5c543
#include <list>
#include <algorithm>
using namespace std;
class isprime {
public:
// declares the constructor and the operator() overloading
isprime(){ number = 0, primes.push_back(2);};
bool operator()(int);
private:
// various private functions and variables
int number;
list<int> primes; // creats a list via the stl library
void morePrimes(int); // function to generate more prime numbers
bool it; // Iterator for the morePrimes list
bool primeCheck; // Bool used in the morePrimes function
};
bool isprime::operator()(int number)
{
if(number == 1) // returns false for 1
return false;
if(number > primes.back()){ // Tests to see if the list of primes range would include the number, if not it runs the morePrimes function
morePrimes(number);
}
it = binary_search(primes.begin(),primes.end(),number); // uses stl find to see if the number is in the list of primes.
if(it) // if the returned iterator points to a value = to number then number is prim.
return true;
return false; // returns false if the number wasnt found
}
void isprime::morePrimes(int) {}
#include <random>
#include <functional>
#include <iostream>
#include <iterator>
int main()
{
auto gen = bind(uniform_int_distribution<>(), mt19937());
list<int> random_list;
for (int i=0; i<5; i++) random_list.push_back(gen());
list<int> isprime_list(random_list.size());
isprime test;
transform(random_list.begin(), random_list.end(), isprime_list.begin(), test);
}

Related

random number generator that doesn't repeat it self (cpp/c++)

I want to make a function that generates numbers but doesn't repeat it self. If every number is generated the array can be emptied and it can start over again.
This is the code I made but it doesn't work.
The comments in the code explains the code a little.
The largest number that is allowed is "howManyWords".
This is used to display words which are stored in an array
I want to use it like this: array\[random()\]
#include <stdio.h>
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
//public scope
int howManyWords; // how many words you have enter
int random(){
int random;
int numbers[howManyWords];
srand(time(0)); //changing the algorithm
random = rand() % howManyWords;
numbers[random] = random; // store the digit in the position in the array equal to the digit that is generated
for(int i=0; i<howManyWords; i++){ // going through every element in the array
if(numbers[i] == random){ // if the number is already generated, generate a different number
random = rand() % howManyWords;
}
}
return random;
}
Rather than your function, which discards the state of which numbers it has returned each time it is called, you should use a function object.
struct random_t {
random_t(int max) : values(max), current(max) {
std::iota(values.begin(), values.end(), 0);
}
template<typename URBG = std::random_device &>
int operator()(URBG&& urbg = default_random) {
if (current == values.size()) {
shuffle(std::forward<URBG>(urbg));
}
return values[current++];
}
private:
template<typename URBG>
void shuffle(URBG&& urbg) {
std::shuffle(values.begin(), values.end(), std::forward<URBG>(urbg));
current = 0;
}
std::vector<int> values;
std::vector<int>::size_type current;
static thread_local std::random_device default_random;
};
See it live

c++ function return the smallest positive integer in a vector

I am using this code below which returns the smallest positive integer in a vector. I got the code here. My question is there a reason to pass the size to the function, can you not calculate it in the function body?
Also what is the second if() testing for? I can't understand how this if statement works?
#include <vector>
using namespace std;
int rec_min_pos(const vector<int> & nums, int size) {
if (size < 1) {
return INT_MAX;
}
if(nums[size-1] > 0){
return min(nums[size-1], rec_min_pos(nums, size-1));
}
else{
return rec_min_pos(nums, size-1);
}
}
The second if statement checks for positivity of the element, since the function shall return the minimum positive integer.
Your function is recursive and the 'size' argument is actually one plus the index to the last element to be tested. This allows a simple recursive function design, but requires an additional argument. It's presumably better to make these points explicit in the function interface
inline int recursive_min_positive(const int*arr, size_t i)
{
return
i==0? std::numeric_limits<int>::max() :
arr[i-1]<=0? recursive_min_positive(arr,i-1) :
std::min(arr[i-1],recursive_min_positive(arr,i-1) ;
}
int min_positive(std::vector<int> const&arr)
{
return recursive_min_positive(arr.data(), arr.size());
}
Recursive function design is often elegant, but inefficient (though compilers tend to unroll the recursion). Here, a non-recursive implementation is actually shorter and clearer.
int min_positive(std::vector<int> const&arr)
{
int result = std::numeric_limits<int>::max();
for(auto val : arr)
if(0 < val && val < result) result = val;
return result;
}
In addition to all comments: you can overload the function like this:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// Original function with size argument
int rec_min_pos(const vector<int> & nums, int size) {
if (size < 1) {
return INT_MAX;
}
if (nums[size - 1] > 0) {
return min(nums[size - 1], rec_min_pos(nums, size - 1));
}
else {
return rec_min_pos(nums, size - 1);
}
}
// Overloaded rec_min_pos function
int rec_min_pos(const vector<int> & nums) {
// here we just call the original rec_mon_pos function
return rec_min_pos(nums, nums.size());
}
int main()
{
vector<int> v{ 9,2,7,3,7,5,6 };
cout << rec_min_pos(v); // call the overloaded function
}
Output:
2
Not related to the recursive function, but expanding on my comment:
int min_positive(std::vector<int> & nums)
{
auto elem = std::min_element(nums.begin(), nums.end(),
[](int lhs, int rhs){ return std::tie(std::signbit(lhs), lhs) < std::tie(std::signbit(rhs), rhs); }
);
if ((elem == nums.end()) || std::signbit(*elems)) { return MAX_INT; }
return *elem;
}
Here we define a comparison function that orders positive before negative, and then by value. We use the three argument std::min_element, which will find us an iterator in nums.
The first check handles an empty nums, and the second one where every value is negative, both of which the original ignores, returning MAX_INT

C++ Using find on a list of objects

I can not seem to get std::find to work with a std::list of objects. I get the error "no match for ‘operator==’ (operand types are ‘Rabbit’ and ‘const int’) ". Fairly sure I need to utilize an object iterator and a lambda function, I'm just completely lost on how to do so and I just need some guidance. What I am ultimately trying to do is to iterator to a specific location in the list and pull the color string from that object in the list.
Edited to clarify the question and simplify the code
#include <iostream>
#include <list>
#include <algorithm>
#include "Rabbit.h"
#include "Population.h"
using namespace std;
int main()
{
Population Tracker;
Tracker.parentSeed(); //generate first random 8, and populate the list
Tracker.Breed(); //generate children, not working nothing happening as getMother does not work
return 0;
}
class Rabbit
{
protected:
const std::vector<std::string> namesList
{"Maxwell", "David", "Laura", "Sarah" , "Benjamin", "Carl",
"Rick", "Maggie", "Glenn", "Daryl", "Michonne", "Roseita",
"Leslie", "Randy", "Ethan", "Survan", "Leah", "Tisha", "Marcus"};
const std::vector<std::string> colorList
{"Red", "Green", "Blue",
"Grey", "Tan", "Brown",
"Calico", "White"};
public:
Rabbit(); //blank for the initial population
Rabbit(int); // pass an int for color inherited from mother
~Rabbit();
void getRabbit();
void randomNumGen(int);
std::string name;
std::string color;
};
Rabbit::Rabbit()
{
std::random_device random; //random seed obj
std::default_random_engine e1(random()); //get a random number seed
std::uniform_int_distribution<int> name_dist(0, 17); // vector position of name
std::uniform_int_distribution<int> color_dist(0, 7); // vector position of col
color = colorList[color_dist(e1)];
name = nameList[name_dist(e1)];
}
class Population
{
friend class Rabbbit;
protected:
public:
Population();
void popStats(int, bool);
void popList(Rabbit);
int getMother();
void parentSeed(); // generate initial population. All stats are random.
std::list<Rabbit> femaleList;
std::list<Rabbit> maleList;
std::list<Rabbit>::iterator male_it;
std::list<Rabbit>::iterator female_it;
};
int Population::getMother()
{
female_it++
//do something to iterate list and get data from the object at that position. Not to be sequential, just used that as example.
}
void Population::Breed()
{
/*
generate a new rabbit with color inhereited from the mother
father does not matter as all other stats are random
*/
if(maleList.size() > 2 && femaleList.size() > 2)
{
getMother(); // does nothing right now
std::cout << "Breed Success!" << std::endl;
Rabbit newRabbit;
popList(newRabbit);
}
}
void Population::parentSeed()
{
/*
Generate the initial seed count
*/
for (int i = 0; i < 8; i++)
{
Rabbit newRabbit;
popList(newRabbit);
}
}
The compiler is not aware of how it should distinguish between your Rabbits and raw integers. Thus, it's telling that you need to show it how to distinguish between them by defining an overloaded equality operator for your Rabbit objects and integers. You should add the following overloaded operators to your code:
bool
operator==(int const &i, Rabbit const &r) {
...
return ?;
}
bool
operator==(Rabbit const &r, int const &i) {
...
return ?;
}

combinations of k-tuple from n elements set by recursive

#include <vector>
#include <iostream>
using namespace std;
void SubSetNum(bool * select, int*a, int selectk, int k, int selectn, int n )// depthk to
{
if(k>n) return;
if(selectn==n)
{
if(selectk==k)
{
for(int i=0;i<n;i++)
if(select[i]==true)
cout<<a[i];
cout<<endl;
}
return;
}
select[selectk]=false;
SubSetNum(select,a,selectk,k,selectn+1,n);
select[selectk]=true;
SubSetNum(select,a,selectk+1,k,selectn+1,n);
}
int main()
{
int k=3;
int n=5;
int a[]={1,5,8,10,13};
//while(cin>>k)
{
bool *select=new bool[n];
memset(select,0,sizeof(bool)*n);
SubSetNum(select,a,0,k,0,n);
delete []select;
}
return 0;
}
This a question, that I want to get k elements from n elements set.
But it prints out incorrect answer? I am always confused when I design recursive algorithms...Especially the parameter of functions, if or not return value, and so on, thus I always try to forcely remember the code in textbook.
Your mistake is here:
select[selectk]=false;
...
select[selectk]=true;
It should be this:
select[selectn]=false;
...
select[selectn]=true;
I believe the cause of the mistake was a failure to remember what the variables represent. The variable selectn is the index of the element being included or excluded. The variable selectk is the number of elements already included. It does not make sense to use selectk as an index into a.

maintaining a recursion count

I'm trying to count the number of calls within a recursive permutation function.
I've written a function that fills a queue with all the permutations but I can't seem to figure out how to maintain an accurate count.
Ultimately i'd like the function to return a subset of the permuatations specified by lbound and ubound arguments, and to do so I think i need someway to keep an internal count.
Using the size of the returned queue will not work since i'd like the function to be able to handle permutations too big to hold in memory.
For this code i'd like the count to be returned as 100.
#include <vector>
#include <iostream>;
using namespace std;
int& Permutations(vector<vector<int>> param, vector<vector<int>> &perm, int index=0)
{
static vector<int> iter;
static int count = 0;
if (index == param.size())
{
perm.push_back(iter); // add permutation to queue
count++;
return count;
}
for (int i=param[index][0]; i<=param[index][1]; i+=param[index][2])
{
if (iter.size() > index) iter[index] = i;
else iter.push_back(i);
Permutations(param, perm, index+1); // recursive function
}
}
void main()
{
vector<vector<int>> params; // vector of parameter vectors
vector<int> param1, param2;
int arr1[3] = {0,9,1}; // range for each parameter vector
int arr2[3] = {0,9,1}; // specified as lbound, ubound, step
param1.insert(param1.end(),arr1,arr1+3);
param2.insert(param2.end(),arr2,arr2+3);
params.push_back(param1);
params.push_back(param2);
vector<vector<int>> queue; // queue of generated permutations
int permcount = Permutations(params,queue);
cout << "the permutation count is " << permcount << endl;
cin.get();
}
Using a static count will not work, because it's not going to ever be reset (and will cause problems if you ever go multi-threaded).
Instead, how about this:
int Permutation(/* params */)
{
int count = 1; // Count ourself
for (whatever)
{
count += Permutation(whatever); // Count cumulative sum from recursion
}
return count;
}
Each call to Permutation() returns the total number of calls that were made below it in the call tree. As we unwind, all the counts from the sub-trees get summed together, to eventually produce the final return value.
int foo(int count,/*Other Params*/) {
/*Calucation*/
if (!terminatingCondition) {
foo(count++,/*Other Params*/);
}
logger.log("foo was called " + count + "times");
return /*calcualtion*/;
}
I'm just trying to answer the question by ignoring your actual algorithm purpose. The two statics should be moved to argument references, or you don't have a good way to reset their values.
void Permutations(vector<vector<int>> param, vector<vector<int>> &perm, vector<int> &iter, int &count, int index=0)
{
++count;
// ...
}