Giving the change using a "greedy "method - what(): std::bad_allock - c++

After expanding my program to include change such as 0.01,0.02,0.05,0.1,0.2,0.5 (zł) I was given:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Process returned 3 (0x3) execution time : 56.358 s
Press any key to continue.
It isn't the first time I have gotten this message, but it only happens upon using vectors.
The program would be working fine had I refrained from adding the update, but I'm curious as to why this message pops out, and what the cause of it may be. I suppose it has to do with the bad placement of something in the memory?
Thank you for your help people.
#include <iostream>
#include <vector>
using namespace std;
int main(){
int iloscMonet=9;
double monety[iloscMonet]={0.01,0.02,0.05,0.1,0.2,0.5,1,2,5};
double resztaDoWydania=4.01;
int licznikMonet=0;
vector <int> jakieMonety;
while(resztaDoWydania){
int nominal = 0;
for(int i=0;i<iloscMonet;i++){
if((monety[i]<=resztaDoWydania)&&(monety[i]>nominal)){
nominal=monety[i];
}
}
resztaDoWydania-=nominal;
jakieMonety.push_back(nominal);
licznikMonet++;
}
cout<<"ile monet?: "<<licznikMonet<<endl;
cout<<"jakie monety?: ";
for(int i=0;i<jakieMonety.size();i++){
cout<<jakieMonety.at(i)<<" ";
}
return 0;
}

Calculation of floating-point number may contain errors.
When I add #include <cstdio> in top of your code and printf("%.30f\n", resztaDoWydania); after licznikMonet++;, I found that the value of resztaDoWydania stacking at 0.009999999999999786837179271970.
You should avoid using floating-point numbers as much as you can.
In this case, you can multiply each of the values by 100 to make them integers.
#include <iostream>
#include <vector>
using namespace std;
int main(){
int iloscMonet=9;
int monety[iloscMonet]={1,2,5,10,20,50,100,200,500};
int resztaDoWydania=401;
int licznikMonet=0;
vector <int> jakieMonety;
while(resztaDoWydania){
int nominal = 0;
for(int i=0;i<iloscMonet;i++){
if((monety[i]<=resztaDoWydania)&&(monety[i]>nominal)){
nominal=monety[i];
}
}
resztaDoWydania-=nominal;
jakieMonety.push_back(nominal);
licznikMonet++;
}
cout<<"ile monet?: "<<licznikMonet<<endl;
cout<<"jakie monety?: ";
for(int i=0;i<jakieMonety.size();i++){
cout<<jakieMonety.at(i)<<" ";
// if you want outpuf of floating-point numbers as the original
//cout<<(jakieMonety.at(i)/100.0)<<" ";
}
return 0;
}

try while(resztaDoWydania>0)

Related

Why does the program to find the largest number formed using elements of an array not work?

