how can I abort a funciton after elapsed time? - c++

I am testing some algorithms and timing them. I would like to know how to abort the function while its running if it runs for longer than 60 seconds. Here's what I'm working with:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <ctime>
#include <chrono>
#include <cstdlib>
#include <random>
#include <algorithm>
using namespace std;
bool isUnique(const vector<int>& arr, int start, int end) {
if (start >= end) return true;
if (!isUnique(arr, start, end - 1))
return false;
if (!isUnique(arr, start + 1, end))
return false;
return (arr[start] != arr[end]);
}
bool isUniqueLoop(const vector<int>& arr, int start, int end) {
if (start >= end) return true;
for (int i = start; i < end; i++)
for (int j = i + 1; j <= end; j++)
if (arr[i] == arr[j])return false;
return true;
}
bool isUniqueSort(const vector<int>& arr, int start, int end) {
if (start <= end) return true;
vector<int> buf(arr);
sort(buf.begin() + start, buf.begin() + end);
for (int i = start; i < end; i++)
if (buf[i] == buf[i + 1]) return false;
return true;
}
int main() {
int max = 0;
cout << "Enter a number for the Max range: ";
cin >> max;
default_random_engine randGen(time(0));
uniform_int_distribution<int> randNum(0, max);
int i;
int j;
int n = randNum(randGen);
int m = n;
vector<int> myVect;
for (i = 0; i <= m; i++) {
myVect.push_back(randNum(randGen));
//cout << myVect[i] << endl;
}
cout << "Recursive Algorithm Test... " << endl;
cout << endl;
// recursive algorithm
clock_t start = clock();
isUnique(myVect, 0, n);
if (isUnique(myVect, 0, n) == true) {
cout << "The Vector is Unique! " << endl;
}
else {
cout << "The Vector is not Unique! " << endl;
}
clock_t end = clock();
double time = (double)(end - start) / CLOCKS_PER_SEC * 1000.0;
cout << "CPU Time used for this algorithm: " << time << " ms" << endl;
if (time > 60000) {
cout << "This function takes too long! " << endl;
}
cout << "------------------------------------" << endl;
cout << "Iterative Algorithm Test... " << endl;
cout << endl;
// iterative algorithm
clock_t start2 = clock();
isUniqueLoop(myVect, 0, n);
if (isUniqueLoop(myVect, 0, n) == true) {
cout << "The Vector is Unique! " << endl;
}
else {
cout << "The Vector is not Unique! " << endl;
}
clock_t end2 = clock();
double time2 = (double)(end2 - start2) / CLOCKS_PER_SEC * 1000.0;
cout << "CPU time used for this algorithm: " << time2 << " ms. " << endl;
if (time2 > 60000) {
cout << "This function takes too long! " << endl;
}
cout << "------------------------------------" << endl;
cout << "Sort Algorithm Test... " << endl;
cout << endl;
// sort algorithm
clock_t start3 = clock();
isUniqueSort(myVect, 0, n);
if (isUniqueSort(myVect, 0, n) == true) {
cout << "The Vector is Unique! " << endl;
}
else {
cout << "The Vector is not Unique " << endl;
}
clock_t end3 = clock();
double time3 = (double)(end3 - start3) / CLOCKS_PER_SEC * 1000.0;
cout << "CPU time used for this algorithm: " << time3 << " ms. " << endl;
if (time3 > 60000) {
cout << "This function takes too long! " << endl;
}
cout << endl;
system("pause");
return 0;
}
everything works fine except the fact that I want it to quit the function isUnique(myVect, 0, m) if it lasts longer than 60 seconds....Any suggestions?

