randomized tests, documentation, back to vector

This commit is contained in:
sprintyaf 2020-07-07 20:38:40 +04:00
parent 4b3749ed49
commit 8216a3267f

View File

@ -1,6 +1,6 @@
/** /**
* Copyright 2020 @author sprintyaf * Copyright 2020 @author sprintyaf
* @file * @file fibonacci_search.cpp
* @brief [Fibonacci search * @brief [Fibonacci search
* algorithm](https://en.wikipedia.org/wiki/Fibonacci_search_technique) * algorithm](https://en.wikipedia.org/wiki/Fibonacci_search_technique)
*/ */
@ -8,27 +8,21 @@
#include <iostream> #include <iostream>
#include <vector> // for std::vector class #include <vector> // for std::vector class
#include <cassert> // for assert #include <cassert> // for assert
#include <cstdlib> // for random numbers
#include <algorithm> // for sorting
/** /**
* Returns minimum of the two numbers * @brief using fibonacci search algorithm finds an index of a given element in a sorted array
*
* @param arr sorted array
* @param value value that we're looking for
* @returns if the array contains the value, returns an index of the element. otherwise -1.
*/ */
int min(int first, int second){ int fibonacci_search(const std::vector<int> &arr, int value){
if(first < second){
return first;
} else {
return second;
}
}
/**
* Input: a sorted array, a value we're looking for and size of the array
* Output: if the array contains the value, returns its index
* else returns -1
*/
int fibonacci_search(int *arr, int value, int length){
int last = 0, current = 1, offset = -1, index; int last = 0, current = 1, offset = -1, index;
int length = arr.size();
int next = last + current; int next = last + current;
while(next < length){ while(next < length){
@ -38,7 +32,7 @@ int fibonacci_search(int *arr, int value, int length){
} }
while(next > 1){ while(next > 1){
index = min(offset + last, length-1); index = std::min(offset + last, length-1);
if(arr[index] < value){ if(arr[index] < value){
next = current; next = current;
current = last; current = last;
@ -52,115 +46,68 @@ int fibonacci_search(int *arr, int value, int length){
return index; return index;
} }
} }
if(current && (length > 0) && arr[offset+1] == value){ if(current && !arr.empty() && arr[offset+1] == value){
return offset+1; return offset+1;
} }
return -1; return -1;
} }
/** /**
* Tests where given value occurs only once * @brief random tests for checking performance when an array doesn't contain an element
*/ */
bool one_occurence_test(){ bool no_occurence_tests(){
// declarations
int value, index, length;
bool passed = true; bool passed = true;
// last element int rand_num, rand_value, index, num_tests = 1000;
length = 3; std::vector<int> arr;
int arr1[3] = {1, 2, 3}; while(num_tests--){
value = 3; arr.clear();
index = fibonacci_search(arr1, value, length); for(int i = 0; i < 100; i++){
passed = passed && (index == 2); rand_num = rand() % 1000;
// first element arr.push_back(rand_num);
value = 1; }
index = fibonacci_search(arr1, value, length); rand_value = rand() % 1000;
passed = passed && (index == 0); while(std::find(arr.begin(), arr.end(), rand_value) != arr.end()){
// somewhere in the middle element std::remove(arr.begin(), arr.end(), rand_value);
length = 4; }
int arr2[4] = {1, 3, 5, 7}; sort(arr.begin(), arr.end());
value = 3; index = fibonacci_search(arr, rand_value);
index = fibonacci_search(arr2, value, length); passed = passed && (index == -1);
passed = passed && (index == 1); }
// arr size is 1
length = 1;
int arr3[1] = {10};
value = 10;
index = fibonacci_search(arr3, value, length);
passed = passed && (index == 0);
return passed; return passed;
} }
/** /**
* Tests where given value occurs more than once * @brief random tests which cover cases when we have one, multiple or zero occurences of the value we're looking for
*/ */
bool many_occurence_test(){ bool random_tests(){
// declarations
int value, index, length;
bool passed = true; bool passed = true;
// last element int rand_num, rand_value, index, real_value, num_tests = 10000;
length = 4; std::vector<int> arr;
int arr1[4] = {1, 1, 10, 10}; while(num_tests--){
value = 10; arr.clear();
index = fibonacci_search(arr1, value, length); for(int i = 0; i < 100; i++){
passed = passed && (index == 2 || index == 3); rand_num = rand() % 1000;
// first element arr.push_back(rand_num);
value = 1; }
index = fibonacci_search(arr1, value, length); rand_value = rand() % 1000;
passed = passed && (index == 0 || index == 1); sort(arr.begin(), arr.end());
// somewhere in the middle element index = fibonacci_search(arr, rand_value);
length = 4; if(index != -1){
int arr2[4] = {1, 3, 3, 7}; real_value = arr[index];
value = 3; passed = passed && (real_value == rand_value);
index = fibonacci_search(arr2, value, length); } else {
passed = passed && (index == 1 || index == 2); passed = passed && (std::find(arr.begin(), arr.end(), rand_value) == arr.end());
// all elements are the same }
length = 3; }
int arr3[3] = {10, 10, 10};
value = 10;
index = fibonacci_search(arr3, value, length);
passed = passed && (index >= 0 && index <= 2);
return passed; return passed;
} }
/**
* Tests where the array doesn't contain given value
*/
bool no_occurence_test(){
// declarations
int value, index, length;
bool passed = true;
// many elements
length = 4;
int arr1[4] = {1, 2, 4, 5};
value = 3;
index = fibonacci_search(arr1, value, length);
passed = passed && (index == -1);
// one element
length = 1;
int arr2[1] = {1};
value = 2;
index = fibonacci_search(arr2, value, length);
passed = passed && (index == -1);
// empty array
length = 0;
int arr3[10] = {};
value = 10;
index = fibonacci_search(arr3, value, length);
passed = passed && (index == -1);
return passed;
}
/** /**
* Main Function * Main Function
* testing the algorithm * testing the algorithm
*/ */
int main() { int main() {
assert(one_occurence_test()); assert(no_occurence_tests());
assert(many_occurence_test()); assert(random_tests());
assert(no_occurence_test());
return 0; return 0;
} }