【代码模板】simHash算法文本查重(golang代码实现)

ps:

  • 供自己以后参考以及供了解simhash算法的人看
  • 本代码针对通用文本查重,故所有分词的权重均为1
  • 由于没有安装分词器,所以目前只能对英文句子进行相似度检测
  • 代码只提供一个大致思路,没有做进一步优化
package main

import (
	"fmt"
	"strings"
)

func main() {
	fmt.Println(hemingwayDistance(simHash("rng tes jdg edg"), simHash("rng edg tes jdg")))
	fmt.Println(hemingwayDistance(simHash("gen.g t1 dk drx"), simHash("rng edg tes jdg")))
	fmt.Println(hemingwayDistance(simHash("wo zhen de hui xie"), simHash("ting wo shuo xie xie ni")))
	fmt.Println(hemingwayDistance(simHash("wo zhen de hui xie"), simHash("wo shi zhen de xie xie ni")))
}

//计算simHash值
func simHash(statement string) int {
	words := strings.Split(statement, " ")
	bitCount := make([]int, 32)
	for _, word := range words {
		h := stringHash(word)
		for i := 0; i < 32; i++ {
			if h%2 == 1 {
				bitCount[i]++
			} else {
				bitCount[i]--
			}
			h /= 2
		}
	}
	ans := 0
	x := 1
	for i := 0; i < 32; i++ {
		if bitCount[i] > 0 {
			ans += x
		}
		x *= 2
	}
	return ans
}

//计算普通的字符串hash值
func stringHash(str string) int {
	h := 0
	bytes := []byte(str)
	for i := 0; i < len(bytes); i++ {
		h = 31*h + (int(bytes[i]) & 0xff)
	}
	return h
}

//计算海明威距离
func hemingwayDistance(a, b int) int {
	count := 0
	for i := 0; i < 32; i++ {
		if a%2 != b%2 {
			count++
		}
		a /= 2
		b /= 2
	}
	return count
}

输出:

0
5 
6 
1 

ps.一般<=3就认为比较相似,海明威距离值越大说明相差越多。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用golang的hash/crc32包来计算simhash算法中的哈希值,具体实现可以参考以下代码: ``` package simhash import ( "bytes" "hash/crc32" ) // Simhash represents a 64-bit hash value type Simhash uint64 // NewSimhash calculates the simhash of the given data func NewSimhash(data []byte) Simhash { // Step 1: tokenize data into shingles shingles := tokenize(data) // Step 2: compute the weighted frequency counts of shingles counts := countShingles(shingles) // Step 3: create the simhash var simhash Simhash for shingle, weight := range counts { hash := crc32.ChecksumIEEE([]byte(shingle)) for i := 0; i < 32; i++ { if hash&(1<<uint(i)) != 0 { simhash += Simhash(weight) } else { simhash -= Simhash(weight) } } } return simhash } // tokenize splits the given data into shingles func tokenize(data []byte) []string { shingles := make([]string, 0) var buffer bytes.Buffer for i := 0; i < len(data); i++ { if data[i] == ' ' { shingles = append(shingles, buffer.String()) buffer.Reset() continue } buffer.WriteByte(data[i]) } if buffer.Len() > 0 { shingles = append(shingles, buffer.String()) } return shingles } // countShingles computes the weighted frequency counts of the given shingles func countShingles(shingles []string) map[string]int { counts := make(map[string]int) for _, shingle := range shingles { counts[shingle]++ } return counts } ``` 这段代码实现simhash算法的三个步骤:将输入数据分割为shingles,计算shingles的加权频率,以及计算simhash值。其中,crc32包用于计算哈希值,bytes包用于处理字符串。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值