Visit https://www.interviewbit.com/problems/largest-number/ for the question...
Now I wrote the below code to solve the question (although I used an array to store the number, will do the storing in strings part later..)-
So in this algorithm, I basically used quicksort but with a twist, I changed the definition of greater than or lesser than of two numbers say X, Y such that if the number formed by using X first and Y second or XY is >= YX then greater than(X, Y) is true
In the present scenario, the code is giving runtime error, which I can't understand why, also after a bit of debugging as shown in the comments, still the answer is not coming as expected.
#include <iostream>
#include <vector>
#include <cmath>
#include <stdlib.h>
#include <time.h>
using namespace std ;
bool greaterthan(int a,int b)
{
int n1,n2,s1,s2;
n1=((int )log10(a))+1;
n2=((int)log10(b))+1;
s1=a*((int )pow(10,n2))+b;
s2=a + ((int )pow(10,n1))*b;
if(s1>=s2){return true;}
else{return false;}
}
int spartitions(vector<int >&B,int s , int e)
{
int pivot = B[e];
int pin =s;
int i;
for(i=s;i<=e;i++) //if i change this to i<e
{
if(B[pin]>=pivot)
{swap(B[pin],B[i]);
pin++;
}
// and add swap(B[pin],B[e]);
}
return pin-1; // and return pin here then it works but not give correct output
}
int prand(vector<int >&B,int s ,int e)
{
srand(time(NULL));
int n = rand()%(e-s+1)+s;
swap(B[n],B[e]);
int pin = spartitions(B,s,e);
return pin;
}
void qsort(vector<int >&B,int s, int e )
{
if(s<e){
int p= prand(B,s,e);
qsort(B,s,p-1);
qsort(B,p+1,e);
}
}
vector<int> largestnumber(vector<int >&A)
{
int n =A.size();
vector<int >B(n);
B=A;
qsort(B,0,n-1);
return B;
}
int main()
{
int n;
cin>>n;
vector<int>A(n);
int i;
for(i=0;i<n;i++)
{
cin>>A[i];
}
vector<int >B(n);
B=largestnumber(A);
for(i=0;i<n;i++)
{
cout<<B[i];
}
}
Please Help as I am a newbie in programming and can't figure this out from like 3-4 hours ...??
Would really appreciate if someone can correct my code only and not give a different algorithm, as I want this algorithm to be corrected.
Your self-written qsort function recursively calls itself, which adds more things to the stack, which only has so much space. When the list is too big, there will be too many function calls in the stack and it overflows. That's why anything less than 5 for the first input (which is for n) works fine but as soon as you exceed that, you get a runtime error. Consider not using a recursive function call.
Edit: Enabling optimisation also seems to fix this issue.
This may not work depending on the compiler and how it optimises. (Works on MSVC)

For and while loop not working in a globally defined function

#include <iostream>
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
int help(int i,int money,int denomination[]){
int sum=0;
int j=0;
while(i>0){
if(i&1) sum+=denomination[j];
i=i>>1;
j+=1;
}
return sum==money?1:0;
}
int ans(int numOfNotes,int money,int denomination[]){
for(int i=0;i<(1<<numOfNotes);i++){
if(help(i,money,denomination)){
return 1;
}
}
return 0;
}
int main() {
int testCases,numOfNotes,money;
cin>>testCases;
while(testCases>0){
cin>>numOfNotes>>money;
int denomination[numOfNotes];
int i=0;
while(numOfNotes){
cin>>denomination[i];
i++;
numOfNotes--;
}
testCases--;
ans(numOfNotes,money,denomination)==1?cout<<"Yes"<<endl:cout<<"No"<<endl;
}
return 0;
}
If there exists a subset of array denomination such that it amounts to money, program should show "Yes", else "No".
But for the following simple input
1
3 3
1
1
1
output is coming out to be
No
whereas it should be
Yes
According to me, the for and while loops are not working in the ans and help functions. Is there any other bug in the program?
You're modifying numOfNotes in the inner while loop in main, which means its value is 0 when later passed to ans. The loops in the functions are working, you're just giving them other limits than you expected.
You can easily solve issues like this yourself by stepping through your program in a debugger and inspecting variable values and control flow along the way. This is a vital programming skill. See also How to debug small programs by Eric Lippert.
Unrelated to the problem at hand, but please also see these SO questions about what's wrong with including bits/stdc++.h and declaring using namespace std;.

Different output on online judge

I was trying a problem in hackerrank(online judge). The task is to take an input string and then print the characters of the even indices first, followed by a space and then the characters in the odd indices for a given number of test cases 'n'. I was able to solve it. However I get different output on my compiler and a different one in the online judge. The output i get on my computer is correct one but i am not getting the same in the online judge. Here is my code :-
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
int main()
{
int n;
cin>>n;
getchar();
char s[1000];
for(int i=0;i<n;i++)
{
cin.getline(s,1000);
int len;
len=strlen(s);
for(int j=0;j<=len;j++)
{
if(j%2==0)
cout<<s[j];
}
cout<<" ";
for(int m=0;m<len;m++)
{
if(m%2!=0)
{
cout<<s[m];
}
}
cout<<endl;
}
return 0;
}
Input given
1
Hacker
Output when running on my computer using g++
Hce akr
Output when running on the online judge
Hce
Please Help.
Note: 0 is considered an even index.
for(int j=0;j<=len;j++)
{
if(j%2==0)
cout<<s[j];
}
You wrote <= instead of <.
Here, when the word length is even (as is "Hacker"), you're accidentally printing the terminating NULL as well.
The result of this depends on your execution environment. Apparently your terminal just ignores it, and this "online judge" of which you speak does not, instead using it as a NULL terminator for your program output!! (Which is poor coding if you ask me)
N.B. You don't get program output from your compiler. You get it from executing your program, over which the compiler has no control.
Also, please, for the love of Cthulhu, indent your code and use meaningful variable names?