When you have an exceptional circumstance (like a timeout) you can throw an exception. In your case what kind of exceptions is up to you. Exceptions work well when you want to exit a many levels deep call tree without having to check every function individually for an exit return code. In the example below I am throwing a string as an exception:
Edit
To prevent doing the time calculations way too often here is an attempt to limit how often they are done. This is by no means scientific, but on my box it gives a reasonable result. If you have a better way let me know.
#include <iostream>
#include <vector>
#include <ctime>
#include <chrono>
#include <cstdlib>
#include <random>
#include <algorithm>
bool isUnique(const std::vector<int>& arr, int start, int end, clock_t clock_start,
unsigned long & iterations, unsigned long timecheck) {
if (++iterations > timecheck) {
iterations = 0;
clock_t clock_current = clock();
double time = (double)(clock_current - clock_start) * 1000.0 / CLOCKS_PER_SEC;
if (time > 60000) throw "This function takes too long!";
else std::cout << time << " ms elapsed..." << std::endl;
}
if (start >= end) return true;
if (!isUnique(arr, start, end - 1, clock_start, iterations, timecheck))
return false;
if (!isUnique(arr, start + 1, end, clock_start, iterations, timecheck))
return false;
return (arr[start] != arr[end]);
}
bool isUniqueLoop(const std::vector<int>& arr, int start, int end, clock_t clock_start,
unsigned long & iterations, unsigned long timecheck) {
if (start >= end) return true;
for (int i = start; i < end; i++) {
for (int j = i + 1; j <= end; j++) {
if (++iterations > timecheck) {
iterations = 0;
clock_t clock_current = clock();
double time = (double)(clock_current - clock_start) * 1000.0 / CLOCKS_PER_SEC;
if (time > 60000) throw "This function takes too long!";
else std::cout << time << " ms elapsed..." << std::endl;
}
if (arr[i] == arr[j])return false;
}
}
return true;
}
bool isUniqueSort(const std::vector<int>& arr, int start, int end, clock_t clock_start,
unsigned long & iterations, unsigned long timecheck) {
if (start <= end) return true;
std::vector<int> buf(arr);
sort(buf.begin() + start, buf.begin() + end);
for (int i = start; i < end; i++) {
if (++iterations > timecheck) {
iterations = 0;
clock_t clock_current = clock();
double time = (double)(clock_current - clock_start) * 1000.0 / CLOCKS_PER_SEC;
if (time > 60000) throw "This function takes too long!";
else std::cout << time << " ms elapsed..." << std::endl;
}
if (buf[i] == buf[i + 1]) return false;
}
return true;
}
unsigned long calculate_timecheck() {
// since we want to limit the functions to 60 seconds we need to check how
// long they have been running but we don't want to do that all the time
// so we should only check so often - here is an attemopt to figure out how often
unsigned long upperlimit = 1;
volatile unsigned long i;
clock_t start, current;
double time;
do {
if (upperlimit > ULONG_MAX/2) return ULONG_MAX-1;
upperlimit *= 2;
start = clock();
for (i = 0; i < upperlimit*100000; i++);
current = clock();
time = (double)(current - start) * 1000.0 / CLOCKS_PER_SEC;
std::cout << upperlimit*100000 << " iterations took " << time << " ms." << std::endl;
} while (time<500);
return upperlimit*100000;
}
int main() {
int max = 0;
std::cout << "Enter a number for the Max range: ";
std::cin >> max;
std::default_random_engine randGen(time(0));
std::uniform_int_distribution<int> randNum(0, max);
int n = randNum(randGen);
int m = n;
std::vector<int> myVect;
for (int i = 0; i <= m; i++) {
myVect.push_back(randNum(randGen));
//std::cout << myVect[i] << std::endl;
}
std::cout << "Calculating timeout... " << std::endl;
std::cout << std::endl;
unsigned long timecheck = calculate_timecheck();
std::cout << "Will check for timeout every " << timecheck << " iterations..." << std::endl;
std::cout << std::endl;
std::cout << "------------------------------------" << std::endl;
// recursive algorithm
try {
std::cout << "Recursive Algorithm Test... " << std::endl;
std::cout << std::endl;
clock_t start = clock();
unsigned long iterations = 0;
// isUnique(myVect, 0, n, start, iterations, timecheck);
if (isUnique(myVect, 0, n, start, iterations, timecheck) == true) {
std::cout << "The Vector is Unique! " << std::endl;
}
else {
std::cout << "The Vector is not Unique! " << std::endl;
}
clock_t end = clock();
double time = (double)(end - start) * 1000.0 / CLOCKS_PER_SEC;
std::cout << "CPU Time used for this algorithm: " << time << " ms." << std::endl;
} catch (const char *err) {
std::cout << err << std::endl;
}
std::cout << "------------------------------------" << std::endl;
// iterative algorithm
try {
std::cout << "Iterative Algorithm Test... " << std::endl;
std::cout << std::endl;
clock_t start = clock();
unsigned long iterations = 0;
// isUniqueLoop(myVect, 0, n, start, iterations, timecheck);
if (isUniqueLoop(myVect, 0, n, start, iterations, timecheck) == true) {
std::cout << "The Vector is Unique! " << std::endl;
}
else {
std::cout << "The Vector is not Unique! " << std::endl;
}
clock_t end = clock();
double time = (double)(end - start) * 1000.0 / CLOCKS_PER_SEC;
std::cout << "CPU time used for this algorithm: " << time << " ms." << std::endl;
} catch (const char *err) {
std::cout << err << std::endl;
}
std::cout << "------------------------------------" << std::endl;
// sort algorithm
try {
std::cout << "Sort Algorithm Test... " << std::endl;
std::cout << std::endl;
clock_t start = clock();
unsigned long iterations = 0;
// isUniqueSort(myVect, 0, n, start, iterations, timecheck);
if (isUniqueSort(myVect, 0, n, start, iterations, timecheck) == true) {
std::cout << "The Vector is Unique! " << std::endl;
}
else {
std::cout << "The Vector is not Unique " << std::endl;
}
clock_t end = clock();
double time = (double)(end - start) * 1000.0 / CLOCKS_PER_SEC;
std::cout << "CPU time used for this algorithm: " << time << " ms." << std::endl;
} catch (const char *err) {
std::cout << err << std::endl;
}
std::cout << std::endl;
system("pause");
return 0;
}
Original:
#include <iostream>
#include <vector>
#include <ctime>
#include <chrono>
#include <cstdlib>
#include <random>
#include <algorithm>
using namespace std;
bool isUnique(const vector<int>& arr, int start, int end, clock_t clock_start) {
clock_t clock_current = clock();
double time = (double)(clock_current - clock_start) / CLOCKS_PER_SEC * 1000.0;
if (time > 60000) throw "This function takes too long!";
if (start >= end) return true;
if (!isUnique(arr, start, end - 1, clock_start))
return false;
if (!isUnique(arr, start + 1, end, clock_start))
return false;
return (arr[start] != arr[end]);
}
bool isUniqueLoop(const vector<int>& arr, int start, int end, clock_t clock_start) {
if (start >= end) return true;
for (int i = start; i < end; i++) {
for (int j = i + 1; j <= end; j++) {
clock_t clock_current = clock();
double time = (double)(clock_current - clock_start) / CLOCKS_PER_SEC * 1000.0;
if (time > 60000) throw "This function takes too long!";
if (arr[i] == arr[j])return false;
}
}
return true;
}
bool isUniqueSort(const vector<int>& arr, int start, int end, clock_t clock_start) {
if (start <= end) return true;
vector<int> buf(arr);
sort(buf.begin() + start, buf.begin() + end);
for (int i = start; i < end; i++) {
clock_t clock_current = clock();
double time = (double)(clock_current - clock_start) / CLOCKS_PER_SEC * 1000.0;
if (time > 60000) throw "This function takes too long!";
if (buf[i] == buf[i + 1]) return false;
}
return true;
}
int main() {
int max = 0;
cout << "Enter a number for the Max range: ";
cin >> max;
default_random_engine randGen(time(0));
uniform_int_distribution<int> randNum(0, max);
int i;
int j;
int n = randNum(randGen);
int m = n;
vector<int> myVect;
for (i = 0; i <= m; i++) {
myVect.push_back(randNum(randGen));
//cout << myVect[i] << endl;
}
try {
cout << "Recursive Algorithm Test... " << endl;
cout << endl;
// recursive algorithm
clock_t start = clock();
isUnique(myVect, 0, n, start);
if (isUnique(myVect, 0, n, start) == true) {
cout << "The Vector is Unique! " << endl;
}
else {
cout << "The Vector is not Unique! " << endl;
}
clock_t end = clock();
double time = (double)(end - start) / CLOCKS_PER_SEC * 1000.0;
cout << "CPU Time used for this algorithm: " << time << " ms" << endl;
} catch (const char *err) {
cout << err << endl;
}
cout << "------------------------------------" << endl;
try {
cout << "Iterative Algorithm Test... " << endl;
cout << endl;
// iterative algorithm
clock_t start2 = clock();
isUniqueLoop(myVect, 0, n, start2);
if (isUniqueLoop(myVect, 0, n, start2) == true) {
cout << "The Vector is Unique! " << endl;
}
else {
cout << "The Vector is not Unique! " << endl;
}
clock_t end2 = clock();
double time2 = (double)(end2 - start2) / CLOCKS_PER_SEC * 1000.0;
cout << "CPU time used for this algorithm: " << time2 << " ms. " << endl;
} catch (const char *err) {
cout << err << endl;
}
cout << "------------------------------------" << endl;
try {
cout << "Sort Algorithm Test... " << endl;
cout << endl;
// sort algorithm
clock_t start3 = clock();
isUniqueSort(myVect, 0, n, start3);
if (isUniqueSort(myVect, 0, n, start3) == true) {
cout << "The Vector is Unique! " << endl;
}
else {
cout << "The Vector is not Unique " << endl;
}
clock_t end3 = clock();
double time3 = (double)(end3 - start3) / CLOCKS_PER_SEC * 1000.0;
cout << "CPU time used for this algorithm: " << time3 << " ms. " << endl;
} catch (const char *err) {
cout << err << endl;
}
cout << endl;
system("pause");
return 0;
}

