"No matching function for call to" Templates C++ - c++

Help I don't understand why i can not run this snippet of code it is for a homework assignment and xCode seems to disagree with me when it says I havent defined the function. see bellow in main for the error
template <class Comparable>
Comparable maxSubsequenceSum1( const vector<Comparable> & a, int & seqStart, int & seqEnd){
int n = a.size( );
Comparable maxSum = 0;
for( int i = 0; i < n; i++ )
for( int j = i; j < n; j++ )
{
Comparable thisSum = 0;
for( int k = i; k <= j; k++ )
thisSum += a[ k ];
if( thisSum > maxSum )
{
maxSum = thisSum;
seqStart = i;
seqEnd = j;
}
}
return maxSum;
}
int main(){
vector<int> vectorofints;
vectorofints.resize(128);
for (int i=0; i<vectorofints.size(); i++){
vectorofints[i] = (rand() % 2001) - 1000;
}
maxSubsequenceSum1(vectorofints, 0, 127) //**---->the error i get in xcode is "No matching function for call to maxSubsequenceSum1"
return 0;
}

Change the signature from
Comparable maxSubsequenceSum1( const vector<Comparable> & a,
int & seqStart, int & seqEnd)
to
Comparable maxSubsequenceSum1( const vector<Comparable> & a,
int seqStart, int seqEnd)
The same problem happens if you would do int & i = 0;. You cannot initialize a non-const reference from an rvalue. 0 and 127 are temporary objects that expire at the end of the expression, temporaries cannot bind to non-const references.

You have declared a function that expects two integer references but the one you are calling takes two integers by value.
It should be like this
vector<int> vectorofints;
vectorofints.resize(128);
for (int i=0; i<vectorofints.size(); i++){
vectorofints[i] = (rand() % 2001) - 1000;
}
int k = 0;
int j = 127;
maxSubsequenceSum1(vectorofints, k, j)
return 0;

The compiler is correct. You are calling maxSubsequenceSum1(std::vector<int>&, int, int), you defined maxSubsequenceSum1(std::vector<int>&, int &, int &)
There are 2 quick solutions:
1) Redefine your function to not take a reference.
2) Move your constants to variables and pass them along that way.
Note: there is another problem with your code. You invoke the function maxSubsequenceSum1, but you do not tell it what template parameter to use.
I have been corrected, and the correction is correct. The note is not valid.

Related

c++ swapping content of array - Selection Sort

I'm new to C++. I was attempting to write a function for selection sort the following way.
void selection_sort(int* m[], int array_size) {
for (int i = 0; i < array_size; i++)
int min_ind = i;
for (int j = i+1; j < array_size; j++){
if (m[min_ind] > m[j]){
min_ind = j;
}
}
int temp = *m[i];
*m[i] = *m[min_ind];
*m[min_ind] = temp;
}
}
Within main, the array is defined as:
int *sel_nums = new int[n];
And I'm calling selection sort in main:
selection_sort( &sel_nums, x );
I keep getting an error that says:
Segmentation fault (core dumped)
Does anyone have any input on why this keeps happening?
You allocated dynamically an array of objects of the type int.
int *sel_nums = new int[n];
This array you are going to pass to the function selection_sort. So the function declaration will look at ;east like
void selection_sort( int m[], int array_size );
The compiler implicitly adjust the parameter having the array type to pointer to the array element type. That is the above declaration is equivalent to
void selection_sort( int *m, int array_size );
So the function can be called like
selection_sort( sel_nums, n );
To swap two elements of the array within the function you can write
if ( min_ind != i )
{
int temp = m[i];
m[i] = m[min_ind];
m[min_ind] = temp;
}
Or you could use the standard C++ function std::swap like
#include <utility>
//...
if ( min_ind != i )
{
std::swap( m[i], m[min_ind] );
}

Invoking function with paremeters, one of which is an array of structures in C++?

I have a program where I have a function that sorts elements of an array of structures by their key field. However, when I invoke the function Insertion(a[],7) - I pass the array and its size, the compiler gives an error expected primary expression before ']' token. I would like to ask what am I doing wrong?
#include <iostream>
using namespace std;
struct CElem
{
int key;
};
CElem a[7];
void Insertion(CElem m[],int n)
{
CElem x;
int i;
int j;
for (i = 0; i < n; i++)
{
x = m[i];
j = i-1;
while (j >= 0 && x.key < m[j].key)
m[j+1] = m[j--];
m[j+1] = x;
}
}
int main()
{
a[0].key=32;
a[1].key=45;
a[2].key=128;
a[3].key=4;
a[4].key=-9;
a[5].key=77;
a[6].key=-7;
Insertion(a[],7);
return 0;
}
you only need to pass the pointer to the start of the array:
Insertion(a, 7);
Your parameter m of the method Insertion is of type CElem*. The variable a is of type CElem* too so you are supposed to give the method just a, like Insertion(a,7);.

