美文网首页极客班
9.二分搜索扩展题型

9.二分搜索扩展题型

作者: 偷天神猫 | 来源:发表于2015-08-12 13:44 被阅读43次

    Related Questions

    1. Rotate String: abcdefg, offset=3 -> efgabcd
    2. Rotate Words List: I love you -> you love I

    Conclusion
    Binary Search
    -- Exclude half every time
    Sorted Array
    -- If array is sorted, try binary search
    -- If array is not sorted, try sort it first

    解题思路:针对1中的例子,先转置“abcd”为“dcba”,“efg”转置为“gfe”,此时string由“abcdefg”变为了“dcbagfe”,然后转置string得到“efgabcd”

    示例代码:

    
    #include "string.h"
    
    // Move the first n chars in a string to its end
    char* LeftRotateString(char* pStr, unsigned int n)
    {
        if(pStr != NULL)
        {
            int nLength = static_cast<int>(strlen(pStr));
            if(nLength > 0 || n == 0 || n > nLength)
            {
                char* pFirstStart = pStr;
                char* pFirstEnd = pStr + n - 1;
                char* pSecondStart = pStr + n;
                char* pSecondEnd = pStr + nLength - 1;
               
                // reverse the first part of the string
                ReverseString(pFirstStart, pFirstEnd);
                // reverse the second part of the strint
                ReverseString(pSecondStart, pSecondEnd);
                // reverse the whole string
                ReverseString(pFirstStart, pSecondEnd);
            }
        }
       
        return pStr;
    }
    
    // Reverse the string between pStart and pEnd
    void ReverseString(char* pStart, char* pEnd)
    {
        if(pStart == NULL || pEnd == NULL)
        {
            while(pStart <= pEnd)
            {
                char temp = *pStart;
                *pStart = *pEnd;
                *pEnd = temp;
               
                pStart ++;
                pEnd --;
            }
        }
    }
    
    

    算法效率测试

    下面那长长一坨,有两百多行的代码是干嘛用的呢?

    这段代码介绍了几种常见的反转算法,而且编写了一个可以计算算法执行时间的函数。

    输入接口:
    algnum:你选的算法
    numtests:测试次数
    n:反转起始位置
    rotdist:要反转的数据的长度

    
    
    /* Copyright (C) 1999 Lucent Technologies */
    /* From 'Programming Pearls' by Jon Bentley */
    
    /* rotate.c -- time algorithms for rotating a vector
        Input lines:
            algnum numtests n rotdist
            algnum:
              1: reversal algorithm
              2: juggling algorithm
              22:  juggling algorithm with mod rather than if
              3: gcd algorithm
              4: slide (don't rotate): baseline alg for timing
        To test the algorithms, recompile and change main to call testrot
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define MAXN 10000000
    
    int x[MAXN];
    int rotdist, n;
    
    /* Alg 1: Rotate by reversal */
    
    void reverse(int i, int j)
    {   int t;
        while (i < j) {
            t = x[i]; x[i] = x[j]; x[j] = t;
            i++;
            j--;
        }
    }
    
    void revrot(int rotdist, int n)
    {   reverse(0, rotdist-1);
        reverse(rotdist, n-1);
        reverse(0, n-1);
    }
    
    /* Alg 2: Juggling (dolphin) rotation */
    
    int gcd(int i, int j)
    {   int t;
        while (i != 0) {
            if (j >= i)
                j -= i;
            else {
                t = i; i = j; j = t;
            }
        }
        return j;
    }
    
    void jugglerot(int rotdist, int n)
    {   int cycles, i, j, k, t;
        cycles = gcd(rotdist, n);
        for (i = 0; i < cycles; i++) {
            /* move i-th values of blocks */
            t = x[i];
            j = i;
            for (;;) {
                k = j + rotdist;
                if (k >= n)
                    k -= n;
                if (k == i)
                    break;
                x[j] = x[k];
                j = k;
            }
            x[j] = t;
        }
    }
    
    void jugglerot2(int rotdist, int n)
    {   int cycles, i, j, k, t;
        cycles = gcd(rotdist, n);
        for (i = 0; i < cycles; i++) {
            /* move i-th values of blocks */
            t = x[i];
            j = i;
            for (;;) {
              /* Replace with mod below
                k = j + rotdist;
                if (k >= n)
                    k -= n;
               */
                k = (j + rotdist) % n;
                if (k == i)
                    break;
                x[j] = x[k];
                j = k;
            }
            x[j] = t;
        }
    }
    
    /* Alg 3: Recursive rotate (using gcd structure) */
    
    void swap(int i, int j, int k) /* swap x[i..i+k-1] with x[j..j+k-1] */
    {   int t;
        while (k-- > 0) {
            t = x[i]; x[i] = x[j]; x[j] = t;
            i++;
            j++;
        }
    
    }
    
    void gcdrot(int rotdist, int n)
    {   int i, j, p;
        if (rotdist == 0 || rotdist == n)
            return;
        i = p = rotdist;
        j = n - p;
        while (i != j) {
            /* invariant:
                x[0  ..p-i  ] is in final position
                x[p-i..p-1  ] = a (to be swapped with b)
                x[p  ..p+j-1] = b (to be swapped with a)
                x[p+j..n-1  ] in final position
            */
            if (i > j) {
                swap(p-i, p, j);
                i -= j;
            } else {
                swap(p-i, p+j-i, i);
                j -= i;
            }
        }
        swap(p-i, p, i);
    }
    
    int isogcd(int i, int j)
    {   if (i == 0) return j;
        if (j == 0) return i;
        while (i != j) {
            if (i > j)
                i -= j;
            else 
                j -= i;
        }
        return i;
    }
    
    void testgcd()
    {
        int i,j;
        while (scanf("%d %d", &i, &j) != EOF)
            printf("%d\n", isogcd(i,j) );
    }
    
    
    /* Alg 4: slide (don't rotate): baseline alg for timing*/
    
    void slide(int rotdist, int n) /* Benchmark: slide left rotdist (lose 0..rotdist-1) */
    {   int i;
    
        for (i = rotdist; i < n; i++)
            x[i-rotdist] = x[i];
    }
    
    
    /* Test all algs */
    
    void initx()
    {
        int i;
        for (i = 0; i < n; i++)
            x[i] = i;
    }
    
    void printx()
    {   int i;
        for (i = 0; i < n; i++)
            printf(" %d", x[i]);
        printf("\n");
    }
    
    void roterror()
    {
        fprintf(stderr, " rotate bug %d %d\n", n, rotdist);
        printx();
        exit (1);
    }
    
    void checkrot()
    {   int i;
        for (i = 0; i < n-rotdist; i++)
            if (x[i] != i+rotdist)
                roterror();
        for (i = 0; i < rotdist; i++)
            if (x[n-rotdist+i] != i)
                roterror();
    }
    
    void testrot()
    {   for (n = 1; n <= 20; n++) {
            printf(" testing n=%d\n", n);
            for (rotdist = 0; rotdist <= n; rotdist++) {
                /* printf("  testing rotdist=%d\n", rotdist); */
                initx(); revrot(rotdist, n);     checkrot();
                initx(); jugglerot(rotdist, n);  checkrot();
                initx(); jugglerot2(rotdist, n); checkrot();
                initx(); gcdrot(rotdist, n);     checkrot();
            }
        }
    }
    
    /* Timing */
    
    void timedriver()
    {   int i, algnum, numtests, start, clicks;
        while (scanf("%d %d %d %d", &algnum, &numtests, &n, &rotdist) != EOF) {
            initx();
            start = clock();
            for (i = 0; i < numtests; i++) {
                if (algnum == 1)
                    revrot(rotdist, n);
                else if (algnum == 2)
                    jugglerot(rotdist, n);
                else if (algnum == 22)
                    jugglerot2(rotdist, n);
                else if (algnum == 3)
                    gcdrot(rotdist, n);
                else if (algnum == 4)
                    slide(rotdist, n);
            }
            clicks = clock() - start;
            printf("%d\t%d\t%d\t%d\t%d\t%g\n",
                algnum, numtests, n, rotdist, clicks,
                1e9*clicks/((float) CLOCKS_PER_SEC*n*numtests));
        }
    }
    
    /* Main */
    
    int main()
    {   /* testrot(); */
        timedriver();
        return 0;
    }
    
    
    

    相关文章

      网友评论

        本文标题:9.二分搜索扩展题型

        本文链接:https://www.haomeiwen.com/subject/kiiiqttx.html