Related

The function called by std::async is not executed immediately?

#include <iostream>
#include <future>
auto gClock = clock();
char threadPool(char c) {
std::cout << "enter thread :" << c << " cost time:" << clock() - gClock << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
for (int i = 0; i < 10; i++)
std::cout << c;
std::cout << std::endl;
return c;
}
void fnTestAsync(){
auto begin = clock();
std::future<char> futures[10];
for (int i = 0; i < 10; ++i){
futures[i] = std::async(std::launch::async,threadPool, 'a' + i);
}
for (int i = 0; i < 10; ++i){
std::cout << futures[i].get() << " back ,cost time: " << clock() - begin << std::endl;
}
std::cout << "fnTestAsync: " << clock() - begin << std::endl;
}
int main(){
std::thread testAsync(fnTestAsync);
testAsync.detach();
std::this_thread::sleep_for(std::chrono::seconds(10));
return 0;
}
run result
I'm trying to get these 10 threads to execute together and all return immediately after a two second delay, but I output the time spent and find that it takes about 2900ms, much larger than the 2000ms I expected.
What is the cause of this increase?
How should he fix it?

How to get the value of chrono c++?

I am trying to make a text game where there is a timer and once the game was finished before or in 60 seconds, there is a bonus points. However, I have no idea how can I get the value or the time from using the chrono without cout-ing it. I want to use the value for calculating the bonus point. i can cout the value through the .count() but I cannot get that value to use for the condition part.
here's my code for the scoring part:
void Game::score(auto start, auto end) {
int bonus = 0;
int total = 0;
string name;
box();
gotoxy(10,8); cout << "C O N G R A T U L A T I O N S";
gotoxy(15,10); cout << "You have successfully accomplished all the levels!";
gotoxy(15,11); cout << "You are now a certified C-O-N-N-E-C-T-o-r-I-s-T" << char(002) << char(001);
gotoxy(20,13); cout << "= = = = = = = = = = GAME STATS = = = = = = = = = =";
gotoxy(25,15); cout << "Time Taken: " << chrono::duration_cast<chrono::seconds>(end - start).count() << " seconds";
gotoxy(25,16); cout << "Points: " << pts << " points";
if (chrono::duration_cast<chrono::seconds>(end - start).count() <= 60) {
bonus == 5000;
} else if (chrono::duration_cast<chrono::seconds>(end - start).count() <= 90) {
bonus == 3000;
} else if (chrono::duration_cast<chrono::seconds>(end - start).count() <= 120) {
bonus == 1000;
}
gotoxy(30,17); cout << "Bonus Points (Time Elapsed): " << bonus;
total = pts + bonus;
gotoxy(25,18); cout << "Total Points: " << total << " points";
gotoxy(20,20); cout << "Enter your name: ";
cin >> name;
scoreB.open("scoreboard.txt",ios::app);
scoreB << name << "\t" << total << "\n";
scoreB.close();
}
You should really use the chrono literals for comparing durations. See example here:
#include <chrono>
#include <iostream>
#include <thread>
using Clock = std::chrono::system_clock;
void compareTimes(std::chrono::time_point<Clock> startTime,
std::chrono::time_point<Clock> finishTime) {
using namespace std::chrono_literals;
std::chrono::duration<float> elapsed = finishTime - startTime;
std::cout << "elapsed = " << elapsed.count() << "\n";
if (elapsed > 10ms) {
std::cout << "over 10ms\n";
}
if (elapsed < 60s) {
std::cout << "under 60s\n";
}
}
int main() {
using namespace std::chrono_literals;
auto startTime = Clock::now();
std::this_thread::sleep_for(20ms);
auto finishTime = Clock::now();
compareTimes(startTime, finishTime);
return 0;
}
Demo: https://godbolt.org/z/hqv58acoY

