package Test;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* @author: Inki
* @email: inki.yinji@qq.com
* @create: 2020 1113
* @last_modify: 2020 1113
*/
public class MyFind {
/**
* The array.
*/
private int[] arr;
/**
* The key.
*/
private int key;
/**
* The size of array.
*/
private int size;
/**
* The index of key.
*/
private int idx;
/**
* The type of find algorithm.
*/
private String type;
/**
* The Fibonacci list.
*/
private List fibonacciList;
/**
* The first constructor.
*
* @param arr: The given array.
* @param key: Your goal.
*/
public MyFind(int[] arr, int key) {
this(arr, key, "insert");
}//Of the first constructor.
/**
* The second constructor.
*
* @param arr: The given array.
* @param key: Your goal.
* @param type: The type of find algorithm.
*/
public MyFind(int[] arr, int key, String type) {
this.arr = arr;
this.key = key;
this.type = type;
this.initialize();
}//Of the second constructor.
/**
* The initialize.
*/
private void initialize() {
this.size = this.arr.length;
//If not find, index == 1.
this.idx = -1;
switch (this.type) {
case "insert":
this.insert();
break;
case "fibonacci":
this.fibonacci();
break;
}//Of switch
}//Of initialize
/**
* Insert value find.
*/
private void insert() {
int start = 0;
int end = this.size - 1;
int mid = this.getMid(start, end);
while (start <= end) {
// System.out.print(mid + " ");
if (this.arr[mid] == this.key) {
this.idx = mid;
break;
} else if (this.arr[mid] >this. key) {
end = mid - 1;
} else {
start = mid + 1;
}//Of if
mid = this.getMid(start, end);
}//Of while
}//Of insert
/**
* Get mid.
*
* @param start: The start index.
* @param end: The end index.
* @return: The mid.
*/
private int getMid(int start, int end) {
return start + (int)((this.key - this.arr[start]) / (this.arr[end] - this.arr[start] + 1e-6) * (end - start));
}//Of getMid
/**
* Fibonacci find.
*/
private void fibonacci() {
this.fibonacciList = new LinkedList<>();
this.fibonacciList.add(1);
this.fibonacciList.add(1);
int k = this.getK();
int start = 0;
int end = this.size - 1;
int[] temp = Arrays.copyOf(this.arr, this.fibonacciList.get(k));
for (int i = this.size; i < this.fibonacciList.get(k); i++) {
temp[i] = temp[end];
}//Of for i
while (start <= end) {
int mid = start + this.fibonacciList.get(k) - 1;
// System.out.print(mid + " ");
if (temp[mid] == this.key) {
this.idx = mid;
break;
} else if (temp[mid] > this.key) {
end = mid - 1;
k--;
} else {
start = mid + 1;
k -= 2;
}//Of if
}//Of while
if (this.idx >= this.size) {
this.idx = this.size - 1;
}//Of if
}//Of fibonacci
/**
* Get k.
* @return Index k.
*/
private int getK() {
int k = 0;
while (size > this.fibonacciList.get(k)) {
this.fibonacciList.add(this.fibonacciList.get(k) + this.fibonacciList.get(k + 1));
k++;
}//Of while
return k;
}//Of getFibonacciList
/**
* Get index.
* @return: The find index.
*/
public int getIdx() {
return this.idx;
}//Of getIdx
/**
* The main.
*/
public static void main(String[] args) {
int[] arr = {0, 3, 4, 7, 8, 10, 13, 14, 17, 18, 23, 27, 29, 31, 32, 33, 34,
35, 36, 37, 38, 39, 41, 48, 49, 51, 53, 57, 58, 59, 61, 64, 65, 66,
67, 68, 69, 70, 73, 76, 81, 83, 84, 85, 86, 88, 91, 93, 95, 96, 98};
for (int a: arr) {
MyFind test = new MyFind(arr, a, "fibonacci");
System.out.println(test.getIdx());
}//Of for a
}//Of main
}//Of class MyFind