首页 > golang > golang实现字符串相似度计算函数 Levenshtein和SimilarText
2021
02-04

golang实现字符串相似度计算函数 Levenshtein和SimilarText


levenshtein() 和 similar_text() 是 PHP 内置的两个字符串相似度计算函数。Levenshtein 计算两个字符串之间的编辑距离,SimilarText 计算两个字符串的相似度。下面使用Go分别实现二者。


Levenshtein

package main

import "fmt"

func main() {
   first := "【2023.02.06开年过渡周期樵夫点评】今日沪深两市成交量约8750亿,量能相比上周五小幅萎缩,缩减量能约400亿,显示市场交投情绪较为谨慎,增量资金进场积极性较差,市场正处于技术回踩蓄势节奏中。全天人工智能、东数西算、充电桩、信创等题材股表现较强,家电、多元金融、白酒、有色、证券、地产、半导体等传统蓝筹股小幅杀跌,整体赚钱效应较差,主要还是结构性题材个股轮动机会,不过天然气、环保、传媒、基建、港口等低估值行业股温和反弹较多,后市有望展开行情。对比外资来看,今日北上资金基本保持出入平衡,北上成交额约947亿,交投相比上周五还是比较稳定的,同时资金开始出现低吸回流,说明外资比较看好A股中长期机会。从技术分析来看,今日沪指继续低开低走,报收震荡小阴K,带下影线,说明盘中空头抛压还是比较强的,多头反击力量较弱,指数依然有向下回踩的可能,继续关注沪指3210点附近的支撑。好的方面是上证50指数回踩空间开始收敛,后续的空头发力空间有限,市场大概率做区间震荡反复整理。从券商的1小时调整中枢来看,目前尚未出现1小时的拐点信号,短期做多窗口还需要继续等候。樵夫提醒:当前大主力对低估值蓝筹股等核心资产压制较多,结构性题材股反而比较活跃,在经济低迷的复苏期,这是异常的,或是助攻主力全面吸筹布局,A股中长期的指数行情值得期待。"
   second := "市场正处于技术回踩蓄势节奏中。全天人工智能、东数西算、充电桩、股小幅杀跌,整体赚钱效应较差,主要还是结构性题材个股轮动机会,不过天然气、环保、传媒、基建、港口等低估值行业股温和反弹较多,后市有望展开行情。对比外资来看,今日北上资金基本保持出入平衡,北上成交额约947亿,交投相比上周五还是比较稳定的,同时资金开始出现低吸回流,说明外资比较看好A股中长期机会。从技术分析来看,今日沪指继续低开低走,报收震荡小阴K,带下影线,说明盘中空头抛压还是比较强的,多头反击力量较弱,指数依然有向下回踩的可能,继续关注沪指3210点附近的支撑。好的方面是上证50指数回踩空间开始收敛,后续的空头发力空间有限,市场大概率做区间震荡反复整理。从券商的1小时调整中枢来看,目前尚未出现1小时的拐点信号,短期做多窗口还需要继续等候。樵夫提醒:当前大主力对低估值蓝筹股等核心资产压制较多,结构性题材股反而比较活跃,在经济低迷的复苏期,这是异常的,或是助攻主力全面吸筹布局,A股中长期的指数行情值得期待。"
   percent := Levenshtein(first, second, 1, 2, 3)
   fmt.Println(percent)
}
func Levenshtein(str1, str2 string, costIns, costRep, costDel int) int {
   var maxLen = 255
   l1 := len(str1)
   l2 := len(str2)
   if l1 == 0 {
      return l2 * costIns
   }
   if l2 == 0 {
      return l1 * costDel
   }
   if l1 > maxLen || l2 > maxLen {
      return -1
   }

   tmp := make([]int, l2+1)
   p1 := make([]int, l2+1)
   p2 := make([]int, l2+1)
   var c0, c1, c2 int
   var i1, i2 int
   for i2 := 0; i2 <= l2; i2++ {
      p1[i2] = i2 * costIns
   }
   for i1 = 0; i1 < l1; i1++ {
      p2[0] = p1[0] + costDel
      for i2 = 0; i2 < l2; i2++ {
         if str1[i1] == str2[i2] {
            c0 = p1[i2]
         } else {
            c0 = p1[i2] + costRep
         }
         c1 = p1[i2+1] + costDel
         if c1 < c0 {
            c0 = c1
         }
         c2 = p2[i2] + costIns
         if c2 < c0 {
            c0 = c2
         }
         p2[i2+1] = c0
      }
      tmp = p1
      p1 = p2
      p2 = tmp
   }
   c0 = p1[l2]
   return c0
}