Issues with program to test Shell, Insertion, and Quick sorts

So, this program is supposed to test run insertion, shell, and quick sorts with 3 different text files of integers, but for some reason beyond my understanding, none of the results short of the number of items is being displayed. It is supposed to show the number of seconds and clock cycles it takes to run each sort using clock(). Please, can anyone tell me why it isn't working? I am stumped!
#include "targetver.h"
#include <time.h>
#include <stdio.h>
#include <dos.h>
#include <iomanip>
#include <fstream>
#include <string>
#include <stdio.h>
#include <tchar.h>
#include <queue>
#include <stack>
#include <vector>
#include<iostream>
#include<cstdio>
#include<sstream>
#include<algorithm>
using namespace std;
// insertion sort function
void insertionSort(vector<int> arr, int n)
{
int i, key, j;
for (i = 1; i < n; i++)
{
key = arr[i];
j = i - 1;
/* Move elements of arr[0..i-1], that are
greater than key, to one position ahead
of their current position */
while (j >= 0 && arr[j] > key)
{
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}
// shell sort function
void shellSort(vector<int> arr, int n)
{
// Start with a big gap, then reduce the gap
for (int gap = n / 2; gap > 0; gap /= 2)
{
// Do a gapped insertion sort for this gap size.
// The first gap elements a[0..gap-1] are already in gapped order
// keep adding one more element until the entire array is
// gap sorted
for (int i = gap; i < n; i += 1)
{
// add a[i] to the elements that have been gap sorted
// save a[i] in temp and make a hole at position i
int temp = arr[i];
// shift earlier gap-sorted elements up until the correct
// location for a[i] is found
int j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap)
arr[j] = arr[j - gap];
// put temp (the original a[i]) in its correct location
arr[j] = temp;
}
}
}
// function that swaps two elements
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
/* This function takes last element as pivot, places
the pivot element at its correct position in sorted
array, and places all smaller (smaller than pivot)
to left of pivot and all greater elements to right
of pivot */
int partition(vector<int> arr, int low, int high)
{
int pivot = arr[high]; // pivot
int i = (low - 1); // Index of smaller element
for (int j = low; j <= high - 1; j++)
{
// If current element is smaller than or
// equal to pivot
if (arr[j] <= pivot)
{
i++; // increment index of smaller element
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
/* The main function that implements QuickSort
arr --> Array to be sorted,
low --> Starting index,
high --> Ending index */
void quickSort(vector<int> arr, int low, int high)
{
if (low < high)
{
/* pi is partitioning index, arr[p] is now
at right place */
int pi = partition(arr, low, high);
// Separately sort elements before
// partition and after partition
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
// print array function
void printArray(vector<int> arr)
{
int z = arr.size();
int i;
for (i = 0; i < z; i++)
printf("%d ", arr[i]);
printf("n");
}
int main()
{
int max = 10000000;
vector<int> arr;
arr.reserve(max);
double start, end, elapsed_clock, elapsed_time;
int low, high, n;
string name;//holds first file name entered by user
ifstream fin;
cout << "Please enter the file name you wish to read from: ";//asks user for file name
getline(cin, name);//gets file name
fin.open(name);//opens file with set file name
if (fin.fail())//run if file name is incorrect or fails to load
{
cout << "Error opening " << name << "\n";//print error and file name
}
else
{
cout << "\nFile opened successfully, please wait." << endl;
// holds data read from file
int theData;
do // loop reads file till end
{
fin >> theData;
if (fin.good())
{
arr.push_back(theData);
}
//if read failed, check to see if file end was cause, otherwise print message and close
else if (!fin.eof())
{
cout << "\nThe file could not be read" << endl;
}
//runs while data being read
} while (!fin.eof());
}
fin.close();
n = sizeof(arr) / sizeof(arr[0]);
start = clock();
insertionSort(arr, n);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Insertion Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
start = clock();
shellSort(arr, n);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Shell Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
start = clock();
quickSort(arr, 0, n - 1);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Quick Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
printArray(arr);
cout << endl;//space
cout << "Please enter the file name you wish to read from: ";//asks user for file name
getline(cin, name);//gets file name
fin.open(name);//opens file with set file name
if (fin.fail())//run if file name is incorrect or fails to load
{
cout << "Error opening " << name << "\n";//print error and file name
}
else
{
cout << "\nFile opened successfully, please wait." << endl;
// holds data read from file
int theData;
do // loop reads file till end
{
fin >> theData;
if (fin.good())
{
arr.push_back(theData);
}
//if read failed, check to see if file end was cause, otherwise print message and close
else if (!fin.eof())
{
cout << "\nThe file could not be read" << endl;
}
//runs while data being read
} while (!fin.eof());
}
fin.close();
n = sizeof(arr) / sizeof(arr[0]);
start = clock();
insertionSort(arr, n);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Insertion Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
start = clock();
shellSort(arr, n);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Shell Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
start = clock();
quickSort(arr, 0, n - 1);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Quick Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
printArray(arr);
cout << endl;//space
cout << "Please enter the file name you wish to read from: ";//asks user for file name
getline(cin, name);//gets file name
fin.open(name);//opens file with set file name
if (fin.fail())//run if file name is incorrect or fails to load
{
cout << "Error opening " << name << "\n";//print error and file name
}
else
{
cout << "\nFile opened successfully, please wait." << endl;
// holds data read from file
int theData;
do // loop reads file till end
{
fin >> theData;
if (fin.good())
{
arr.push_back(theData);
}
//if read failed, check to see if file end was cause, otherwise print message and close
else if (!fin.eof())
{
cout << "\nThe file could not be read" << endl;
}
//runs while data being read
} while (!fin.eof());
}
fin.close();
n = sizeof(arr) / sizeof(arr[0]);
start = clock();
insertionSort(arr, n);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Insertion Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
start = clock();
shellSort(arr, n);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Shell Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
start = clock();
quickSort(arr, 0, n - 1);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Quick Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
printArray(arr);
cout << endl;//space
system("Pause");//waits for user input
return 0;
}
You should pass all vectors to function by reference, not by value.

Which are the best methods for speeding up the algorithm based on vector search?

I am trying to solve the Euler question 419
So far, I think I managed to build an algorithm to find the answer. Or at least it gives the correct result for first 40 step. But I need to compute 1,000,000,000,000th step. Solving first 40 step (with my algorithm) takes about 3-4 seconds. And bigger the iteration number increases, computation time increases as well. I don't think my computer can solve 1,000,000,000,000 iteration in a year.
What I do is simply using temporary vectors for both sequential number counting(form_1 and form_2) and keeping the calculated the result for each iteration(testVec). Here is my code below:
#include <iostream>
#include <stdio.h>
#include <vector>
#include <cmath>
std::vector<int> form_1;
std::vector<int> form_2;
std::vector<int> testVec;
void showVec(std::vector<int>& vec)
{
//
for (unsigned long int i = 0; i < vec.size(); i++)
{
//
std::cout << vec[i] << std::endl;
}
}
void resFin(int start, int stop, std::vector<int>& vec)
{
//
for (unsigned long int i = 0; i < vec.size(); i++)
{
//
if (i == 0)
{
//
form_1.push_back(vec[0]);
//std::cout << "form_1 pushed " << vec[0] << std::endl;
}
else
{
//
if (i != vec.size() - 1)
{
//
if (vec[i] == vec[i - 1])
{
//
form_1.push_back(vec[i]);
//std::cout << "form_1 pushed " << vec[i] << std::endl;
}
else
{
//
form_2.push_back(form_1.size());
form_2.push_back(vec[i - 1]);
form_1.clear();
form_1.push_back(vec[i]);
}
}
else
{
//
if (vec[i] == vec[i - 1])
{
//
form_1.push_back(vec[i]);
//std::cout << "form_1 pushed " << vec[i] << std::endl;
form_2.push_back(form_1.size());
//std::cout << "form_2 pushed " << form_1.size() << std::endl;
form_2.push_back(vec[i - 1]);
//std::cout << "form_2 pushed " << vec[i - 1] << std::endl;
form_1.clear();
}
else
{
//
form_2.push_back(form_1.size());
//std::cout << "form_2 pushed " << form_1.size() << std::endl;
form_2.push_back(vec[i - 1]);
//std::cout << "form_2 pushed " << vec[i - 1] << std::endl;
form_2.push_back(1);
//std::cout << "form_2 pushed " << 1 << std::endl;
form_2.push_back(vec[i]);
//std::cout << "form_2 pushed " << vec[i] << std::endl;
form_1.clear();
}
}
}
}
vec.clear();
for (unsigned long int k = 0; k < form_2.size(); k++)
{
//
vec.push_back(form_2[k]);
//std::cout << "vec pushed " << form_2[k] << std::endl;
}
//showVec(vec);
if (start + 1 != stop)
{
//
form_1.clear();
form_2.clear();
std::cout << "recursed to " << start + 1 << std::endl;
resFin(start + 1, stop, vec);
}
}
void stepFind(int stop, std::vector<int>& vec)
{
//
resFin(1, stop, vec);
}
void trimmVec(std::vector<int>& vec)
{
//
int a = 0;
int b = 0;
int c = 0;
for (unsigned long int i = 0; i < vec.size(); i ++)
{
//
switch (vec[i])
{
case 1:
a++;
a = a % 1073741824;
break;
case 2:
b++;
b = b % 1073741824;
break;
case 3:
c++;
c = c % 1073741824;
break;
default:
break;
}
}
std::cout << "a is " << a << "; b is " << b << "; c is " << c << std::endl;
}
int main()
{
//
testVec.push_back(1);
testVec.push_back(1);
stepFind(39, testVec);
//showVec(testVec);
trimmVec(testVec);
getchar();
return 0;
}
I think no one ought to wait more than a few hours to solve euler problems right? So I am doing something wrong here. So, are there such methods existed to minimize computing time, especially in vectors inside searching(I think this consumes the time most)?

C++ class and function output issue

I'm having problems with my program's output. It keeps spitting out 12345.
Here's the details:
It's split in three files: program8.cpp (the part that runs tests), myRandom.cpp (implementation of the class), and myRandom.h (specification of the class).
myRandom.h:
#ifndef MYRANDOM_H_
#define MYRANDOM_H_
class myRandom
{
public:
myRandom(); //Constructor
~myRandom(); //Destructor
void seed(unsigned long theSeed); //Mutator for current
unsigned long next(); //Mutator or Accessor for current
int randInt(int start, int end); //Scales result to a range
double randNormal(); //Future expansion
private:
unsigned long current; //Current random #
static const unsigned long a = 1103515245; //Multiplier for LGC
static const unsigned long c = 12345; //Increment for LGC
static const unsigned long m = 2147483648; //Modulus for LGC
};
#endif /* MYRANDOM_H_ */
myRandom.cpp:
#include <iostream>
#include <cstdlib>
#include "myRandom.h"
using namespace std;
myRandom::myRandom() //Constructor
{
current = 0;
}
myRandom::~myRandom() //Destructor
{
}
void myRandom::seed(unsigned long theSeed) //Mutator for current
{
if (theSeed < 0 || theSeed > m-1)
{
// ERROR
return;
}
else
current = theSeed;
}
unsigned long myRandom::next() //Mutator or Accessor for current
{
if (current < 0)
{
cout << "Error: cannot set seed to a negative number" << endl;
return 0;
}
else
{
current = (m*current+c)%m; //Formula
return current;
}
}
int myRandom::randInt(int start, int end) //Scales result to a range
{
if (start >= end)
{
cout << "Error: cannot set start greater than or equal to end" << endl;
return 0;
}
else
{
return ((this->next() % (end - start)) + start);
}
}
double myRandom::randNormal() //Future expansion
{
cout << "Warning: randNormal not implemented" << endl;
return 0;
}
program8.cpp:
#include <iostream>
#include <cstdlib>
#include "myRandom.h"
using namespace std;
int main()
{
myRandom theRand;
unsigned long theSeed;
cout << "Verify that the sequence generated by next() is the same on each run" << endl;
for (int i = 0; i < 5; i++)
{
cout << theRand.next() << endl;
}
cout << "Verify that you can set the seed to 0 and 1" << endl;
theSeed = 0;
cout << theRand.next() << endl;
theSeed = 1;
cout << theRand.next() << endl;
cout << "Verify that attempting to set the seed to -1 generates an error" << endl;
theSeed = -1;
cout << theRand.next() << endl;
cout << "Verify that you can set the seed to m-2 and m-1" << endl;
theSeed = 2147483648-2;
cout << theRand.next() << endl;
theSeed = 2147483648-1;
cout << theRand.next() << endl;
cout << "Verify that attempting to set the seed to m generates and error" << endl;
theSeed = 2147483648;
cout << theRand.next() << endl;
cout << "Verify that next() produces a sequence predicted by hand/calc for the chosen seed" << endl;
cout << "Please enter a seed: ";
cin >> theSeed;
cout << theRand.next() << endl;
cout << "Verify that using start == end generates and error. Set both to 10." << endl;
theRand.randInt(10,10);
cout << theRand.next() << endl;
cout << "Verify that using start > end generates and error. Set start to 10 and end to 5." << endl;
theRand.randInt(10,5);
cout << theRand.next() << endl;
theRand.seed(theSeed);
cout << "Testing randInt for start=0 end=1,000" << endl;
for (int i = 0; i < 5; i++)
{
cout << theRand.randInt(0 , 1000) << endl;
}
return 0;
}
I think the problem lies in the next() function, since that's what gets called all those times in program8.cpp cout statements. I could understand getting 12345 once, but it should be updated once that function runs successive times. I apologize if it's a dumb question. Thank you for your time and patience.
Your problem isn't a code specific one - it is Math-related from here:
current = (m*current+c)%m;
This always returns the value of c if c < m, otherwise (or more generally) it returns c % m. Why? From this theorem:
(m*n + a)%m = a
Example:
m = 10
n = 3
a = 7
(10*3 + 7)%10 = 7
See this for more:
http://en.wikipedia.org/wiki/Modulo_operation