Write a program to solve Coin-row problem using dynamic programming (in c++)
Given the coin row: 5,1,2,10,6,2
I wrote the code, but I get an error about the size. Why?
this is code
#include<iostream>
using namespace std;
int max(int a,int b){
if(a>b)
return a;
else
return b;
}
int main(){
int coinrow[]={5,1,2,10,6,2};
int size=sizeof(coinrow)/sizeof(coinrow[0]);
//cout<<size;
int i;
int coins[size+1];
for(i=0;i<size;i++){
coins[i+1]=coinrow[i];
}
int F[size+1];
F[0]=0;
F[1]=coins[1];
for(i=2;i<=size;i++){
F[i]=max(coins[i]+F[i-2],F[i-1]);
}
cout<<F[size];
}
The size of an array has to be a compile time constant and known at compile time. int coins[size+1]; is a variable-length array (because size is not a compile time constant) and not valid C++. Some compilers support it with compiler extensions but its usage is limited. The memory is allocated on the stack and the stack size is limited. Larger arrays should be allocated on the heap. Use std::vector (heap) or const/constexpr (stack) instead of VLAs. const doesn't guarantee a compile time constant.
#include<iostream>
using namespace std;
int max(int a,int b){
if(a>b)
return a;
else
return b;
}
int main(){
int coinrow[]={5,1,2,10,6,2};
constexpr int size=sizeof(coinrow)/sizeof(coinrow[0]);
//cout<<size;
int i;
int coins[size+1];
for(i=0;i<size;i++){
coins[i+1]=coinrow[i];
}
int F[size+1];
F[0]=0;
F[1]=coins[1];
for(i=2;i<=size;i++){
F[i]=max(coins[i]+F[i-2],F[i-1]);
}
cout<<F[size];
}
I prefer
#include <algorithm>
#include <array>
#include <iostream>
int main(){
std::array coinrow = {5,1,2,10,6,2};
constexpr auto size = coinrow.size();
//cout<<size;
std::array<int, size+1> coins;
for(std::size_t i=0;i<size;i++){
coins[i+1]=coinrow[i];
}
std::array<int, size+1> F;
F[0]=0;
F[1]=coins[1];
for(std::size_t i=2;i<=size;i++){
F[i]=std::max(coins[i]+F[i-2],F[i-1]);
}
std::cout<<F[size];
}
if the size is known at compile time and the stack can be used and
#include <algorithm>
#include <iostream>
#include <vector>
int main(){
std::vector coinrow = {5,1,2,10,6,2};
auto size = coinrow.size();
//cout<<size;
std::vector<int> coins(size+1);
for(std::size_t i=0;i<size;i++){
coins[i+1]=coinrow[i];
}
std::vector<int> F(size+1);
F[0]=0;
F[1]=coins[1];
for(std::size_t i=2;i<=size;i++){
F[i]=std::max(coins[i]+F[i-2],F[i-1]);
}
std::cout<<F[size];
}
if the size not known at compile time or the heap has to be used.
Related
I am working on my own library and I want to create function max(). I know that function like this exists in C++ and it isn't in namespace std, so erasing using namespace std; won't help. I am creating this function in my namespace like this:
namespace ml
{
template<typename T>T max(T cntr, int size)//I'm getting errors here
{
sort(cntr,0,size-1);//my function which just sorts elements, it's working fine
return cntr[size-1];
}
}
Here is my main function:
#include <iostream>
#include <ctime>
#include "mylib.hpp"
int main()
{
srand(time(NULL));
int* arr, n;
std::cin>>n;
arr = new int [n];
for(int i = 0; i < n; i++)
{
arr[i] = rand()%100;
}
int maximum = ml::max(arr,n);//I'm getting errors here
std::cout<<maximum<<'\n';
return 0;
}
Sorry for grammatical mistakes if i've done so.
If the purpose of the function is to search a C-style array, the signature should be template <typename T> T max(T* cntr, int size). (note the T* as the type of cntr) That way, when it's called with an int*, T is deduced as int, and that's the correct return type.
I am using the Eigen linear algebra library. I struggling trying to allocate Eigen Vectors in the constructor in a class, and then calling the elements of those vectors.
For example,
#include <Eigen/Dense>
using Eigen::VectorXd;
#include <memory>
using std::unique_ptr;
class Cl
{
public:
unique_ptr<VectorXd> v;
Cl(const int n);
~Cl(void);
}
Cl::Cl(const int n)
{
auto v= unique_ptr<VectorXd>(new VectorXd(n));
}
Cl::~Cl(void)
{
v= nullptr;
}
main(void)
{
Cl cl(10);
/* call an element of v how? */
}
For example, using "cl.v(2)" gives me the compiler error (I am using clang++)
error: type 'unique_ptr<VectorXd>' (aka 'unique_ptr<Matrix<double, Dynamic, 1> >') does
not provide a call operator
while using "cl.(*v)(2)" gives me
error: expected unqualified-id
cout << cl.(*v)(2) << endl;
I am new to c++, so I may be missing something very basic here.
Why are you trying to dynamically allocate the Eigen::VectorXd v; itself? Unless you would like to extend the lifetime of v beyond the lifetime of cl (in which case you would indeed have to do so), I would recommend to follow the following simple example:
#include <Eigen/Dense>
using Eigen::VectorXd;
class Cl
{
public:
VectorXd v;
Cl(int n) : v(n) {}
~Cl() {}
}
int main()
{
Cl cl(10);
for (int i=0; i<10; ++i)
cl.v(i) = i;
}
I believe in addition to the answers already regarding std::vector you are also misusing your 'unique_ptr', if indeed you actually require the use of one (reference ggael answer). Please see below example on the use of unique_ptr:
#include <iostream>
#include <memory>
#include <vector>
class Cl {
public:
std::unique_ptr<std::vector<int>> v;
Cl(const int size, int default_values);
~Cl(void);
int Size();
};
Cl::Cl(const int size, int default_values = 0) {
v.reset(new std::vector<int>(size, default_values));
}
Cl::~Cl(void) {
// do not require to reset/destroy an auto_ptr so this can be ommitted
}
int Cl::Size() {
return v->size();
}
int main(int argc, char* argv[]) {
Cl blob(10);
int size = blob.Size();
std::cout << size << std::endl;
}
In your provided code you're declaring a new auto in the constructor rather than using the variable you've defined in your Public class definition. I've included a 'Size' method so you can see the scope extends beyond the constructor.
#include<iostream>
using namespace std;
int accept(int &,int );//int accept(int*,int)
int main()
{
int n=3;
//int arr[3]={0,1,2};
int *marks=new int[n]; //creating an array dynamically
//int (&ref_arr)[3]=arr;// I know how to create a reference to statically created array;
int* &ref_marks=marks;//creating reference for array;
accept(ref_marks,n);
return 0;
}
int accept(int &marks,int n)
{
int i;
for(i=0;i<n;i++)
{
cin>>marks[i];
}
return 0;
}
Could you please help me out with creating reference to an array which is on heap area.
You could write:
using int3 = int[3];
int3& ref = reinterpret_cast<int3&>(*marks);
However it would be better practice to just use std::array or std::vector.
#include <bits/stdc++.h>
using namespace std;
int* insertionSort(int* a);
int main()
{
int a[5];
for(int i=0;i<5;i++)
{
cin>>a[i];
}
int b[5];
*b = insertionSort(a);
for(int i=0;i<5;i++)
{
cout<<b[i]<<" ";
}
}
int* insertionSort(int* a)
{
for(int i=1;i<5;i++)
{
int key=a[i];
int j=i-1;
while(j>0 && a[j]>key)
{
a[j]=a[j+1];
j-=1;
}
a[j+1]=key;
}
return a;
}
So this is my code for insertion sort. But when I run this it gives me the error
insertionSort.cpp: In function ‘int main()’:
insertionSort.cpp:15:21: error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
*b = insertionSort(a);
I would like to know how does passing and returning arrays in functions work in C++. What is the error in my code?
P.S : It may happen that my insertion code may be wrong. I have not really tested it so pardon me I could not check it because of this error. It would be really helpful if someone can explain it in detail.
insertionSort is returning a int pointer, and you're trying to assign it to an int by dereferencing the pointer (*b). The correct syntax would be
b = insertionSort(a);
Also, b should be declared as int* b
P.S., this compiles, but still doesn't work as intended, but that's a whole different question from the one you posed.
#include <array>
#include <algorithm> // sort
#include <iostream>
constexpr size_t size {5};
std::array<int, size>* insertionSort(std::array<int, size>& a)
{
std::sort(a.begin(), a.end());
return &a;
}
int main()
{
std::array<int, size> a {1, 4, 3, 2, 5};
std::array<int, size>* b = insertionSort(a);
for(size_t i = 0; i < size; ++i)
std::cout << (*b)[i] << std::endl;
}
You should use the standard library functions when possible (here the sort one)
Thanks to C++11 we know have array (instead of playing with raw pointers)
How come when I run the following code it outputs 3 not 5? I was under the impression that passing a pointer to a function changes the original variable.
#include <iostream>
using namespace std;
void addTwo(int* b){
b +=2;
}
int main() {
int a = 3;
int* ptr = &a;
addTwo(ptr);
cout<<*ptr<<endl;
return 0;
}
You need to add two, to the contents of what b points at. What you are doing is incrementing the pointer. You need to increment *b:
#include <iostream>
using namespace std;
void addTwo(int* b){
*b +=2;
}
int main() {
int a = 3;
int* ptr = &a;
addTwo(ptr);
cout<<*ptr<<endl;
return 0;
}
#include <iostream>
using namespace std;
void addTwo(int& b){
b +=2;
}
int main() {
int a = 3;
addTwo(a);
cout<<a<<endl;
return 0;
}
First thing, you should use references in C++ instead of pointers. It really is easier in the long run.
#include <iostream>
using namespace std;
void addTwo(int* b){
*b +=2;
}
int main() {
int a = 3;
int* ptr = &a;
addTwo(ptr);
cout<<*ptr<<endl;
return 0;
}
Second thing, you simply forgot the * in addTwo(), incrementing the pointer adress and not the content itself.