why std::map throws an exception?

I run this code using both gpp and microsoft compiler but in both case I'v got an exception
but I can't understand why!
this is my code:
#include <iostream>
#include <map>
using namespace std;
map<int,int> fib;
int fibo(int i)
{
if (!fib.count(i))
{
fib.insert(pair<int, int>(i,fibo(i-1)+fibo(i-2)));
}
return fib[i];
}
int r(int i)
{
if(i<3)
{
return i;
}
else
{
return fibo(i)+r(i-2);
}
}
int main()
{
fib.insert(pair<int, int>(0,1));
fib.insert(pair<int, int>(1,1));
int a,b,n;
cin>>a>>b;
n=b-a;
int fiba=fibo(a);
int fibaa=fibo(a-1);
cout << (r(n+1)*fiba)+(r(n)*fibaa);
return 0;
}
can anyone help me?
I debugged this code and I found that fib.insert(pair<int, int>(i,fibo(i-1)+fibo(i-2))); doesn't work.
I've got Stack Overflow exception when I ran your code, obviously because of too deep recursion.
You should either increase stack size (but you can later choose to input a larger number and get the same exception again), or convert this algorithm into a non-recursive one (for example see this one: http://www.codeproject.com/Tips/109443/Fibonacci-Recursive-and-Non-Recursive-C)
Did you try to input some negative numbers? You don't do any check on the inputs you pass to your program, and in
return fib[i];
you will receive an error if you try to access non-existent locations.

Code Crashes Immediately After Running

Even at the bare minimum of 10 numbers to input, I get no errors but my code crashes immediately on running. I was also wondering, what should I do if I have a question similar to another question that I've already asked, but on another new problem?
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
int primer(int max);
int main()
{
primer(5);
system("pause");
return 0;
}
int primer(int max){
vector<int> a;
a[1]=2;
for (int i=2;i<=max;i++){
bool prime=true;
for (int ii=0;ii<a.size();ii++) {
if (i/a[ii]==floor(i/a[ii])) {
prime=false;
}
}
if (prime==true) {
a.push_back(i);
}
}
for (int iii=0;iii<=a.size();iii++) {
cout << a[iii] << endl;
}
}
I get no errors but the compiled code crashes immediately.
I changed it to
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
int primer(int max);
int main()
{
primer(5);
system("pause");
return 0;
}
int primer(int max){
vector<int> a;
a.push_back(2);
for (double i=2;i<=max;i++){
bool prime=true;
for (int ii=0;ii<a.size();ii++) {
if (i/a[ii]==floor(i/a[ii])) {
prime=false;
}
}
if (prime) {
a.push_back(i);
}
}
for (int iii=0;iii<=a.size();iii++) {
cout << a[iii] << endl;
return a.size();
}
}
I addressed all of your problems. It still returns no errors and still crashes.
What makes you think you can do this?
vector<int> a;
a[1]=2;
vector<int> a;
a[1]=2;
You can't access a[1] until you've reserved space for it. You should probably use a.push_back(2) to append 2 to the end of a.
You have declared primer to return int, yet it returns nothing. Either make it void or return the number of primes.
i/a[ii]==floor(i/a[ii]) isn't going to do what you expect. i/a[ii] performs integer division. You should cast i to double before dividing.
if (prime==true) can be changed to simply if (prime), no need to compare a boolean to true.
Please improve your coding style. Use proper indentation and more commonly used variable names: i, j, k instead of i, ii, iii.
Here is another bug:
for (int iii=0;iii<=a.size();iii++) {
cout << a[iii] << endl;
return a.size();
}
My understanding is that you can only return once from a function, main included. The execution will not loop here because of the return statement.
Did you really want a return statement inside a for loop?