我正在尝试将我的理解中的java代码用于斐波那契搜索 http://en.wikipedia.org/wiki/Fibonacci_search:
设k被定义为F中的一个元素,即Fibonacci数的数组。 n = Fm是数组大小。如果数组大小不是Fibonacci数,则让Fm为F中最小的数,大于n。
斐波纳契数的数组定义为Fk + 2 = Fk + 1 + Fk,当k≥0,F1 = 1,F0 = 0时。
要测试某个项目是否在有序数字列表中,请按以下步骤操作:
设定k = m。 如果k = 0,则停止。没有比赛;该项目不在数组中。 将项目与Fk-1中的元素进行比较。 如果项目匹配,请停止。 如果项目小于条目Fk-1,则丢弃从位置Fk-1 + 1到n的元素。设置k = k - 1并返回步骤2。 如果项目大于条目Fk-1,则丢弃从位置1到Fk-1的元素。将剩余的元素从1重新编号为Fk-2,设置k = k - 2,然后返回步骤2.
以下是我的代码:
package com.search.demo;
public class FibonacciSearch {
static int[] a = {10,20,30,40,50,60,70,80,90,100};
static int required = 70;
static int m = 2;
static int p = 0;
static int q = 0;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
FibonacciSearch fs = new FibonacciSearch();
fs.findm();
fibSearch(required);
}
private void findm(){
//here you have to find Fm which matches size of searching array, or which is close to it.
int n = a.length;
int fibCurrent = 1;
int fibPrev1 = 1;
int fibPrev2 = 0;
while(n > fibCurrent){
fibPrev2 = fibPrev1;
fibPrev1 = fibCurrent;
fibCurrent = fibPrev1 + fibPrev2;
m++;
}
p = m-1;
q = m-2;
}
public static int fibSearch(int no){
for(;;){
if(m == 0){
System.out.println("not found");
return -1;
}
int j = f(p);
if(no == a[j]){
System.out.println("found at "+p);
}else if(no < a[j]){
m = p;
p = m - 1;
q = m - 2;
}else if(no > a[j]){
m = q; // as per the step 6..
p = m-1;
q = m-2;
}
}
//return m;
}
public static int f(int val){
if(val == 2 || val == 1 || val == 0){
return 1;
}
return (f(val-1) + f(val-2));
}
}
请纠正我的错误,并帮助我清楚地理解它。
我看过这个Fibonacci Search和http://www.cs.utsa.edu/~wagner/CS3343/binsearch/searches.html,但我无法理解..
答案 0 :(得分:0)
while(n > fibCurrent){
fibPrev2 = fibPrev1;
fibPrev1 = fibCurrent;
fibCurrent = fibPrev1 + fibPrev2;
m++;
}
findm()函数中的这一部分实际上是在比较第n个斐波纳契数,但根据算法,它应该是斐波那契数的累积和。 相反,你可以在findm的while循环中搜索元素。
答案 1 :(得分:0)
最后,我能够解决这个谜题,这阻止了我......
我认为以下代码可以帮助那些像我一样陷入困境的人。
package com.search.demo;
public class FibonacciSearch {
int a[] = {10,20,30,40,50,60,70,80,90,100};
static FibonacciSearch fs;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
fs = new FibonacciSearch();
int location = fs.find(70);
if(location < 0){
System.out.println("number not found..");
}else{
System.out.println("found at location "+location);
}
}
private int find(int no){
int n = a.length;
int m = findFm(n); //m = Fm iff n is Fibonacci number else returns Fm+1
int p = fibSequenceIterative(m-1); //p = Fm-1, always a fibonacci number
int q = fibSequenceIterative(m -2); //q = Fm-2, always a fibonacci number
while(true){
if(no == a[m]){
return m;
}else if (no < a[m]){
if(q == 0){
return -(m - 1);// we crossed 0th index in array, number not found.
}
m = m - q; //moved to 1 step left towards a fibonacci num
int tmp = p;//hold this temporarily
p = q; //move p to 1 step left into another fibonacci num
q = tmp - q;//moved q to 1 step left....
}else if(no > a[m]){
if(p == 1){
return -m;//we reached 0th index in array again and number not found..
}
m = m + q;
p = p - q;
q = q - p;
}
}
}
private int findFm(int n){
int prev = 1;
int curr = 1;
int next = 0;
if(n == 0){
next = 0;
return -1;
}else if(n == 1 || n == 2){
next = 1;
return 1;
}else{
for(int i = 3; ; i++){
next = prev + curr;
prev = curr;
curr = next;
System.out.println("prev = "+prev+" curr = "+curr+" next = "+next);
if(n <= curr){
System.out.println("n = "+n+" curr = "+curr);
return i;
}
}
//return -1;//we should not get here..
}
}
/* Iterative method for printing Fibonacci sequence..*/
private int fibSequenceIterative(int n){
int prev = 1;
int curr = 1;
int next = 0;
if(n == 0){
next = 0;
//return 0;
}else if(n == 1 || n == 2){
next = 1;
//return 1;
}else{
for(int i = 3; i <= n; i++){
next = prev + curr;
prev = curr;
curr = next;
}
return next;
}
return next;
}
}
我所做错的代码是管理索引,它确实会影响在索引位置分割数组的位置。
应首先找到m,匹配n(数组大小)的值。如果它不匹配,它应该是F(x)将>的下一个值。 ñ。也就是说,在我的情况下,大小是10,它与任何斐波那契数不匹配,因此斐波那契数列中的下一个值是13.而我们的条件满足的i的索引是F(7)= 13,这是&GT; 10.所以m = 7
现在p和q是2个连续的斐波那契数,它们总是决定分割数组的间隔。
阅读以下内容:
取N = 54,使N + 1 = 55 = F [10]。我们将搜索排序的数组:A [1],...,A [54],包括在内。数组索引严格地在两个Fibonacci数之间:0&lt; 55.这次搜索不使用中点,而是使用从F [10] = 55下来的下一个斐波那契数,即F [9] = 34.而不是将搜索区间分为两个,每边50%,我们粗略划分黄金比例,左边约62%,右边约38%。如果y == A [34],那么我们就找到了它。否则我们有两个较小的间隔来搜索:0到34和34到55,不包括端点。如果你有两个连续的Fibonacci数,那么使用减法很容易向后行进,所以在上面,从34回来的下一个数字是55 - 34 = 21.我们将分解0到34,中间有21 。使用下一个斐波纳契数下降34到55的范围:34 - 21 = 13.整个区间[34,55]的长度为21,我们从开始经过13到34 + 13 = 47。这不是斐波纳契数 - 它是所有区间的长度。(从http://www.cs.utsa.edu/~wagner/CS3343/binsearch/fibsearch.html复制)