C++ clock() behaving weirdly with recursive function - c++

Here's a simple program I wrote to find all the non-decreasing-digit numbers of length <=L whose digits sum upto N. The code works fine, but when I try to clock the run time using clock() from ctime it shows a weird behaviour.
#include<iostream>
#include<vector>
#include<ctime>
using namespace std;
typedef long long int LL;
int Sum(LL S){
int sum=0;
for(;S;S/=10)
sum+=S%10;
return sum;
}
void Generate(LL S, int len, int N, int L, vector<LL> &V){
if(len<L)
for(int i=0;i<=9;++i)
if(i>=S%10)
Generate(S*10+i, len+1, N, L, V);
int sum = Sum(S);
if(sum!=N)
return;
else if(sum == N && len == L){
V.push_back(S);
cout << S << endl; //Line 4
return;
}
}
int main(){
int N,L;
vector<LL> V;
LL S;
cin >> N >> L;
clock_t start=clock(); //Line 1
Generate(S, 0, N, L, V);
//clock_t start=clock(); //Line 2
clock_t end = clock();
for(int i=0;i<V.size();++i)
cout << V[i] << " ";
cout << endl;
cout << "Run time: " << (double)(end-start)/CLOCKS_PER_SEC;
return 0;
}
I record the no. of clock ticks elapsed before calling the "Generate" function at //Line 1 and I do the same afterwards at //Line 2, the difference of which I believe should give me the no. of clock ticks elapsed in generating the required numbers.
But if I do so my function "Generate"'s processing somehow gets affected! It won't output the numbers to stdout(from //Line 4) and even if I pass a vector to store up the generated numbers, it won't store any!
However, if I use clock() at //Line 2 my output on stdout is fine and the referenced vector V gets filled up with the desired result. but clock() on //Line 2 is of no use.
What I fail to understand is How can a call to clock() affect some processing in 'Generate' function, unless of course I've some obscure Bug! or the clock() is not supposed to be used in this kind of recursive setup?
Please help me Debug this.

I get variable S is being used without being initialized in your code. Really you need to initialize it to 0 in the very beginning. From then on the behavior is quite unpredictable - thus from time to time you might get the correct answers, but I doubt it. It does not depend on the calls of clock().

Related

Can anyone explain why does this recursive function crash?

Why does this recursive (i'm not sure about it, the site i found this code said it was "recursive") code crash (i found this weird approach on Internet, but i'm honestly not understanding how it works) entering values >4000 (sometimes >4023, sometimes >4015, i really don't understand...)...
#include <iostream>
unsigned long long int sum(unsigned long long int k)
{
if (k > 0) {
return k + sum(k - 1);
}
else {
return 0;
}
}
int main()
{
unsigned long long int n;
std::cout << "This program prints the sum of the first N natural numbers.\n\
Enter N: _";
std::cin >> n;
std::cout << "The sum is: " << sum(n) << ".\n\
Press any key to exit...";
system("pause>nul");
return 0;
}
while this, instead, does not?
#include <iostream>
int main()
{
unsigned int n;
std::cout << "Questo programma stampa la somma dei primi N numeri naturali.\n\
Prego inserire N: _";
std::cin >> n;
unsigned long long int tmp = 0;
for (n; n != 0; --n) {
tmp += n;
//std::cout << tmp << ' ';
}
std::cout << "La somma \212: " << tmp << ".\n\
Premere un tasto per uscire...";
system("pause>nul");
return 0;
}
The recursive version uses a little bit of stack space every time it calls itself, so it is limited by the size of the stack and will crash if it calls itself too many times. It's a classic stack overflow error.
The iterative second version doesn't have that problem.
Your first approach
The first approach is recursive. That means that it calls the function sum() once for each k. Lets say, k is 2, than sum() is called twice and so on.
Each function call requires space on the stack for its parameters, local variables and some management data like the stack pointer, the return address to which the program jumps when the function returns and some other stuff. When you call sum() too often, lets say some 4000 times there is not enough space on the stack left for the very next call to sum(). In result you get a stack overflow and your application crashes.
The exact maximum of k you could provide until your app crashes depends on your system. That means, on a desktop with Windows, Linux or MacOS with a "big" stack you can call the function with k = round about 4000 times while on an embedded system the stack per thread may be lower, and your application crashes earlier.
Your second approach
Your second approach is not recursive and therefore does not require any additional space on the stack for calls to other functions. Therefore your application does not crash since you do not get the stack overflow from the first approach.
In addition, your second approach should run much faster since you do not require the time for the many function calls.

How to find the greatest number among the numbers given input?

I'm a beginner in programming and as you can see, I created a program where the user is asked to input three numbers. It will display the greatest among the numbers given. But after I finished the code, a question came into my mind, what if the user was asked to input a hundreds of numbers and should display the greatest among the numbers given. So the question is, is it possible to do that? what are the things I need to learn to produce that result? is there any hints you can give me?
#include <iostream>
#include <string>
using std::cout, std::cin, std::endl, std::string;
int main() {
string result = " is the greatest among the numbers given";
double x, y, z;
cout<<"Enter three numbers to decide which is the largest: "<<endl;
cin >>x;
cin >>y;
cin >>z;
system("clear");
if(x>y && x>z){
cout<< x << result;
} else if (y>z && y>x){
cout << y << result;
} else
cout<< z << result;
return 0;
}
With the program below, you can get as many numbers as you want from the user and find the largest of them.
#include <iostream>
int main()
{
int size=0, largestValue=0, value=0;
std::cout << "Enter total numbers you want to add :" << "\n";
std::cin >> size;
for (int i{ 0 }; i < size; ++i)
{
std::cout << "Enter value to add : ";
std::cin >> value;
if (i == 0 || value > largestValue)
{
largestValue = value;
}
}
std::cout << "Largest value = " << largestValue << "\n";
return 0;
}
One solution would be to store your inputs in a list and sort them afterwards. Just google "sorting alorithms". Also there are nice youtube visualizations.
Another one would be to not save the inputs into dedicated variables - in your case x, y, z - but to always save the largest given input:
int largestInput = std::numeric_limits<int>::min();
int input;
for (int i = 0; i < 10000; i++)
{
std::cin >> input;
largestInput = input > largestInput ? input : largestInput;
}
If you know the inputs are large, you can use vectors.
#include <bits/stdc++.h>
using namespace std;
int main(){
int total_num=0;
cout << "Enter total numbers:" << "\n";
cin>>total_num;
int max_number = INT_MIN;
vector<int> v;
for(int i=0;i<total_num;i++){
int x;
cin>>x;
v.push_back(x);
max_number = max(max_number,x);
}
cout<<"Maximum number present: "<< max_number<<endl;
return 0;
}
Although there is no need to store numbers. But it's your choice if you need it later you can use it in that program.
> what are the things I need to learn
what if the user was asked to input a hundreds of numbers
For this, you'll need to learn about arrays. I suggest you first learn about C-style arrays (int x[3]{};), and then std::array (std::array<int, 3> x{};). You also need to learn about loops.
and should display the greatest among the numbers given
Having to find the largest number in an array is very common. If you want to learn how to do so manually, the other answers here should answer your question. Otherwise, look towards the standard library algorithms std::ranges::max() (C++20) and std::max_element.
Examples
Example 1
Here's a program that uses a C-style array and a simple algorithm to get the largest number:
#include <iostream>
int main(){
// Amount of numbers user should input
constexpr int count{ 3 };
std::cout << "Enter " << count
<< " numbers to decide which is the largest:\n";
// The numbers entered by the user
double numbers[count]{}; // Declare and zero-initialize a C-style array of 3 ints
// Get each number from the user and put it in the array
for (int i{ 0 }; i < count; ++i) {
std::cin >> numbers[i];
}
// The biggest number found so far
int max{ numbers[0] }; // Initialize it with the first number
for (int i{ 1 }; i < count; ++i) { // Start at the second element (element 1)
if (numbers[i] > max) { // If the current number is larger than max...
max = numbers[i]; // ...assign it to max
}
}
std::cout << max << " is the greatest among the numbers given\n";
return 0;
}
Note:
int numbers[count]{};
This creates a C-style array called numbers which has count (3) elements. The first element's "index" is 0 and the last element's is 2. The {} initializes the values of all of the numbers to 0 (good practice).
for (int i{ 0 }; i < count; ++i)
std::cin >> numbers[i];
This loops until i isn't less than count (3) and increments i (++i) each time. It starts at 0, so it loops 3 (0 1 2) times. On each iteration, it gets a number from the console and stores it in numbers[i].
Example 2
Here's a shorter program that uses the standard library:
#include <algorithm> // ranges::max()
#include <array> // array<>
#include <iostream> // cin, cout
int main() {
// Amount of numbers user should input
constexpr int count{ 3 };
std::cout << "Enter "
<< count
<< " numbers to decide which is the largest:\n";
std::array<double, count> numbers{}; // Declare an array of 3 ints
for (int i{ 0 }; i < count; ++i) {
std::cin >> numbers[i];
}
// Return the largest number in array "numbers"
std::cout << std::ranges::max(numbers)
<< " is the greatest among the numbers given\n";
return 0;
}
Note:
std::array<int, count> numbers{};
Declares an array of count (3) ints and zero-initializes it.
std::ranges::max(numbers)
This neat function finds the largest number in numbers. It was added in C++20 -- if you're using an older compiler, you should use *std::max_element(numbers.begin(), numbers.end()). If you want to learn how the latter works, you need to learn about iterators and pointers.
Here are some good practices that your tutorial hasn't taught you yet (if it ever will):
DON'T use using namespace std. It's unsafe because it brings everything in the standard library into global scope. The standard library contains a lot of commonly used identifiers like count and list. Bringing these into global scope is dangerous because it can cause naming conflicts.
Don't use copy initialization (int x = 3). Use uniform/brace/list initialization instead (int x{ 3 }). The former sometimes makes an unnecessary copy, whereas the latter doesn't. The latter also refuses to do narrowing conversions (e.g. initializing a short with a long).
Always initialize variables (do: int x{}, don't: int x), even when it seems redundant. If you don't, then the value stored is undefined - it could be anything. Undefined behaviour is hard to debug but luckily easy to avoid.
Use \n instead of std::endl. Both do the same, except std::endl does an extra buffer flush which is slow and unnecessary. \n is shorter anyways.
DRY -- Don't Repeat Yourself. You have the string " is the greatest among the numbers given" three times in your code. You could have stored it in a std::string instead -- then it wouldn't have repeated.
Repeating code is bad, because:
It's harder to read
It's harder to maintain (you would have to modify it everywhere it's repeated)
Maintenance is more error-prone
If I were you, I'd immediately find a different tutorial/book. See this thread.
#include <stdio.h>
int main()
{
int num1, num2, num3, num4;
printf("Enter num1\n");
scanf("%d",&num1);
printf("Enter num2\n");
scanf("%d",&num2);
printf("Enter num3\n");
scanf("%d",&num3);
printf("Enter num4\n");
scanf("%d",&num4);
if(num1>num2 && num1>num3 && num1>num4){
printf("greatest number is %d",num1);
}
if(num2>num3 && num2>num1 && num2>num4){
printf("greatest number is %d",num2);
}
if(num3>num1 && num3>num2 && num3>num4){
printf("greatest number is %d",num3);
}
if(num4>num1 && num4>num2 && num4>num3){
printf("greatest number is %d",num4);
}
return 0;
}

Measuring running time of program with clock

We are studying the performance of various sorting algorithms and implemented our version of mergesort. We are trying to measure the running time with different input, but when we run the main() program shown below, we are getting different time results.
For example, clock() function output below can show 30 seconds with large input, but when we use the actual timer using our phones, the main program takes about 2 minutes.
What are we missing here? Are we not using the clock() function in a right way? Why is there such a big difference (1.5 minutes)?
Thank you
int n;
cout << "Enter n - lenght of array" << endl;
cin >> n;
vector<int> v(n);
for(int i = 0; i < n; ++i)
{
v[i] = i;
}
auto rng = default_random_engine {};
std::shuffle(std::begin(v), std::end(v), rng);
clock_t begin = clock();
sort(v);
cout << "done";
clock_t end = clock();
cout <<"total time : " << (double)(end-begin) / CLOCKS_PER_SEC<<endl;
return 0;
I ran your code by replacing the sort function with the std::sort, for n=5000000 it showed 11.744s then I moved the line clock_t begin = clock(); before the declaration of vector v and the time was 13.818s
So it seems memory allocation, O(N) initialization and shuffling can take a good amount of time and if you choose a much bigger number for n, depending on the efficiency of your sort function for a random inputset, initialization can take more time than the sort.

Getting inf in a Taylor expansion for e^x, but only for small error bounds

I am writing a program to approximate an exponential function, but I'm running into a problem. For small values of err the program messes up and just loops forever, getting approximations of inf every time. The program seems to be intolerant of larger and larger errors as larger x's are entered. It works fine for, say, x=1 and err=10e-5. As an example of when it doesn't work: x=3 it works fine up to err=10e-4 but when err=10e-5 it results in inf.
//This program approximates e^x at a given x to a given accuracy
#include<algorithm>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
using namespace std;
inline void keep_window_open() {char ch; cin >> ch;}
class bad_entry{};
int fac(int a) //function to find factorial
{
int f=1; //covers 0!
for(int w=0; w<a; ++w)
{
f*=(a-w);
}
return f;
}
int main()
{
try
{
double x=0;
double ans=0;
double err=0;
int n=0;
cout << "What number do you want to expand around?\n";
cin >> x;
if(!cin){throw bad_entry{};}
cout << "What would you like the error to be within?\n";
cin >> err;
if(!cin){throw bad_entry{};}
double actual=exp(x);
while(n>=0)
{
ans += pow(x,n)/fac(n);
cout << "n=" << n << '\t' << "Approx: " << ans << '\t' << "Erro: " << abs(actual-ans) << '\n';
if(abs(actual-ans)<err)
{
keep_window_open();
return 0;
}
++n;
}
}
catch(bad_entry)
{
cout << "\nINVALID ENTRY\n";
return 0;
}
}
If you write a program that just prints fac for increasing n values, you'll get:
n=1 fac=1
n=2 fac=2
n=3 fac=6
n=4 fac=24
n=5 fac=120
n=6 fac=720
n=7 fac=5040
n=8 fac=40320
n=9 fac=362880
n=10 fac=3628800
n=11 fac=39916800
n=12 fac=479001600
n=13 fac=1932053504 // Ups - wrong - should be 6227020800
n=14 fac=1278945280 // Ups - wrong
n=15 fac=2004310016 // Ups - wrong
So you have an overflow already for n equal 13. Therefore all calculations will fail and give strange results.
If you change fac function to use uint64_t instead of int it will be a little better, i.e. higher n before overflow.
Your "while" loop is actually divergent; you are incrementing the counter instead of decrementing.
Moreover, the "pow" function is itself implemented as "exp(y*ln(x))", which makes your implementation redundant, inefficient and imprecise.
The factorial caculation makes the complexity O(n2) which is bad. A simple increasing for loop without break, having the precision criteria as its condition clause, and incremental calculation of factorial and integer x powers would do the job.

Why is clock() returning 1.84467e+13?

I am trying to time a code I've got in C++. I have an inner and an outer loop that I want to time separately, but at the same time. For some reason when I do this one of the instances returns 1.84467e+13 and always this exact number.
Why is this happening?
Here is a minimum working example that replicates the effect on my machine:
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main()
{
long int i, j;
clock_t start, finish, tick, tock;
double a = 0.0;
double adding_time, runtime;
start = clock();
for(i=0; i<10; i++)
{
a=0.0;
tick =clock();
for(j=0; j<10000000; j++)
{
a+=1;
}
tock= clock();
adding_time = (double)(tick - tock)/CLOCKS_PER_SEC;
cout << "Computation time:" << adding_time << endl;
}
finish = clock();
runtime = (double)(finish - start)/CLOCKS_PER_SEC;
cout << "Total computation time:" << runtime << endl;
}
Your clock_t is apparently an unsigned 64-bit type.
You're taking tick - tock, where tock was measured after tick, so if there's any difference between the two at all, it's going to try to produce a negative number--but since it's an unsigned type, that's wrapping around to become something close to the largest number that can be represented in that type.
Obviously, you really want to use tock-tick instead.
let say tic = 2ms and tac is 4ms; so when you do tic-tac(2-4) that will generate a negative number obviously.. even if it given a positive number it wont be the real time. and also, the number it generate (which doesnt appear on my computer) is a big number, so, try to use the manipulator;
#include"iomanip"
cout << fixed << showpoint;
cout << setprecision(2);
it might work..