How to get rid of this global variable when using the recursion?

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).

Copying odd-value elements from array in C++

I have the following code:
int copyOddOnly(int *dest, int *src, int n) {
int copyList = 0;
for(int i = 0; i < n; i++) {
if(src[i]%2!=0) {
dest[i]=src[i];
copyList = copyList + 1;
}
}
return copyList;
}
It's meant to take all the elements with odd values from array src and copy them to array dest. n is the number of elements to be copied from src to dest. It passes most of the tests except for these two:
int a[10] = {0};
ASSERT_EQUALS(3,copyOddOnly(a,descending,5));
ASSERT_EQUALS( "{5,4,3,2,1}",arrayToString(descending,5));
ASSERT_EQUALS( "{5,3,1}",arrayToString(a,3));
ASSERT_EQUALS(5,copyOddOnly(a,mix2,10));
ASSERT_EQUALS( "{-42,12,-9,56,123,32767,48,12,-43,-43}",arrayToString(mix2,10));
ASSERT_EQUALS( "{-9,123,32767,-43,-43}",arrayToString(a,5));
Instead of copying {5,3,1} from arrayToString(a,3) it's copying {5,0,3}. Instead of copying {-9,123,32767,-43,-43} from arrayToString(a,5) it's copying {5,0,-9,0,123}.
My first instinct when writing it was to just have it return n, but for some reason this had it failing even more tests. I have a feeling I'm not getting at something fundamental and I can't figure out what. Any help would be appreciated.
Instead of
dest[i]=src[i];
you probably meant to have
dest[copyList]=src[i];
While it's copying across only the odd elements, it's leaving alone those elements of dest corresponding to even elements of src. Whatever value was originally in e.g. a[1] will still be there after the copy if descending[1] is 4.
You'll need to keep track of how far along dest you are in the loop. This will be equivalent to copyList in the the function:
int copyOddOnly(int *dest, int *src, int n) {
int j = 0;
for (int i = 0; i < n; i++) {
if (src[i]%2 != 0) {
dest[j] = src[i];
j = j + 1;
}
}
return j;
}
First of all take into account that there is standard algorithm std::copy_if declared in header <algorithm> in C++. Your function could look the following way.
#include <algorithm>
//...
int copyOddOnly( int *dest, const int *src, int n )
{
auto last = std::copy_if( src, src + n, dest,
[]( int x ) { return x % 2; } );
return last - dest;
}
If you may not use standard algorithms then the function can look like
int copyOddOnly( int *dest, const int *src, int n )
{
int k = 0;
if ( !( n < 0 ) )
{
for ( int i = 0; i < n; i++ )
{
if ( src[i] % 2 != 0 ) dest[k++] = src[i];
}
}
return k;
}

Modifying a dynamic 2D array in a function

I've got a function that accepts a dynamic multidimensional array (which is initialized to 0) as a parameter, and I'm trying to modify certain values within the array in my function.
The function that accepts the array as a parameter is supposed to simulate the roll of two dice and output the frequency distribution to the array I made that's initialized to zero.
The code for it is as follows:
#include <iostream>
#include <cstdlib>
using namespace std;
int** rollDie(int numRolls, unsigned short seed, int** &rollarray)
{
srand(seed);
int side1, side2;
while (numRolls > 0)
{
side1 = 1 + rand() % 6;
side2 = 1 + rand() % 6;
rollarray[side1][side2]++;
numRolls--;
}
return rollarray;
}
int** initializeArray(void)
{
int i, j;
int** m = new int*[6];
for (i = 0; i < 6; i++)
m[i] = new int[6];
for (i = 0; i < 6; i++)
for (j = 0; j < 6; j++)
m[i][j] = 0;
return m;
}
int main()
{
int numRolls;
unsigned short seed;
int ** a = initializeArray();
cout << "rolls?\n";
cin >> numRolls;
cout << "seed?\n";
cin >> seed;
int ** b = rollDie(numRolls, seed, a);
int i,j;
for (i = 0; i < 6; i++) {
for (j = 0; j < 6; j++) {
cout << b[i][j];
}
cout << "\n";
}
}
Code works for me with just a few issues (I had to guess how you defined a. Next time add that too):
In the printing you should print a space after every number (minor)
In the random, you choose index as 1+rand()%6, so from 1 to 6, but when you print you take indexes from 0 to 5! So your first row and first column will be 0.
Other than that it seems to work.
Only when one goes and does something else does the answer come to mind. I suspect you declared a as:
int a[6][6];
which is an array of 36 integers. In your function, though, you're declaring rollarray to be a pointer to an array of pointers to integers. All you need to do is change the function signature to:
int* rollDie(int numRolls, unsigned short seed, int* rollarray)
As cluracan said, you also want to use array indices in the range 0 to 5.
This is a good case for either the judicious use of print statements or stepping through with a debugger to see what's really going on.