簡體   English   中英

在斐波那契搜索算法中需要幫助

[英]Need help in fibonacci search algorithm

我正在嘗試通過http://en.wikipedia.org/wiki/Fibonacci_search獲得的理解來放入Java代碼進行斐波那契搜索:

令k定義為F(斐波納契數)的數組中的元素。 n = Fm是數組大小。 如果數組大小不是斐波那契數,則讓Fm為F中大於n的最小數。

當k≥0,F1 = 1和F0 = 0時,定義斐波納契數的數組,其中Fk + 2 = Fk + 1 + Fk。

要測試某項是否在訂購號列表中,請按照下列步驟操作:

設置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));
}


}

請糾正我在做什么錯,並幫助我清楚地理解它。

我看過這個斐波那契搜索http://www.cs.utsa.edu/~wagner/CS3343/binsearch/searches.html,但我聽不懂。

while(n > fibCurrent){
                      fibPrev2 = fibPrev1;
                      fibPrev1 = fibCurrent;
                      fibCurrent = fibPrev1 + fibPrev2;
                      m++;
                    }

findm()函數中的該部分實際上是在比較第n個斐波那契數,但根據算法,它應該是直到那個點為止的斐波那契數的累積和。 而是可以在findm的while循環中搜索元素。

終於,我能夠解決這個難題,這讓我停了下來。

我認為以下代碼應該可以幫助像我一樣受困的人。

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)> nie的下一個值,在我的情況下,大小是10,它與任何斐波那契數都不匹配,因此斐波那契數列的下一個值是13 ,並且滿足我們的條件的i的索引為F(7)= 13,即>10。因此m = 7

現在p和q是2個連續的斐波那契數,它們始終確定划分數組的間隔。

閱讀以下內容:

取N = 54,使N + 1 = 55 = F [10]。 我們將搜索排序后的數組:A [1],...,A [54](含)。 數組索引嚴格位於兩個斐波那契數之間:0 <55。該搜索使用從F [10] = 55向下的下一個斐波那契數,而不是中點,即F [9] =34。而不是划分搜索間隔一分為二,兩邊各占50%,我們用黃金分割率大致相除,左邊約62%,右邊約38%。 如果y == A [34],那么我們找到了它。 否則,我們有兩個較小的搜索間隔:0到34和34到55,不包括端點。 如果您有兩個連續的斐波那契數,則很容易通過減法向后移動,因此在上面,從34返回的下一個數是55-34 =21。我們將中間的21分解為0到34。 使用下一個下一個斐波那契數向下破壞從34到55的范圍:34-21 =13。整個區間[34,55]的長度為21,我們從起點經過13,直到34 + 13 =47。請注意這不是斐波那契數-而是所有間隔的長度。(從http://www.cs.utsa.edu/~wagner/CS3343/binsearch/fibsearch.html復制)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM