Я написал три версии алгоритма для своего университетского класса.
Одна - грубая сила, другая - жадная, а последняя - эвристическая.
Я хочу быть в состоянии измерить, скольковремя, необходимое для выполнения каждого из алгоритмов.
Я использую библиотеку <chrono>
для достижения этого
Прямо сейчас мой код выглядит так:
#include <iostream>
#include <chrono>
#include <sstream>
using namespace std;
string getTimeElapsed(long time1, const string &unit1, long time2 = 0, const string &unit2 = "") {
stringstream s;
s << time1 << " [" << unit1 << "]";
if (time2) s << " " << time2 << " [" << unit2 << "]";
return s.str();
}
int main() {
auto begin = chrono::system_clock::now();
// algorithm goes here
auto solution = /* can be anything */
auto end = chrono::system_clock::now();
auto diff = end - begin;
string timeElapsed;
auto hours = chrono::duration_cast<chrono::hours>(diff).count();
auto minutes = chrono::duration_cast<chrono::minutes>(diff).count();
if (hours) {
minutes %= 60;
timeElapsed = getTimeElapsed(hours, "h", minutes, "min");
} else {
auto seconds = chrono::duration_cast<chrono::seconds>(diff).count();
if (minutes) {
seconds %= 60;
timeElapsed = getTimeElapsed(minutes, "min", seconds, "s");
} else {
auto milliseconds = chrono::duration_cast<chrono::milliseconds>(diff).count();
if (seconds) {
milliseconds %= 1000;
timeElapsed = getTimeElapsed(seconds, "s", milliseconds, "ms");
} else {
auto microseconds = chrono::duration_cast<chrono::microseconds>(diff).count();
if (milliseconds) {
microseconds %= 1000;
timeElapsed = getTimeElapsed(milliseconds, "ms", microseconds, "μs");
} else {
auto nanoseconds = chrono::duration_cast<chrono::nanoseconds>(diff).count();
if (microseconds) {
nanoseconds %= 1000;
timeElapsed = timeElapsed = getTimeElapsed(microseconds, "μs", nanoseconds, "ns");
} else timeElapsed = getTimeElapsed(nanoseconds, "ns");
}
}
}
}
cout << "Solution [" << solution << "] found in " << timeElapsed << endl;
return 0;
}
КакВы можете видеть, что составленные if-else
предложения выглядят действительно некрасиво, и вы можете увидеть шаблон здесь:
if (timeUnit) {
timeElapsed = /* process current time units */
} else {
/* step down a level and do the same for smaller time units */
}
Я хотел бы сделать эту процедуру рекурсивной функцией.
Однако яПонятия не имею, какими должны быть параметры такой функции, потому что chrono::duration
является шаблонной структурой (?)
Эта функция будет выглядеть примерно так:
string prettyTimeElapsed(diff, timeUnit) {
// recursion bound condition
if (timeUnit is chrono::nanoseconds) return getTimeElapsed(timeUnit, "ns");
auto smallerTimeUnit = /* calculate smaller unit using current unit */
if (timeUnit) return getTimeElapsed(timeUnit, ???, smallerTimeUnit, ???);
else return prettyTimeElapsed(diff, smallerTimeUnit);
}
Я думалсделать это:
auto timeUnits = {chrono::hours(), chrono::minutes(), ..., chrono::nanoseconds()};
Тогда я мог бы взять указатель (или даже индекс) на единицу времени и передать его функции.
Проблема в том, что я незнать, как обобщать эти структуры.
CLion выдвигает ошибку Deduced conflicting types (duration<[...], ratio<3600, [...]>> vs duration<[...], ratio<60, [...]>>) for initializer list element type