I've been used to using Python or Matlab where I could create a list like:
min = 5;
step = 2;
max = 16;
Range = min:step:max;
and Range would be the list [5,7,9,11,13,15].
Is there an equivalently simple way to generate a list like "Range" in C++? So far the simplest thing I can think of is using a for loop but that is comparatively quite tedious.
C++ doesn't supply such a thing, either in the language or the standard library. I'd write a function template to look (roughly) like something from the standard library, something on this order:
namespace stdx {
template <class FwdIt, class T>
void iota_n(FwdIt b, size_t count, T val = T(), T step = T(1)) {
for (; count; --count, ++b, val += step)
*b = val;
}
}
From there it would look something like this:
std::vector<int> numbers;
stdx::iota_n(std::back_inserter(numbers), 6, 5, 2);
You'll have to implement that yourself, something like this:
std::vector<int> createArray( int min, int max, int step )
{
std::vector<int> array;
for( int i = min; i < max; i += step )
{
array.push_back( i );
}
return array;
}
There is no such predefine method in C++ for this purpose.
Below code may help you.
std::vector<int> createArrayRange( int min, int max, int step )
{
std::vector<int> array;
for( int i = min; i < max; i += step )
{
array.push_back(i);
}
return array
}
Or This would be comparatively faster.
void createArrayRange( std::vector<int>& array, int min, int max, int step )
{
for( int i = min; i < max; i += step )
{
array.push_back(i);
}
}
int main()
{
std::vector<int> array;
createArrayRange(array, min, max, step);
return 0;
}
You can use std::generate for this.
std::vector< int > createArray( int min, int max, int step )
{
std::vector< int > array((max-min)/step);
int n = min;
std::generate(array.begin(), array.end(),
[&]()
{
int res = n;
n+=step;
return res;
});
return array;
}
No explicit loops needed:
vector<int> data(6,2);
data[0] = 5;
std::partial_sum(data.begin(),data.end(),data.begin());
Related
I'm currently trying to program a function that would find the average of elements in an array of integers in C++.
I've looked at new c++11 for loop causes: "error: ‘begin’ was not declared in this scope" but I don't quite understand the problem and how to fix it.
double avg(int arr[]) {
double sum = 0;
int size = 0;
for (int i : arr) {
sum += i;
size += 1;
}
return sum / size;
}
It gives me errors that "'begin' was not declared in this scope" and "'end' was not declared in this scope".
Could somebody explain why the error is occurring and possible ways to fix it?
The type int arr[] decays into a raw pointer, and as a result there's no way to get the size of the array it refers to.
Instead of using raw arrays, it'd be better just to use either std::vector:
double avg(std::vector<int> const& v) {
double sum = 0;
for(int i : v)
sum += i;
return sum / v.size();
}
Or std::array, which acts like a C-array but is copyable and doesn't decay into a pointer:
template<size_t N>
double avg(std::array<int, N> const& arr) {
double sum = 0;
for(int i : arr) {
sum += i;
return sum / N;
}
Or, if you really have to use arrays, pass the size as a parameter:
double avg(int arr[], size_t size) {
double sum = 0;
for(int i = 0; i < size; i++) {
sum += arr[i];
}
return sum / size;
}
Leveraging the C++ standard library
The C++ standard library has a lot of useful functions, and one of them, accumulate, does the job perfectly. It takes a begin and end iterator, as well as the initial value, and computes the sum over the range:
#include <numeric>
double avg(std::vector<int> const& v) {
return std::accumulate(v.begin(), v.end(), 0.0) / v.size();
}
double avg(int[] arr, size_t size) {
return std::accumulate(arr + 0, arr + size, 0.0) / size;
}
Functions may not take arrays as parameters. You get a pointer there. Though you can pass a reference to an array to a function as a parameter. Here is an example:
#include <iostream>
template <typename T, auto n>
void print(const T(&arr)[n]) {
for (auto&& t : arr) {
std::cout << t << ' ';
}
std::cout << '\n';
}
int main() {
int arr[]{ 1, 2, 3, 4, 5 };
print(arr);
}
Output:
1 2 3 4 5
If you want to actually pass an array, not switch to using a vector you can do it with a template function parametrized on the size of the array i.e.
template <int N>
double avg(int (&arr)[N] ) {
double sum = 0;
int size = 0;
for (int i : arr) {
sum += i;
size += 1;
}
return sum / size;
}
int main()
{
int ary[] = { 1,2,3,4,5,6 };
std::cout << avg(ary);
}
First of all, I don't want to use sort. This is just an illustration example. The main purpose of this question is that I want to:
find all possible combinations of m numbers out of n numbers and
process them, then return the unique processed result (since the
processed results of all possible combinations will be compared).
Question start at here
The following code get all possible combinations M numbers out of N numbers. Sum the M numbers and find the largest sum. In doing this I used a recursion function.
However, it seems that I must define a global variable to store the temporary largest sum. Is there any way to get rid of this global variable? For example, define the recursion function to return the largest sum... I don't want the global variable just become an argument &max_sum in the find_sum, since find_sum already have too many arguments.
#include <iostream>
#include <vector>
void find_sum(const std::vector<int>& ar, std::vector<int>& combine,
int index, int start);
int max_sum =0;
int main() {
int N = 10;
int M = 3;
std::vector<int> ar(N);
ar = {0,9,2,3,7,6,1,4,5,8};
int index = 0, start =0;
std::vector<int> combine(M);
find_sum(ar, combine, index, start);
std::cout << max_sum <<std::endl;
return 0;
}
void find_sum(const std::vector<int>& ar, std::vector<int>& combine,
int index, int start) {
if(index == combine.size()) {
int sum =0;
for(int i=0; i<index; ++i) {
sum += combine[i];
}
if(max_sum < sum) {
max_sum = sum;
}
return ;
}
for(int i = start;
i < ar.size() && ar.size()-i > combine.size()-index;
++i) {
combine[index] = ar[i];
find_sum(ar, combine, index+1, start+1);
}
}
An approach that scales well is to turn find_sum into a function object. The trick is to define a struct with an overloaded () operator that takes a certain set of parameters:
struct FindSum
{
void operator()(const std::vector<int>& ar, std::vector<int>& combine,
int index, int start){
/*ToDo - write the function here, a very explicit way of
/*engineering the recursion is to use this->operator()(...)*/
}
int max_sum; // I am now a member variable
};
Then instantiate FindSum find_sum;, set find_sum.max_sum if needed (perhaps even do that in a constructor), then call the overloaded () operator using find_sum(...).
This technique allows you to pass state into what essentially is a function.
From find_sum, return the so-far maximum sum (instead of void). That means that the recursion-terminating code would be:
if(index == combine.size()) {
int sum =0;
for(int i=0; i<index; ++i) {
sum += combine[i];
}
return sum;
}
and the recursive part would be
int max_sum = 0;
for(int i = start;
i < ar.size() && ar.size()-i > combine.size()-index;
++i) {
combine[index] = ar[i];
int thismaxsum = find_sum(ar, combine, index+1, start+1);
if(thismaxssum > max_sum)
max_sum = thismaxsum;
}
return max_sum;
So, the overall solution is:
#include <iostream>
#include <vector>
int find_sum(const std::vector<int>& ar, std::vector<int>& combine,
int index, int start);
int main() {
int N = 10;
int M = 3;
std::vector<int> ar(N);
ar = { 0,9,2,3,7,6,1,4,5,8 };
int index = 0, start = 0;
std::vector<int> combine(M);
int max_sum = find_sum(ar, combine, index, start);
std::cout << max_sum << std::endl;
return 0;
}
int find_sum(const std::vector<int>& ar, std::vector<int>& combine,
int index, int start)
{
if (index == combine.size())
{
int sum = 0;
for (int i = 0; i<index; ++i)
{
sum += combine[i];
}
return sum;
}
int max_sum = 0;
for (int i = start;
i < ar.size() && ar.size() - i > combine.size() - index;
++i)
{
combine[index] = ar[i];
int thismaxsum = find_sum(ar, combine, index + 1, start + 1);
if (thismaxsum > max_sum)
max_sum = thismaxsum;
}
return max_sum;
}
Global variables are much better then adding operands and variables to recursion functions because each operand and variable causes heap/stack trashing negatively impact performance and space usage risking stack overflow for higher recursions.
To avoid global variables (for code cosmetics and multi threading/instancing purposes) I usually use context or temp struct. For example like this:
// context type
struct f1_context
{
// here goes any former global variables and stuff you need
int n;
};
// recursive sub function
int f1_recursive(f1_context &ctx)
{
if (ctx.n==0) return 0;
if (ctx.n==1) return 1;
ctx.n--;
return (ctx.n+1)*f1_recursive(ctx.n);
}
// main API function call
int f1(int n)
{
// init context
f1_context ctx;
ctx.n=n;
// start recursion
return f1_recursion(ctx);
}
the f1(n) is factorial example. This way the operands are limited to single pointer to structure. Of coarse you can add any recursion tail operands after the context... the context is just for global and persistent stuff (even if I did use it for the recursion tail instead but that is not always possible).
It seems to be a simply exercise, but something doesn't work with the following qsort algorithmus. The struct abcSort correctly shows all assigned values. Unfortunately, the qsort is not sorting anything.
typedef int(*compfn)(const void*, const void*);
struct ABCSort
{
int svSort[10];
string itemSort[10];
};
struct ABCSort abcSort;
int compare(struct ABCSort*, struct ABCSort*);
void mainSort()
{
for (int i = 0; i < 10; i++)
{
abcSort.svSort[i] = 100 - i;
abcSort.itemSort[i] = arrayREAD[i][2];
}
qsort( (void*)&abcSort, 10, sizeof(struct ABCSort), (compfn)compare );
}
int compare(struct ABCSort *elem1, struct ABCSort *elem2)
{
if (elem1->svSort< elem2->svSort)
return -1;
else if (elem1->svSort > elem2->svSort)
return 1;
else
return 0;
}
You have build two arrays of integer and strings and you want to sort them by the numbers, keeping the initial pairing. That's the first problem, you should have created one array of structs, each struct containg a number and a string and a function that compares the integer member of that struct to obtain the sort order.
You also tagged this question as C++ but you are using qsort, arrays and function pointers like C, so I'll present two complete C programs that solve your problem.
Let's see, using an array of structs, what your code could be like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 6
#define CMAX 15
typedef int(*cmp_fn)(const void*, const void*);
typedef struct {
int num;
char str[CMAX];
} numABC;
int comp_struct(const numABC *lhs, const numABC *rhs ) {
if ( lhs->num < rhs->num )
return -1;
if ( lhs->num > rhs->num )
return 1;
return 0;
}
int main(void) {
numABC myArray[MAX] = { {6, "cat"}, {4, "dog"}, {8, "panter"},
{2, "red fish"}, {1, "hawk"}, {6, "snake"} };
int i;
// sort the array of structs by int member
qsort(myArray, MAX, sizeof(numABC), (cmp_fn)comp_struct);
// print out the sorted array
printf("\nSort by numbers:\n");
for ( i = 0; i < MAX; ++i ) {
printf("%d %s\n",myArray[i].num,myArray[i].str);
}
return 0;
}
If you want to use this code, but you have a couple of arrays instead, one option is to convert those arrays:
int nums[MAX] = {6,4,8,2,1,3};
char str[MAX][CMAX] = {"cat","dog","panter","red fish","hawk","snake"};
int i;
// create the array of structs from the two arrays
numABC myArray[MAX];
for ( i = 0; i < MAX; ++i ) {
myArray[i].num = nums[i];
strcpy(myArray[i].str, str[i]);
}
Another option to sort two different arrays (mantaining the pairing or alignment between the two) is to use a more complicated method which consists in sorting an array of indeces instead. to keep the relationships between the two original arrays I'll have to use global variables which can be accessed inside the compare function(s). Once the indeces are sorted, the original arrays are changed accordingly.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 6
#define CMAX 15
const size_t I_DIM = MAX * sizeof(int);
const size_t SS_DIM = MAX * sizeof(char*);
const size_t S_DIM = MAX * CMAX;
// global variables needed to perform comparisons
int *pg_int;
char **pg_str;
typedef int(*cmp_fn)(const void*, const void*);
int comp_num(const int *lhs, const int *rhs ) {
if (pg_int[*lhs] < pg_int[*rhs])
return -1;
if (pg_int[*lhs] > pg_int[*rhs])
return 1;
return 0;
}
int comp_str(const int *lhs, const int *rhs ) {
return strcmp(pg_str[*lhs],pg_str[*rhs]);
}
int main(void) {
int nums[MAX] = {6,4,8,2,1,3};
char str[MAX][CMAX] = {"cat","dog","panter","red fish","hawk","snake"};
int i;
// create an array of indeces
int index[MAX];
for ( i = 0; i < MAX; ++i ) {
index[i] = i;
}
// set global copies
pg_int = malloc(I_DIM);
memcpy(pg_int,nums,I_DIM);
pg_str = malloc(SS_DIM);
pg_str[0] = malloc(S_DIM);
memcpy(pg_str[0],str[0],S_DIM);
for ( i = 1; i < MAX; i++ ) {
pg_str[i] = pg_str[0] + i * CMAX;
}
// sort the indeces ordering by ints
qsort(index, MAX, sizeof(int), (cmp_fn)comp_num);
//update the two arrays
for ( i = 0; i < MAX; ++i ) {
nums[i] = pg_int[index[i]];
strcpy(str[i],pg_str[index[i]]);
}
// print out sorted couples
printf("Sort by numbers:\n");
for ( i = 0; i < MAX; ++i ) {
printf("%d %s\n",nums[i],str[i]);
}
// sort the indeces ordering by strings
qsort(index, MAX, sizeof(int), (cmp_fn)comp_str);
//update the two arrays
for ( i = 0; i < MAX; ++i ) {
nums[i] = pg_int[index[i]];
strcpy(str[i],pg_str[index[i]]);
}
// print out sorted couples
printf("\nSort by strings:\n");
for ( i = 0; i < MAX; ++i ) {
printf("%d %s\n",nums[i],str[i]);
}
free(pg_int);
free(pg_str[0]);
free(pg_str);
return 0;
}
The output (sorry for the silly example) is:
Sort by numbers:
1 hawk
2 red fish
3 snake
4 dog
6 cat
8 panter
Sort by strings:
6 cat
4 dog
1 hawk
8 panter
2 red fish
3 snake
If you want to accomplish the same task in C++ you should take advantage of the Standard Library and use std::vector as a container and std::sort as algorithm:
#include <iostream>
#include <vector>
#include <algorithm>
using std::vector;
using std::string;
using std::cout;
struct numABC {
double num;
string str;
// instead of a compare function I can overload operator <
friend bool operator<( const numABC &lhs, const numABC &rhs ) {
return lhs.num < rhs.num;
}
};
// or use a lambda
auto cmp_str = []( const numABC &lhs, const numABC &rhs ) -> bool {
return lhs.str < rhs.str;
};
int main() {
vector<numABC> my_data = { {3.6, "cat"}, {5.7, "dog"}, {7.1, "panter"},
{0.2, "red fish"}, {1.8, "hawk"}, {1.1, "snake"}};
std::sort(my_data.begin(), my_data.end());
std::cout << "Sort by numbers:\n";
for ( auto & s : my_data ) {
std::cout << s.num << ' ' << s.str << '\n';
}
std::sort(my_data.begin(), my_data.end(), cmp_str);
// passing a lambda to specify how to compare ^^
std::cout << "Sort by strings:\n";
// if you don't like c++11 range for:
for ( int i = 0; i < my_data.size(); ++i ) {
std::cout << my_data[i].num << ' ' << my_data[i].str << '\n';
}
return 0;
}
Note that I have initialized my_data as a vector of objects of type numABC. If you have to start from two arrays, you can create the vector like this:
vector<double> nums = {3.6, 5.7, 7.1, 0.2, 1.8, 1.1};
vector<string> str = {"cat", "dog", "panter", "red fish", "hawk", "snake"};
vector<numABC> my_data;
for ( int i = 0; i < nums.size(); ++i ) {
my_data.push_back(numABC{nums[i],str[i]});
}
After sorting, if you have to extract the two vectors again (instead of simply looping through my_data) you can do something like this:
for ( int i = 0; i < my_data.size(); ++i ) {
nums[i] = my_data[i].num;
str[i] = my_data[i].str;
}
Alternatively you could implement an algorithm similar to the one I used before and sort the two vectors nums and srt using an auxiliary vector of indeces:
vector<double> nums = {3.6, 5.7, 7.1, 0.2, 1.8, 1.1};
vector<string> str = {"cat", "dog", "panter", "red fish", "hawk", "snake"};
// create the vector of indeces
vector<int> idx(nums.size());
std::iota(idx.begin(),idx.end(),0); // fill the vector, require #include <numeric>
// thanks to the lambda variable capture you don't need globals
auto cmp_ind = [ &nums ]
( const int &lhs, const int &rhs ) -> bool {
return nums[lhs] < nums[rhs];
};
// sort indeces
std::sort(idx.begin(), idx.end(),cmp_ind);
// create sorted arrays. It could be done in place but it's more difficult
vector<double> sorted_nums(nums.size());
vector<string> sorted_str(str.size());
for ( int i = 0; i < nums.size(); ++i ) {
sorted_nums[i] = nums[idx[i]];
sorted_str[i] = str[idx[i]];
}
std::cout << "Sort by numbers:\n";
for ( int i = 0; i < nums.size(); ++i ) {
std::cout << sorted_nums[i] << ' ' << sorted_str[i] << '\n';
}
You seem to intend to sort an array of integers (your compare function looks like that). But what you are actually handing over to qsort for sorting is a pointer to a structure that holds, among other stuff, an array.
So what you are actually trying to sort is one single struct ABCSort which is initialized and 9 other, uninitialized structures. This must fail.
Your qsort line should look like so:
qsort ((void*)&(abcsort.svsort), 10, sizeof (int), (compfn)compare);
Also, you should change the compare function so that it takes and works on two pointers to integers:
int compare (int * e1, int * e2) {
return *e1 - *e2;
}
EDIT:
After you have explained a bit better what you want, have a look at the following:
typedef int(compfn)(const void, const void*);
#define MAXCARS 5
struct car {
int sortKey;
double displacement;
char name[15]; /* Note I have decided this should be C */
};
/* This time we have an array of structs */
struct car cars [MAXCARS] = {
{ 0, 1.9, "BMW" },
{ 0, 6.3, "Audi" },
{ 0, 0.5, "Fiat" },
{ 0, 25.0, "Humvee" },
{ 0, 0.05, "Minibike" }
};
int compare(struct car*, struct car*);
void main(int argc, char *argv []) {
int i;
for (i = 0; i < MAXCARS; i++)
cars[i].sortKey = 100 - i;
qsort((void *)&cars, MAXCARS, sizeof(struct car), (compfn)compare);
}
/* Note we are comparing struct car-s in here, based on their displacement */
int compare(struct car *elem1, struct car *elem2) {
return elem1->sortKey - elem2->sortKey;
}
Today, I try to solve one weird (kind of) question with my friend, .
Try to get the sum of 1 + 2 + ··· + n, without using multiplication and division, for, while, if, else, switch, case, ternary expression and other keywords.
Here are our solutions
constructor
class Sum
{
public:
Sum() { ++num; sum += num; }
static void Init() { num = 0; sum = 0; }
static unsigned int SumValue() { return sum; }
private:
static unsigned int num;
static unsigned int sum;
};
unsigned int Sum::num = 0;
unsigned int Sum::sum = 0;
unsigned int get_sum(unsigned int n)
{
Sum::Init();
Sum * tmp = new Sum[n];
delete[] tmp;
return Sum::SumValue();
}
recursive
class Ba
{
public:
virtual unsigned int sum(unsigned int n)
{
return 0;
}
};
Ba* sumArray[2];
class D : public Ba
{
public:
virtual unsigned int sum(unsigned int n)
{
return sumArray[!!n]->sum(n - 1) + n;
}
};
unsigned int get_sum2(unsigned int n)
{
Ba b;
D d;
sumArray[0] = &b;
sumArray[1] = &d;
return sumArray[1]->sum(n);
}
We think maybe this question could be solved var template? However, we failed to figure it out. Is it possible to do that with template?
BTW, we try to find the same question in this site, but we failed. Sorry to this duplicated question if it is.
with a minimum of keywords, using short circuit evaluation
unsigned sum(unsigned n) {
unsigned i=0;
n && (i=n+sum(n-1));
return i;
}
I suspect this question will be closed soon, but it sounds like what you're after is the following: a pretty standard introduction to the idea of compile-time recursion, used heavily in template metaprogramming.
template <int I>
struct sum {
static constexpr int value = I + sum<I-1>::value;
};
template <>
struct sum<0> {
static constexpr int value = 0;
};
int main() {
std::cout << sum<5>::value << std::endl;
}
We have that the sum of the first N numbers is S = N(N+1)/2 = (N^2 + N)/2. Therefore,
int main()
{
int N = 10;
int sum = (N*N + N) >> 1;
}
What about using algorithms?
std::iota
template< class ForwardIterator, class T >
void iota( ForwardIterator first, ForwardIterator last, T value );
Fills the range [first, last) with sequentially increasing values,
starting with value and repetitively evaluating ++value.
http://en.cppreference.com/w/cpp/algorithm/iota
std::accumulate
template< class InputIt, class T >
T accumulate( InputIt first, InputIt last, T init );
Computes the sum of the given value init and the elements in the range
[first, last).
http://en.cppreference.com/w/cpp/algorithm/accumulate
Example:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int sum(const int n) {
std::vector<int> v(n);
std::iota(begin(v), end(v), 1);
return std::accumulate(begin(v), end(v), 0);
}
int main() {
const int n = 12;
std::cout << "Sum: " << sum(n) << std::endl;
return 0;
}
https://ideone.com/ajOhWM
Recursion is probably the expected solution, but by no means as complex as you have made it.
unsigned num( unsigned n ){ return n ; }
unsigned sum1toN( unsigned n ) ;
unsigned (*function[])() = { sum1toN, num } ;
unsigned sum1toN( unsigned n )
{
return n + (function[n==1])( n - 1 ) ;
}
This is actual code.Here I am calling for_each to carry out the function shown in sum.Can this be reduced to writing the function inside the for_each statement itself?
int S;
struct sum
{
sum(int& v): value(v){}
void operator()(int data)const {value+=(int)((data+(data%S==0?0:S))/S)+2;}
int& value;
};
int main()
{
int cnt=0;
S=5;
for_each(flights.begin(),flights.end(),sum(cnt));
cout<<cnt-2;
return 0;
}
In C++11, you can, using lambdas with a capture:
int main()
{
int cnt = 0;
S = 5;
for_each(
flights.begin(), flights.end(),
[&] (int data) {
cnt += (data + (data % S == 0 ? 0 : S)) / S + 2;
});
cout << cnt - 2;
return 0;
}
The way this reads is: you have an anonymous function taking an int argument, which captures ([&]) the surrounding context by reference. Note that this is as efficient as your solution since the compiler effectively creates the structure from the lambda for you.
– As Navaz noted int he comments, the cast is actually unnecessary. Furthermore, C-style casts are generally seen as deprecated – use C++ casts instead.
You could use std::accumulate from <numeric> which perfectly expresses your intent to build a sum.
int main()
{
int flights[] = {1, 2, 3};
int S = 5;
std::cout << std::accumulate(
begin(flights), end(flights), 0,
[S] (int sum, int data) { return sum + (int)((data+(data%S==0?0:S))/S)+2; })
- 2;
}
Although you asked for a one liner, I prefer to give this non trivial lambda a name to increase readability.
int main()
{
int flights[] = {1, 2, 3};
auto theFooBarSum = [] (int sum, int data)
{ return sum + (int)((data+(data%5==0?0:5))/5)+2; };
int initialValue = 0;
std::cout << std::accumulate(
begin(flights), end(flights), initialValue , theFooBarSum) - 2;
}