BaezaYates 交集python和golang代码

简介:
复制代码
def bsearch(find, arr, low, high):
    while low <= high:
        mid = (low + high) >> 1
        if arr[mid] == find:
            return mid, True
        elif arr[mid] > find:
            high = mid - 1
        else:
            low = mid + 1
    return low, False


def BaezaYates_intersect_helper(A, B, left1, right1, left2, right2, result):
    if left1 > right1 or left2 > right2:
        return
    if right1-left1 > right2-left2:
        left1, left2 = left2, left1
        right1, right2 = right2, right1
        A, B = B, A
    mid = (left1 + right1) >> 1
    index,found = bsearch(A[mid], B, left2, right2)
    if found:
        result.append(A[mid])
        BaezaYates_intersect_helper(A, B, left1, mid-1, left2, index-1, result)
        BaezaYates_intersect_helper(A, B, mid+1, right1, index+1, right2, result)
    else:
        if A[mid] > B[right2]:
            BaezaYates_intersect_helper(A, B, left1, mid-1, left2, right2, result)
        elif A[mid] < B[left2]:
            BaezaYates_intersect_helper(A, B, mid+1, right1, left2, right2, result)
        else:
            BaezaYates_intersect_helper(A, B, left1, mid-1, left2, index-1, result)
            BaezaYates_intersect_helper(A, B, mid+1, right1, index, right2, result)


def BaezaYates_intersect(A, B):
    result = []
    BaezaYates_intersect_helper(A, B, 0, len(A)-1, 0, len(B)-1, result)
    result.sort()
    return result



from random import randint

if __name__ == "__main__":
    for i in range(2000):
        A = [randint(0, 100) for i in range(30)]
        B = [randint(0, 100) for i in range(30)]

        A.sort()
        B.sort()

        #print A
        #print B

        inter_set = BaezaYates_intersect(A, B)
        #print inter_set

        inter_set2 = set(A) & set(B)

        for data in inter_set:
            assert data in inter_set2
    print "tests passed..."
复制代码

 对应的go代码:

复制代码
package main

import (
    "fmt"
    "math/rand"
    "sort"
    "time"
)

func bsearch(find int, arr []int, low int, high int) (int, bool) {
    for low <= high {
        mid := (low + high) >> 1
        if arr[mid] == find {
            return mid, true
        } else if arr[mid] > find {
            high = mid - 1
        } else {
            low = mid + 1
        }
    }
    return low, false
}

func BaezaYatesIntersectHelper(A []int, B []int, left1 int, right1 int, left2 int, right2 int, result *[]int) {
    if left1 > right1 || left2 > right2 {
        return
    }
    if right1-left1 > right2-left2 {
        left1, left2 = left2, left1
        right1, right2 = right2, right1
        A, B = B, A
    }
    mid := (left1 + right1) >> 1
    index, found := bsearch(A[mid], B, left2, right2)
    /*
        if found {
            fmt.Printf("A[mid]=%d index=%d\n", A[mid], index)
        }
    */
    if found {
        *result = append(*result, A[mid])
        BaezaYatesIntersectHelper(A, B, left1, mid-1, left2, index-1, result)
        BaezaYatesIntersectHelper(A, B, mid+1, right1, index+1, right2, result)
    } else {
        if A[mid] > B[right2] {
            BaezaYatesIntersectHelper(A, B, left1, mid-1, left2, right2, result)
        } else if A[mid] < B[left2] {
            BaezaYatesIntersectHelper(A, B, mid+1, right1, left2, right2, result)
        } else {
            BaezaYatesIntersectHelper(A, B, left1, mid-1, left2, index-1, result)
            BaezaYatesIntersectHelper(A, B, mid+1, right1, index, right2, result)

        }
    }
}

func BaezaYatesIntersect(A, B []int) []int {
    result := []int{}
    BaezaYatesIntersectHelper(A, B, 0, len(A)-1, 0, len(B)-1, &result)
    sort.Ints(result)
    return result
}

func random(min, max int) int {
    return rand.Intn(max-min) + min
}

func main() {
    const SIZE int = 30
    for i := 0; i < 2000; i++ {
        A, B := [SIZE]int{}, [SIZE]int{}
        rand.Seed(time.Now().Unix())
        for j := 0; j < 30; j++ {
            A[j] = random(0, 100)
            B[j] = random(0, 100)
        }

        sort.Ints(A[:])
        sort.Ints(B[:])
        fmt.Println(A)
        fmt.Println(B)

        inter_set := BaezaYatesIntersect(A[:], B[:])
        fmt.Println(inter_set)
        /*
           inter_set2 = set(A) & set(B)

           for data in inter_set:
               assert data in inter_set2
        */
    }
    fmt.Printf("tests passed...\n")
}
复制代码

 牢记go语言中:

(1)要修改函数输入的slice参数,必须通过指针才能搞定,比如

func BaezaYatesIntersectHelper(A []int, B []int, left1 int, right1 int, left2 int, right2 int, result *[]int) 
最后一个参数!如果去掉指针,则无任何append效果!

(2)slice本质是array的内存引用!修改它必然会影响到array!因此,

sort.Ints(A[:]) 可以实现数组排序!





















本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/bonelee/p/6793788.html,如需转载请自行联系原作者



相关文章
|
9月前
|
存储 算法 调度
【复现】【遗传算法】考虑储能和可再生能源消纳责任制的售电公司购售电策略(Python代码实现)
【复现】【遗传算法】考虑储能和可再生能源消纳责任制的售电公司购售电策略(Python代码实现)
433 26
|
9月前
|
测试技术 开发者 Python
Python单元测试入门:3个核心断言方法,帮你快速定位代码bug
本文介绍Python单元测试基础,详解`unittest`框架中的三大核心断言方法:`assertEqual`验证值相等,`assertTrue`和`assertFalse`判断条件真假。通过实例演示其用法,帮助开发者自动化检测代码逻辑,提升测试效率与可靠性。
602 1
|
9月前
|
机器学习/深度学习 算法 调度
基于多动作深度强化学习的柔性车间调度研究(Python代码实现)
基于多动作深度强化学习的柔性车间调度研究(Python代码实现)
417 1
|
8月前
|
测试技术 Python
Python装饰器:为你的代码施展“魔法”
Python装饰器:为你的代码施展“魔法”
389 100
|
8月前
|
开发者 Python
Python列表推导式:一行代码的艺术与力量
Python列表推导式:一行代码的艺术与力量
587 95
|
9月前
|
Python
Python的简洁之道:5个让代码更优雅的技巧
Python的简洁之道:5个让代码更优雅的技巧
393 104
|
9月前
|
开发者 Python
Python神技:用列表推导式让你的代码更优雅
Python神技:用列表推导式让你的代码更优雅
683 99
|
9月前
|
IDE 开发工具 开发者
Python类型注解:提升代码可读性与健壮性
Python类型注解:提升代码可读性与健壮性
448 102
|
8月前
|
缓存 Python
Python装饰器:为你的代码施展“魔法
Python装饰器:为你的代码施展“魔法
494 88
|
8月前
|
监控 机器人 编译器
如何将python代码打包成exe文件---PyInstaller打包之神
PyInstaller可将Python程序打包为独立可执行文件,无需用户安装Python环境。它自动分析代码依赖,整合解释器、库及资源,支持一键生成exe,方便分发。使用pip安装后,通过简单命令即可完成打包,适合各类项目部署。
1459 68