TheAlgorithms-C-Plus-Plus/search/fibonacci_search.cpp

167 lines
3.9 KiB
C++
Raw Normal View History

2020-07-07 21:27:45 +08:00
/**
* Copyright 2020 @author sprintyaf
* @file
* @brief [Fibonacci search
* algorithm](https://en.wikipedia.org/wiki/Fibonacci_search_technique)
*/
2020-07-07 18:38:58 +08:00
#include <iostream>
2020-07-07 21:27:45 +08:00
#include <vector> // for std::vector class
#include <cassert> // for assert
2020-07-07 18:38:58 +08:00
2020-07-07 21:27:45 +08:00
/**
* Returns minimum of the two numbers
*/
2020-07-07 18:57:57 +08:00
int min(int first, int second){
2020-07-07 19:05:07 +08:00
if(first < second){
2020-07-07 18:57:57 +08:00
return first;
} else {
return second;
}
}
2020-07-07 21:27:45 +08:00
/**
2020-07-07 21:54:55 +08:00
* Input: a sorted array, a value we're looking for and size of the array
2020-07-07 21:27:45 +08:00
* Output: if the array contains the value, returns its index
* else returns -1
*/
2020-07-07 21:54:55 +08:00
int fibonacci_search(int *arr, int value, int length){
2020-07-07 18:38:58 +08:00
int last = 0, current = 1, offset = -1, index;
int next = last + current;
while(next < length){
last = current;
current = next;
next = last + current;
}
while(next > 1){
2020-07-07 18:57:57 +08:00
index = min(offset + last, length-1);
2020-07-07 18:38:58 +08:00
if(arr[index] < value){
next = current;
current = last;
last = next - current;
offset = index;
} else if(arr[index] > value){
next = last;
current = current - last;
last = next - current;
} else {
return index;
}
}
2020-07-07 21:54:55 +08:00
if(current && (length > 0) && arr[offset+1] == value){
2020-07-07 18:38:58 +08:00
return offset+1;
}
return -1;
}
2020-07-07 21:27:45 +08:00
/**
* Tests where given value occurs only once
*/
bool one_occurence_test(){
// declarations
2020-07-07 21:54:55 +08:00
int value, index, length;
2020-07-07 21:27:45 +08:00
bool passed = true;
// last element
2020-07-07 21:54:55 +08:00
length = 3;
int arr1[length] = {1, 2, 3};
2020-07-07 21:27:45 +08:00
value = 3;
2020-07-07 21:54:55 +08:00
index = fibonacci_search(arr1, value, length);
2020-07-07 21:27:45 +08:00
passed = passed && (index == 2);
// first element
value = 1;
2020-07-07 21:54:55 +08:00
index = fibonacci_search(arr1, value, length);
2020-07-07 21:27:45 +08:00
passed = passed && (index == 0);
// somewhere in the middle element
2020-07-07 21:54:55 +08:00
length = 4;
int arr2[length] = {1, 3, 5, 7};
2020-07-07 21:27:45 +08:00
value = 3;
2020-07-07 21:54:55 +08:00
index = fibonacci_search(arr2, value, length);
2020-07-07 21:27:45 +08:00
passed = passed && (index == 1);
// arr size is 1
2020-07-07 21:54:55 +08:00
length = 1;
int arr3[length] = {10};
2020-07-07 21:27:45 +08:00
value = 10;
2020-07-07 21:54:55 +08:00
index = fibonacci_search(arr3, value, length);
2020-07-07 21:27:45 +08:00
passed = passed && (index == 0);
2020-07-07 18:38:58 +08:00
2020-07-07 21:27:45 +08:00
return passed;
}
/**
* Tests where given value occurs more than once
*/
bool many_occurence_test(){
// declarations
2020-07-07 21:54:55 +08:00
int value, index, length;
2020-07-07 21:27:45 +08:00
bool passed = true;
// last element
2020-07-07 21:54:55 +08:00
length = 4;
int arr1[length] = {1, 1, 10, 10};
2020-07-07 21:27:45 +08:00
value = 10;
2020-07-07 21:54:55 +08:00
index = fibonacci_search(arr1, value, length);
2020-07-07 21:27:45 +08:00
passed = passed && (index == 2 || index == 3);
// first element
value = 1;
2020-07-07 21:54:55 +08:00
index = fibonacci_search(arr1, value, length);
2020-07-07 21:27:45 +08:00
passed = passed && (index == 0 || index == 1);
// somewhere in the middle element
2020-07-07 21:54:55 +08:00
length = 4;
int arr2[length] = {1, 3, 3, 7};
2020-07-07 21:27:45 +08:00
value = 3;
2020-07-07 21:54:55 +08:00
index = fibonacci_search(arr2, value, length);
2020-07-07 21:27:45 +08:00
passed = passed && (index == 1 || index == 2);
// all elements are the same
2020-07-07 21:54:55 +08:00
length = 3;
int arr3[length] = {10, 10, 10};
2020-07-07 21:27:45 +08:00
value = 10;
2020-07-07 21:54:55 +08:00
index = fibonacci_search(arr3, value, length);
2020-07-07 21:27:45 +08:00
passed = passed && (index >= 0 && index <= 2);
return passed;
}
/**
* Tests where the array doesn't contain given value
*/
bool no_occurence_test(){
// declarations
2020-07-07 21:54:55 +08:00
int value, index, length;
2020-07-07 21:27:45 +08:00
bool passed = true;
// many elements
2020-07-07 21:54:55 +08:00
length = 4;
int arr1[length] = {1, 2, 4, 5};
2020-07-07 21:27:45 +08:00
value = 3;
2020-07-07 21:54:55 +08:00
index = fibonacci_search(arr1, value, length);
2020-07-07 21:27:45 +08:00
passed = passed && (index == -1);
// one element
2020-07-07 21:54:55 +08:00
length = 1;
int arr2[length] = {1};
2020-07-07 21:27:45 +08:00
value = 2;
2020-07-07 21:54:55 +08:00
index = fibonacci_search(arr2, value, length);
2020-07-07 21:27:45 +08:00
passed = passed && (index == -1);
// empty array
2020-07-07 21:54:55 +08:00
length = 0;
int arr3[length];
2020-07-07 21:27:45 +08:00
value = 10;
2020-07-07 21:54:55 +08:00
index = fibonacci_search(arr3, value, length);
2020-07-07 21:27:45 +08:00
passed = passed && (index == -1);
return passed;
}
/**
* Main Function
* testing the algorithm
*/
int main() {
assert(one_occurence_test());
assert(many_occurence_test());
assert(no_occurence_test());
2020-07-07 18:38:58 +08:00
return 0;
}