mirror of
https://hub.njuu.cf/TheAlgorithms/C-Plus-Plus.git
synced 2023-10-11 13:05:55 +08:00
randomized tests, documentation, back to vector
This commit is contained in:
parent
4b3749ed49
commit
8216a3267f
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user