I have created a program that prints out all of the permutations of the characters provided through command-line arguments and decided I wanted to compare execution time to an equivalent program written in Java.
The program worked until I decided to find the permutations multiple times in order to get an average execution time.
void avgTime(char**& argv, int times) {
if (sizeof(argv) > 1) {
long permutationAmnt;
clock_t s_start, s_end, t_start, t_end;
float s_runms, t_runms;
long avg_time;
for (int count = 0; count < times; count++) {
t_start = clock();
for (int i = 1; i < sizeof(argv); i++) {
s_start = clock();
permutationAmnt = permutations(std::string(argv[i]));
s_end = clock();
s_runms = ((float)s_end - s_start) / CLOCKS_PER_SEC * 1000;
std::cout << "SUCCESS (" << s_runms << "ms for " << permutationAmnt << " permutations)" << std::endl << std::endl;
}
t_end = clock();
t_runms = ((float) t_end - t_start) / CLOCKS_PER_SEC * 1000;
std::cout << std::endl << "TOTAL RUNTIME: " << t_runms << "ms" << std::endl;
avg_time += t_runms;
}
std::cout << "AVERAGE RUNTIME: " << avg_time / times << "ms" << std::endl;
}
}
int main(int argc, char** argv) {
avgTime(argv, 10);
return 0;
}
The first for-loop in avgTime() only executes a single time (putting a cout inside of it only prints one time) and the program appears to terminate after the nested for-loop breaks.
I am not sure if the problem is with some of the code from avgTime() or if it comes from one of the helper functions, like permute(). Either way here is the code for each of the helper functions as well as the includes (p.s. num is declared outside of any functions).
/*
* Calls the recursive permute() function then
* returns the total amount of permutations possible
* for the given input.
*
* NOTE: the num variable is used in the permute() function
* for numbering the permutations printed as output (see next function
* for clarificiation)
*/
long permutations(const std::string& arg) {
long totalPermutations = factorial(arg.size()); //self-explanatory
num = 1;
permute(arg, 0);
return totalPermutations;
}
/*
* Recursively prints out each permutation
* of the characters in the argument, str
*/
void permute(const std::string& str, int place) {
if (place == str.size() - 1) std::cout << ((num <= 10) ? "0" : "") << num++ << ". " << str << std::endl;
for (int i = place; i < str.size(); i++) {
permute(swap(place, i, str), place + 1); //self-explanatory
}
}
long factorial(int num) {
if (num < 2) {
return 1;
}
return factorial(num - 1) * num;
}
std::string swap(int i, int j, const std::string& str) {
std::string s(str);
s[i] = s[j];
s[j] = str[i];
return s;
}
NOTE: the permute() function appears before the permutation() function in the source code and is visible to all the necessary callers of it.
//Includes and namespace stuff
#include <iostream>
#include <string>
#include <time.h>
I would appreciate any help that you guys can offer, if there is any additional information that you would like me to provide just let me know. Thanks again for any help.
P.S. No, this isn't a homework assignment :P
EDIT: Removed using namespace std; and adjusted the code accordingly to avoid confusion between the function std::swap() and my own swap() function. Also, added the swap() and factorial() functions to avoid any ambiguity. I apologize for the confusion this caused.
I was using sizeof(argv) rather than just using argc. Switching to the latter option fixed the issue.
Related
A program is divided into N functions.
Like the following code snippets: after calling each function, I wanna show the progress count/N
how to count N at compile time ?
#include <iostream>
using namespace std;
double progress()
{
int const total = 4; // how to get 4?
static int counter = 0;
return static_cast<double>(counter++) / static_cast<double>(total);
}
int main()
{
cout << progress() << endl; // 0.25
cout << progress() << endl; // 0.5
cout << progress() << endl; // 0.75
cout << progress() << endl; // 1.0
return 0;
}
I tried constexpr function, but cannot increment a variable.
Imagine the following code:
int main() {
cout << "N = ";
int N;
cin >> N;
for (int i = 0; i < N; ++i) cout << 'progress()' << endl;
}
There is absolutely no way, the compiler can know how many times the function will be executed. So you need to determine the number using the logic of your data.
If you want to know how many times you call progress without loops, recursions, conditions etc., the only way I can think of is using external tool on the source file. E.g.
cat source.cpp | grep -o progress() | wc -l
Just remember to subtract 1 from the result, which accounts for the function definition.
You can't do it, but you could fake it by making the printing happen after N (function call count) is known.
static struct counter_impl {
int n = 0;
constexpr void operator ()() noexcept { ++n; }
friend std::ostream& operator<<(std::ostream& os, counter_impl const& self) {
os << std::fixed;
std::generate_n(std::ostream_iterator<double>(os, "\n"), self.n,
[i = 1, N = static_cast<double>(self.n)] () mutable { return i++ / N; });
return os << std::defaultfloat;
}
} counter;
int main() {
counter();
std::cout << counter; // 1.00
}
Live example on compiler explorer
Unfortunately, you cannot.
This is not something that can be determined at compile time.
See https://en.wikipedia.org/wiki/Halting_problem
I am new to C++ and I need to measure the total time for different parts of a recursive function. A simple example to show where I get so far is:
#include <iostream>
#include <unistd.h>
#include <chrono>
using namespace std;
using namespace std::chrono;
int recursive(int);
void foo();
void bar();
int main() {
int n = 5; // this value is known only at runtime
int result = recursive(n);
return 0;
}
int recursive(int n) {
auto start = high_resolution_clock::now();
if (n > 1) { recursive(n - 1); n = n - 1; }
auto stop = high_resolution_clock::now();
auto duration_recursive = duration_cast<microseconds>(stop - start);
cout << "time in recursive: " << duration_recursive.count() << endl;
//
// .. calls to other functions and computations parts I don't want to time
//
start = high_resolution_clock::now();
foo();
stop = high_resolution_clock::now();
auto duration_foo = duration_cast<seconds>(stop - start);
cout << "time in foo: " << duration_foo.count() << endl;
//
// .. calls to other functions and computations parts I don't want to time
//
start = high_resolution_clock::now();
bar();
stop = high_resolution_clock::now();
auto duration_bar = duration_cast<seconds>(stop - start);
cout << "time in bar: " << duration_bar.count() << endl;
return 0;
}
void foo() { // a complex function
sleep(1);
}
void bar() { // another complex function
sleep(2);
}
I want the total time for each of the functions, for instance, for foo() it is 5 seconds, while now I always get 1 second. The number of iterations is known only at runtime (n=5 here is fixed just for simplicity).
To compute the total time for each of the functions I did try replacing the type above by using static and accumulate the results but didn't work.
You can use some container to store the times, pass it by reference and accumulate the times. For example with a std::map<std::string,unsinged> to have labels:
int recursive(int n, std::map<std::string,unsigned>& times) {
if (n >= 0) return;
// measure time of foo
times["foo"] += duration_foo;
// measure time of bar
times["bar"] += duration_bar;
// recurse
recursive(n-1,times);
}
Then
std::map<std::string,unsigned> times;
recursive(200,times);
for (const auto& t : times) {
std::cout << t.first << " took total : " << t.second << "\n";
}
there is code.
#include "pch.h"
#include <algorithm>
#include <iostream>
#include <vector>
#include <stdlib.h>
using namespace std;
vector<int> SearchInt(vector<int> vec, int num) {
vector<int> temp(2);
sort(begin(vec), end(vec));
int j = 0;
for (int i : vec) {
if (i > num) {
temp[0] = i;
temp[1] = j;
return { temp };
}
//cout << i << " !>= " << num << endl ;
j++;
}
cout << "NO";
exit(0);
}
int main()
{
int n;
cin >> n;
vector<int> nums(n, 0);
vector<int> NewNums(n, 0);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
if (n != nums.size()) {
cout << "://";
return 0;
}
sort(begin(nums), end(nums));
NewNums[1] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
NewNums[0] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
for (int j = 2; j <= NewNums.size() - 1; j++) {
NewNums[j] = SearchInt(nums, NewNums[j-1]- NewNums[j-2])[0];
nums.erase(nums.begin() + SearchInt(nums, NewNums[j] - NewNums[j - 1])[1]);
}
if (NewNums[NewNums.size()-1] < NewNums[NewNums.size() - 2] + NewNums[0]) {
cout << "YES" << endl;
for (int i : NewNums) {
cout << i << " ";
}
return 0;
}
else {
cout << "NO";
return 0;
}
}
His task is to check whether it is possible from the given Each number is less than the sum of the two adjacent ones.
(each number is less than both of two adjacent ones)
But there is a problem - with a large number of numbers, the code takes too long. Please help me to optimize it, or just give some advice.
numbers cаn not be null.
time limit: 3.0 s
n <= 500000
You are given n numbers a1, a2,…, an. Is it possible to arrange them in a circle so that each number is strictly less than the sum of its neighbors?
For example, for the array [1,4,5,6,7,8], the left array satisfies the condition, while the right array does not, since 5≥4 + 1 and 8> 1 + 6.
Input data
The first line contains one integer n (3≤n≤105) - the number of numbers.
The second line contains n integers a1, a2,…, an (1≤ai≤109) - the numbers themselves. The given numbers are not necessarily different.
Output
If there is no solution, print "NO" on the first line.
If it exists, print "YES" on the first line. After that, on the second line print n numbers - the elements of the array in the order in which they will stand on the circle. The first and last elements you print are considered neighbors on the circle. If there are multiple solutions, output any of them. You can print a circle starting with any of the numbers.
First I'll only briefly analyze technical shortcomings of your code - without analyzing its meaning. After that I'll write my solution of the problem you defined.
Performance problems of your code are due to some strange decisions:
(1) passing std::vector<int> by value and not by reference to SearchInt function - this implies allocating and copying of the whole array on each function invocation,
(2) call SearchInt two times per loop iteration in function main instead of only one,
(3) sort array within each invocation of SearchInt - it is already sorted before the loop.
To be honest your code feels ridiculously time-consuming. I'm only wondering if that was your intention to make it as slow as you possibly can...
I will not analyze correctness of your code according to problem description. To be honest even after fixing technical shortcomings your code seems to me utterly sub-optimal and quite incomprehensible - so it is just easier to solve the problem from scratch to me.
The answer to the problem as defined is YES if the biggest number is smaller than the sum of the second big and the third big and NO otherwise - this follows from the fact that all numbers are positive (in range 1 - 109 according to newly found problem description). If the answer is YES then to make a circle that satisfies the problem description you just need in a sorted sequence of input numbers switch places of the biggest number and the next big one - that's all.
Here is my code for that (for slightly relaxed input format - I'm not checking if number of items is on a separate line and that all items are on the same line - but all correct inputs will be parsed just fine):
#include <set>
#include <iostream>
int main()
{
std::multiset<unsigned> input_set;
unsigned n;
if( !( std::cin >> n ) )
{
std::cerr << "Input error - failed to read number of items." << std::endl;
return 2;
}
if( n - 3U > 105U - 3U )
{
std::cerr << "Wrong number of items value - " << n << " (must be 3 to 105)" << std::endl;
return 2;
}
for( unsigned j = 0; j < n; ++j )
{
unsigned x;
if( !( std::cin >> x ) )
{
std::cerr << "Input error - failed to read item #" << j << std::endl;
return 2;
}
if( x - 1U > 109U - 1U )
{
std::cerr << "Wrong item #" << j << " value - " << x << " (must be 1 to 109)" << std::endl;
return 2;
}
input_set.insert(x);
}
std::multiset<unsigned>::const_reverse_iterator it = input_set.rbegin();
std::multiset<unsigned>::const_reverse_iterator it0 = it;
std::multiset<unsigned>::const_reverse_iterator it1 = ++it;
if( *it0 >= *it1 + *++it )
{
std::cout << "NO (the biggest number is bigger than the sum of the second big and the third big numbers)" << std::endl;
return 1;
}
std::cout << "YES" << std::endl;
std::cout << "Circle: " << *it1 << ' ' << *it0;
do
{
std::cout << ' ' << *it;
}
while( ++it != input_set.rend() );
std::cout << std::endl;
return 0;
}
I am trying to calculate the final digit of a 13 digit ISBN using the first 12 digits using C++. I feel like my code should be correct but I have a feeling the formula I'm using may be wrong.
The formula is:
10 - (d0 + d1 * 3 + d2 + d3 * 3 + d4 + d5 * 3 + d6 + d7 * 3 + d8 + d9 * 3 + d10 + d11 * 3) % 10
Here's what I have:
#include <cstring>
#include <iostream>
int main() {
int weightedSum = 0;
int checksum = 0;
int i; //for loop decrement
int mul = 3;
const int LENGTH = 12;
char ISBNinput[LENGTH];
std::cout << "Enter first 12 digits of ISBN: "; //ask user for input
std::cin >> ISBNinput; //stores input into ISBNinput
std::cout << std::endl;
for (i = 0; i < strlen(ISBNinput); i++) {
weightedSum += (ISBNinput[i] % 12) * mul;
if (mul == 3) {
mul = 1;
} else {
mul = 3;
}
}//close for loop
checksum = weightedSum % 10; //calculates checksum from weightedSum
std::cout << checksum << std::endl; //prints checksum with new line for format
return 0;
}
For example:
978007063546 should return 3
and
978032133487 should return 9
Thank you for any help.
Here's how I go about this.
First, let's decide how we're going to test this. I'll assume that we've written the function, and that it gives the correct output. So I pick up a couple of books off my desk, and test that it works for them:
#include <iostream>
int main()
{
std::cout << "Book 1 - expect 3, got " << checksum("978032114653") << std::endl;
std::cout << "Book 2 - expect 0, got " << checksum("978020163361") << std::endl;
}
Of course, when we try to compile that, we get an error. So create the function, before main():
char checksum(const char *s)
{
return '1';
}
Now it compiles, but the result is always 1, but now we can start to fill in the body. Let's start with some smaller examples, that we can calculate by hand; add these at the beginning of main():
std::cout << "1 digit - expect 4, got " << checksum("6") << std::endl;
Now let's get this one working - this gives us conversion from character to digit and back, at least:
char checksum(const char *s)
{
int digit = *s - '0';
return '0' + 10 - digit;
}
Let's try 2 digits:
std::cout << "1 digit - expect 6, got " << checksum("11") << std::endl;
And now our test fails again. So add some more processing, to make this pass (and not break the single-digit test):
char checksum(const char *s)
{
int sum = 0;
int digit = *s - '0';
sum += digit;
++s;
if (*s) {
digit = *s - '0';
sum += 3 * digit;
}
return '0' + (10 - sum)%10;
}
We're probably ready to make this into a loop now. Once that's passed, we no longer need the short tests, and I have:
#include <iostream>
char checksum(const char *s)
{
int sum = 0;
for (int mul = 1; *s; ++s) {
int digit = *s - '0';
sum += mul * digit;
mul = 4 - mul;
}
return '0' + (1000 - sum)%10;
}
int test(const char *name, char expected, const char *input)
{
char actual = checksum(input);
if (actual == expected) {
std::cout << "PASS: " << name << ": "
<< input << " => " << actual
<< std::endl;
return 0;
} else {
std::cout << "FAIL: " << name << ": "
<< input << " => " << actual
<< " - expected " << expected
<< std::endl;
return 1;
}
}
int main()
{
int failures = 0;
failures += test("Book 1", '3', "978032114653");
failures += test("Book 2", '0', "978020163361");
return failures > 0;
}
I factored out the actual checking into a function here, so we can keep count of failures, and exit with the appropriate status, but everything else is as I described above.
You'll want to add a few more test cases - in particular, make sure the function correctly returns the extreme values 0 and 9 when it should.
There is one clear bug in your code: you are not allocating enough space in for ISBNinput. You should make it one character longer:
const int LENGTH = 13;
The reason for this is that that character-array strings are terminated with an extra null character. You might be lucky and the next byte in memory could sometimes happen to be a null byte, in which case the program would still work sometimes.
If you run the program with valgrind or a similar memory checker you are likely to see an error as the program access memory beyond what was allocated on the stack.
Also I think there is another bug. I think that mul should be initialized to 1.
By the way, this code is very fragile, depending on you entering no more than 12 characters, all of which are assumed to be digits. It might be OK as a quick hack for a proof-of-concept, but should not be used in any real program.
To clarify, this is a lab for class. I'm just learning all the fundamentals right now. I am trying to figure out how to print the total using a float variable AND a double variable (I thought we can just choose one or the other) while using loop mechanisms (while, do-while or for). I decided to go with the for loop. Any suggestions would be helpful. What I have now prints every single fraction until it gets to the very last one. I tried different variations but so far I got nothing.
I need help calculating the total for:
1/1 + 1/2 + 1/3 + 1/4 +....... 1/99999999 + 1/100000000
This is what I have so far:
#include <iostream>
using namespace std;
int main()
{
float answer = 0;
int num;
for (int den = 1; den <= 100000000; ++den)
{
num = 1;
cout << num << "/" << den;
if (den == 100000000)
cout << " = " << endl;
else
cout << " + ";
answer += ( (float)num ) / ( (float)den );
}
cout << answer << endl;
}
Thanks!
At any point in time, your program has to be using either a float or a double, so I guess you're wanting to reuse your calculation code for each of those types in turn. Here's an example of how to do the calculation twice using a template - first for float, then for double:
#include <iostream>
template <typename T>
void calculate()
{
T answer = 0;
for (int den = 1; den <= 100000000; ++den)
answer += T(1) / T(den);
std::cout << answer << '\n';
}
int main()
{
calculate<float>();
calculate<double>();
}