SimilarText

package main

import "fmt"

func main() {
   first := "【2023.02.06开年过渡周期樵夫点评】今日沪深两市成交量约8750亿,量能相比上周五小幅萎缩,缩减量能约400亿,显示市场交投情绪较为谨慎,增量资金进场积极性较差,市场正处于技术回踩蓄势节奏中。全天人工智能、东数西算、充电桩、信创等题材股表现较强,家电、多元金融、白酒、有色、证券、地产、半导体等传统蓝筹股小幅杀跌,整体赚钱效应较差,主要还是结构性题材个股轮动机会,不过天然气、环保、传媒、基建、港口等低估值行业股温和反弹较多,后市有望展开行情。对比外资来看,今日北上资金基本保持出入平衡,北上成交额约947亿,交投相比上周五还是比较稳定的,同时资金开始出现低吸回流,说明外资比较看好A股中长期机会。从技术分析来看,今日沪指继续低开低走,报收震荡小阴K,带下影线,说明盘中空头抛压还是比较强的,多头反击力量较弱,指数依然有向下回踩的可能,继续关注沪指3210点附近的支撑。好的方面是上证50指数回踩空间开始收敛,后续的空头发力空间有限,市场大概率做区间震荡反复整理。从券商的1小时调整中枢来看,目前尚未出现1小时的拐点信号,短期做多窗口还需要继续等候。樵夫提醒:当前大主力对低估值蓝筹股等核心资产压制较多,结构性题材股反而比较活跃,在经济低迷的复苏期,这是异常的,或是助攻主力全面吸筹布局,A股中长期的指数行情值得期待。"
   second := "市场正处于技术回踩蓄势节奏中。全天人工智能、东数西算、充电桩、股小幅杀跌,整体赚钱效应较差,主要还是结构性题材个股轮动机会,不过天然气、环保、传媒、基建、港口等低估值行业股温和反弹较多,后市有望展开行情。对比外资来看,今日北上资金基本保持出入平衡,北上成交额约947亿,交投相比上周五还是比较稳定的,同时资金开始出现低吸回流,说明外资比较看好A股中长期机会。从技术分析来看,今日沪指继续低开低走,报收震荡小阴K,带下影线,说明盘中空头抛压还是比较强的,多头反击力量较弱,指数依然有向下回踩的可能,继续关注沪指3210点附近的支撑。好的方面是上证50指数回踩空间开始收敛,后续的空头发力空间有限,市场大概率做区间震荡反复整理。从券商的1小时调整中枢来看,目前尚未出现1小时的拐点信号,短期做多窗口还需要继续等候。樵夫提醒:当前大主力对低估值蓝筹股等核心资产压制较多,结构性题材股反而比较活跃,在经济低迷的复苏期,这是异常的,或是助攻主力全面吸筹布局,A股中长期的指数行情值得期待。"
   percent := 0.0
   SimilarText(first, second, &percent)
   fmt.Println(percent)
}

// similar_text()
func SimilarText(first, second string, percent *float64) int {
   var similarText func(string, string, int, int) int
   similarText = func(str1, str2 string, len1, len2 int) int {
      var sum, max int
      pos1, pos2 := 0, 0

      // Find the longest segment of the same section in two strings
      for i := 0; i < len1; i++ {
         for j := 0; j < len2; j++ {
            for l := 0; (i+l < len1) && (j+l < len2) && (str1[i+l] == str2[j+l]); l++ {
               if l+1 > max {
                  max = l + 1
                  pos1 = i
                  pos2 = j
               }
            }
         }
      }

      if sum = max; sum > 0 {
         if pos1 > 0 && pos2 > 0 {
            sum += similarText(str1, str2, pos1, pos2)
         }
         if (pos1+max < len1) && (pos2+max < len2) {
            s1 := []byte(str1)
            s2 := []byte(str2)
            sum += similarText(string(s1[pos1+max:]), string(s2[pos2+max:]), len1-pos1-max, len2-pos2-max)
         }
      }

      return sum
   }

   l1, l2 := len(first), len(second)
   if l1+l2 == 0 {
      return 0
   }
   sim := similarText(first, second, l1, l2)
   if percent != nil {
      *percent = float64(sim*200) / float64(l1+l2)
   }
   return sim
}


本文》有 0 条评论

留下一个回复