I'm brushing up on some beginner's algorithms as I familiarize myself with C++. There are already some bugs I have no idea where to start fixing.
1) The following gives me seg faults around the time when the fib() function returns its results. EDIT: with inputs >= 9
#include <iostream>
using namespace std;
int fib(int n) {
int fibs[] = {1, 1}; // dynamic array
int i = 2; // start at 3rd element
while(i < n) {
fibs[i] = fibs[i-2] + fibs[i-1];
cout << "DEBUG: fibs[" << i << "] = " << fibs[i] << endl;
i = i+1;
}
cout << "about to return to main()" << endl;
return fibs[n-1];
}
int main() {
cout << "\n================= Hello cruel world =================" << endl;
cout << "Enter a number: ";
int x;
cin >> x;
cout << "fib(" << x << ") = " << fib(x) << endl;
cout << "================ Goodbye cruel world ================\n" << endl;
return 0;
}
Otherwise, the code works just fine, the numbers are found correctly. But 2) when I change the function to support long integers, it starts acting weird:
#include <iostream>
using namespace std;
long fib(int n) {
long fibs[] = {1L, 1L}; // dynamic array
int i = 2; // start at 3rd element
while(i < n) {
fibs[i] = fibs[i-2] + fibs[i-1];
cout << "DEBUG: fibs[" << i << "] = " << fibs[i] << endl;
i = i+1;
}
cout << "about to return to main()" << endl;
return fibs[n-1];
}
int main() {
cout << "\n================= Hello cruel world =================" << endl;
cout << "Enter a number: ";
int x;
cin >> x;
cout << "fib(" << x << ") = " << fib(x) << endl;
cout << "================ Goodbye cruel world ================\n" << endl;
return 0;
}
Output:
================= Hello cruel world =================
Enter a number: 7
DEBUG: fibs[2] = 2
DEBUG: fibs[0] = 1
DEBUG: fibs[1] = 30071067265
DEBUG: fibs[2] = 30071067266
DEBUG: fibs[14] = 0
about to return to main()
fib(7) = 140733637791872
================ Goodbye cruel world ================
It doesn't make any sense to me. Thanks for any help.
int fibs[] = {1, 1};
is equivalent to:
int fibs[2] = {1, 1};
In another word, the array fibs(in both programs) has only two elements, it's illegal to access fibs[n] if n is bigger than 1.
In
long fibs[] = {1L, 1L};
the [] does not mean "as big as it needs to be", it means "count the number of initializers". It's the same as
long fibs[2] = { 1L, 1L };
And the comment
// dynamic array
is just plain WRONG.
The other answers explain what's wrong. To fix it, you can declare fibs as a vector instead:
vector<int> fibs(n, 1);
which will construct a vector of n integers and initialize them all to 1. Replacing that single line of code should be all you need!
Yes it will fail because fibs[2] doesn't exist!
This is not dynamic array by any mean. Its array of 2 long
long fibs[] = {1L, 1L}; // dynamic array
Related
I am trying to split one large user given vector into x sub vectors. Everything "seems" to work as it should but the outcome is not right.
std::vector<std::vector<std::string>> split_to_sub_vectors(std::vector<std::string> initial_vector, int thread_amount) {
std::cout << "initial size: " << initial_vector.size() << std::endl;
int size_for_splitting = initial_vector.size();
std::cout << "split amount: " << thread_amount << std::endl;
int r = size_for_splitting / thread_amount;
std::cout << r << " need to be in each sub-vector" << std::endl;
std::cout << "There will be: " << size_for_splitting % thread_amount << " element remaining" << std::endl;
std::vector<std::vector<std::string>> perm_vector;
for (int x = 0; x < thread_amount; x++) {
std::vector<std::string> temp_vector;
for (int a = 0; a < r; a++) {
hm++;
std::cout << hm << std::endl;
temp_vector.push_back(initial_vector[hm]);
}
perm_vector.push_back(temp_vector);
}
std::cout << "Size of vector holding the sub vectors after splitting: " << perm_vector.size() << std::endl;
std::cout << perm_vector[0][0];
return perm_vector;
Running this code will give you this:
initial size: 7
split amount: 3
2 need to be in each sub-vector
There will be: 1 element remaining
1
2
3
4
5
6
Size of vector holding the sub vectors after splitting: 3
2
the vector i pass in is called test holds strings and is like so:
test.push_back("1");
test.push_back("2");
test.push_back("3");
test.push_back("4");
test.push_back("5");
test.push_back("6");
test.push_back("7");
Everything up until the last print statement seems to work. So perm_vector should hold 3 sub vectors containing every element in the main user given vector. When you print perm_vector[0][0] you would expect the output to be "1", but it is 2, also 7 should not be in the vector and 6 should be the last one but since it starts at 2, 7 is in it. the counter is defined outside of the function and it starts at 0. My question is why is it starting at 2?
I see two problems in your code:
hm is incremented before use. Furthermore, there is no point in making it global.
size_for_splitting is the result of an integer division, so the remainder is missing
I modified your code so the issues with hm are solved. I get the intended output <<1, 2>, <3, 4>, <5, 6>>, the 7 is missing as mentioned above.
#include <iostream>
#include<vector>
#include<string>
std::vector<std::vector<std::string> > split_to_sub_vectors(std::vector<std::string> initial_vector, int thread_amount) {
std::cout << "initial size: " << initial_vector.size() << std::endl;
int size_for_splitting = initial_vector.size();
std::cout << "split amount: " << thread_amount << std::endl;
int r = size_for_splitting / thread_amount;
std::cout << r << " need to be in each sub-vector" << std::endl;
std::cout << "There will be: " << size_for_splitting % thread_amount << " element remaining" << std::endl;
std::vector<std::vector<std::string> > perm_vector;
int hm = 0;
for (int x = 0; x < thread_amount; x++) {
std::vector<std::string> temp_vector;
for (int a = 0; a < r; a++) {
std::cout << hm << std::endl;
temp_vector.push_back(initial_vector[hm]);
hm++;
}
perm_vector.push_back(temp_vector);
}
std::cout << "Size of vector holding the sub vectors after splitting: " << perm_vector.size() << std::endl;
return perm_vector;
}
int main()
{
std::vector<std::string> test;
test.push_back("1");
test.push_back("2");
test.push_back("3");
test.push_back("4");
test.push_back("5");
test.push_back("6");
test.push_back("7");
std::vector<std::vector<std::string> > out = split_to_sub_vectors(test, 3);
}
Even if hm starts at 0, you increment it before you use it. Probably if you increment at the end of the internal for loop, you might get the output you expect. It's hard to tell the problem because I don't know what's in 'initial_vector', I assume initial_vector[0] = 1?
If you use the range-v3 library, implementing this logic becomes much easier, and less error prone:
#include <range/v3/all.hpp>
namespace rs = ranges;
namespace rv = ranges::views;
auto split_to_sub_vectors(std::vector<std::string> initial_vector, int thread_amount) {
auto res = initial_vector
| rv::chunk(thread_amount)
| rs::to<std::vector<std::vector<std::string>>>;
if (res.back().size() != thread_amount)
res.pop_back();
return res;
}
Here's a demo.
if x > INT_MAX or if x > INT_MIN the function will return 0... or that's what i'm trying to do :)
in my test case i pass in a value that is INT_MAX + 1... 2147483648 ... to introduce integer overflow to see how the program handles it.
i step through... my IDE debugger says that the value immediately goes to -2147483648 upon overflow and for some reason the program executes beyond both of these statements:
if (x > INT_MAX)
if (x < INT_MIN)
and keeps crashes at int revInt = std::stoi(strNum);
saying out of range
Must be something simple, but it's got me stumped. Why isn't the program returning before it ever gets to that std::stoi() given x > INT_MAX? Any help appreciated. Thanks! Full listing of function and test bed below: (sorry having trouble with the code insertion formatting..)
#include <iostream>
#include <algorithm>
#include <string> //using namespace std;
class Solution {
public: int reverse(int x)
{
// check special cases for int and set flags:
// is x > max int, need to return 0 now
if(x > INT_MAX)
return 0;
// is x < min int, need to return 0 now
if(x < INT_MIN)
return 0;
// is x < 0, need negative sign handled at end
// does x end with 0, need to not start new int with 0 if it's ploy numeric and the functions used handle that for us
// do conversion, reversal, output:
// convert int to string
std::string strNum = std::to_string(x);
// reverse string
std::reverse(strNum.begin(), strNum.end());
// convert reversed string to int
int revInt = std::stoi(strNum);
// multiply by -1 if x was negative
if (x < 0)
revInt = revInt * -1;
// output reversed integer
return revInt;
}
};
Main:
#include <iostream>
int main(int argc, const char * argv[]) {
// test cases
// instance Solution and call it's method
Solution sol;
int answer = sol.reverse(0); // 0
std::cout << "in " << 0 << ", out " << answer << "\n";
answer = sol.reverse(-1); // -1
std::cout << "in " << -1 << ", out " << answer << "\n";
answer = sol.reverse(10); // 1
std::cout << "in " << 10 << ", out " << answer << "\n";
answer = sol.reverse(12); // 21
std::cout << "in " << 12 << ", out " << answer << "\n";
answer = sol.reverse(100); // 1
std::cout << "in " << 100 << ", out " << answer << "\n";
answer = sol.reverse(123); // 321
std::cout << "in " << 123 << ", out " << answer << "\n";
answer = sol.reverse(-123); // -321
std::cout << "in " << -123 << ", out " << answer << "\n";
answer = sol.reverse(1024); // 4201
std::cout << "in " << 1024 << ", out " << answer << "\n";
answer = sol.reverse(-1024); // -4201
std::cout << "in " << -1024 << ", out " << answer << "\n";
answer = sol.reverse(2147483648); // 0
std::cout << "in " << 2147483648 << ", out " << answer << "\n";
answer = sol.reverse(-2147483648); // 0
std::cout << "in " << -2147483648 << ", out " << answer << "\n";
return 0;
}
Any test like (x > INT_MAX) with x being of type int will never evaluate to true, since the value of x cannot exceed INT_MAX.
Anyway, even if 2147483647 would be a valid range, its reverse 7463847412 is not.
So I think its better to let stoi "try" to convert the values and "catch" any out_of_range-exception`. The following code illustrates this approach:
int convert() {
const char* num = "12345678890123424542";
try {
int x = std::stoi(num);
return x;
} catch (std::out_of_range &e) {
cout << "invalid." << endl;
return 0;
}
}
So I'm working on this project where I have to gather 2 integers from a user 3 times (loop), and each time I have to print the two integers in ascending order. The restriction is that you can only have two cout statements within your loop (one is asking for their input and the second is outputting the ascending order).
My only issue with that is, when I think about ascending order, I would do it like (which has two count statements):
if (m<n) {
cout << m << n << endl;
if (m>n){
cout << n << m << endl;
So far, this is what I have:
#include <iostream>
using namespace std;
int main(int,char**) {
int n, m, z;
for (n=0;n<3;n++){
cout << "Give me two numbers: ";
cin >> m;
cin >> z;
//if (m>z);
//cout << m << z << "sorted is: " << m << z << endl;
// This is where I'm getting stuck because I need two count statements to organize in ascending order as shown above
}
}
So have you considered to change which variable holds the lower number? e.g.
if(m > n){
int temp = n;
n = m;
m = temp;
}
Then you can just use one print
cout << m << " " << n << endl;
This is where I'm getting stuck because I need two count[sic]
statements to organize in ascending order as shown above
You have marked this post as C++:
Additional options to consider:
use algorithm lib:
#include <algorithm>
std::cout << std::min(m,n) << " " << std::max(m,n) << std::endl;
or use conditional / ternary operator in your cout:
std::cout << ((m<n) ? m : n) << " " << ((n<m) ? m : n) << std::endl;
References are sometimes fun ... but perhaps this challenge is too trivial.
// guess m < n
int& first = m;
int& second = n;
if(!(m<n)) { first = n; second = m; }
std::cout << first << " " << second << std::endl;
Pointers can do the same:
// guess m < n
int& first = &m;
int& second = &n;
if(!(m<n)) { first = &n; second = &m; }
std::cout << *first << " " << *second << std::endl;
or you can use
lambda expressions, or
c++ functions, or
c++ class methods
But I think each of these would be directly comparable to either of the first alternatives.
I found that the parameter I returned is different in the outer function when it's called than where it was in the local function. I set some printing out in each section of the code but still have no idea why the parameter i is not returned:
int assign_cookie(vector<int>& g, vector<int>& s){
if(s.size()==0 || g.size()==0){
cout << "size = 0, returning 0" << endl;
return 0;
}
cout << "s.size() = " << s.size() << endl;
cout << "g.size() = " << g.size() << endl;
sort(g.begin(), g.end());
sort(s.begin(), s.end());
unsigned int i, j = 0;
while(i<g.size() && j<s.size()){
if(g[i]<=s[j]) i++;
j++;
}
cout << "(assign_cookie) i = " << i << endl;
return i;
}
when I called it in the main function as follows:
int main(){
int g[] = {1,2,3};
int s[] = {1,1};
vector<int> vg (g, g+3);
vector<int> vs (s, s+2);
int result = assign_cookie(vg,vs);
cout << "result = " << result << endl;
}
I got results as follows:
s.size() = 2
g.size() = 3
(assign_cookie) i = 1
(main) result = 0
I was very confused with the result. Anyone has an idea what's going on?
Thanks in advance for your help!
You have undefined behaviour, because here
unsigned int i,j=0;
you only initialize j but not i and then you use i as index in g[i] without ever assigning it a meaningful value. Hence it is UB and anything can happen. Actually this is an interesting case of UB, as when you do
unsigned int i,j=0;
std::cout << "i = " << i << "\n";
it still prints
i = 0
(assign_cookie) i = 1
result = 0
see also here. Even if the compiler seems to initialize i to 0 it still realizes that there is UB and takes the freedom to produce garbage output.
Let me preface this by saying I'm still extremely new to C++ and want to keep things as simple as possible. I'm also pretty terrible at math.
Mostly, I'm looking to see if anyone can help my code so it will always give the correct result. I've mostly got it to do what I want, except in one scenario.
My code is trying to find out how many packages of hotdog weiners and how many packages of hotdog buns someone has purchased. Then it tells the user how many hotdogs they can make from that as well as how much leftover weiners or buns they would have. Assuming a package of weiners contains 12 and a package of buns contains 8, this is what I have come up with so far:
#include <iostream>
#include <cmath>
using namespace std;
void hotdog(int a, int b){ //a = weiner packages, b = bun packages
int weiners = 12 * a;
int buns = 8 * b;
int total = (weiners + buns) - (weiners - buns);
int leftOverWeiners = total % weiners;
int leftOverBuns = total % buns;
int totalHotDogs = total / 2;
cout << "You can make " << totalHotDogs << " hotdogs!" << endl;
if (leftOverWeiners > 0){
cout << "You have " << leftOverWeiners << " weiners left over though." << endl;
}else if (leftOverBuns > 0){
cout << "You have " << leftOverBuns << " buns left over though." << endl;
}
}
int main(){
int a;
int b;
cout << "Let's see how many hotdogs you can make!" << endl;
cout << "How many weiner packages did you purchase?: ";
cin >> a;
cout << "How many bun packages did you purchase?: ";
cin >> b;
hotdog(a, b);
return 0;
}
With this, I can always get the correct answer if the ratio of buns to weiners is the same or if there are more weiners than buns.
Because of the way I've set up total and/or leftOverBuns (lines 9, 11), I will never get the correct answer to how many left over buns there will be. I know there must be a simpler way to do this if not a way to modify my current code but I am stumped.
I know I left virtually zero notation, so if you would like some please let me know!
You're making it too complicated. Try this:
if(weiners > buns)
{
cout << "You can make " << buns << " hotdogs!" << endl;
cout << "with " << weiners-buns << " weiners left over" << endl;
return;
}
cout << "You can make " << weiners << " hotdogs!" << endl;
if(buns > weiners)
{
cout << "with " << buns-weiners << " buns left over" << endl;
}
The smaller of {buns, weiners} is the number of hot dogs, and the if-then blocks determine whether the function will report leftover buns or weiners.
#include <iostream>
void hotdog( int weinerspackages, int bunspackages ){
const int weinersPerPackage = 12;
const int bunsPerPackage = 8;
const int totalweiners = weinerspackages * weinersPerPackage;
const int totalbuns = bunspackages * bunsPerPackage;
int leftoverweiners = 0;
int leftoverbuns = 0;
int amountOfHotdogs = 0;
if( totalweiners > totalbuns ){
leftoverweiners = totalweiners - totalbuns;
amountOfHotdogs = totalbuns;
leftoverbuns = 0;
}
else if( totalbuns > totalweiners ){
leftoverbuns = totalbuns - totalweiners;
amountOfHotdogs = totalweiners;
leftoverweiners = 0;
}
else{
amountOfHotdogs = totalweiners;
leftoverweiners = 0;
leftoverbuns = 0;
}
std::cout << "You can make: " << amountOfHotdogs << " Hotdogs" << std::endl;
std::cout << "Leftover Weiners: " << leftoverweiners << " || Leftover Buns: " << leftoverbuns << std::endl;
}
int main(){
int PackagesW = 8;
int PackagesB = 12;
hotdog( PackagesW, PackagesB );
system("pause");
return 0;
}
Note: It is possible to do this with less variables, I declared this amount of variables to make it easier to understand what the numbers represent.
Assuming that it only takes one of each to make a hotdog, you can find which of the ingredients you have the least, and the amount of hotdogs you can make will be limited by the amount of that ingredient, that is why amountOfHotdogs takes the value of the lesser one. If both are equal in amount, then amountOfHotdogs can take the amount of either.
Only the ingredient with the larger amount will have leftovers, therefore leftoverweiners = totalweiners - totalbuns; when totalweiners > totalbuns and vice-versa.