C#中字符串的模糊匹配

liubococoa 2010-10-11 02:21:14
TextBox中输入以下内容:
北京市 朝阳区 朝阳门北大街 天辰大厦 东林花屋



想模糊匹配出数据库中已有的数据,比如:
北京 朝阳门北大街 东林花屋
北京市 朝阳区 天辰大厦 金枝名店
北京市 海淀区 知春路 天辰实业



请帮忙推荐一下这方面的文章,我在网上没搜明白。
...全文
2132 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
你是不是傻啊 2011-10-31
  • 打赏
  • 举报
回复
学习了!
pyjhlovemoon 2010-10-13
  • 打赏
  • 举报
回复
用我以前 用.net写一个
数据库函数
输入两个字符串A,B 返回 这两个字符串 的相近度
相近度就是把A串通过插入或删除两个操作变成B串 所需要的最短步与串长度的差

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlInt32 simil(string str1, string str2)
{
int len1 = str1.Length;
int len2 = str2.Length;
int lenLCS;
// unsigned *previous, *next;
if (len1 == 0 || len2 == 0)
return 0;
int[] previous = new int[len1 + 1];
int[] next = new int[len1 + 1];
int[] temp = new int[len1 + 1];
//next=(unsigned *)calloc( len1+1, sizeof(unsigned));
for (int j = 0; j < len2; ++j)
{
for (int k = 1; k <= len1; ++k)
if (str1[k - 1] == str2[j])
next[k] = previous[k - 1] + 1;
else next[k] = previous[k] >= next[k - 1] ? previous[k] : next[k - 1];
temp = next;
next = previous;
previous = temp;
//swap( &previous, &next);
}
lenLCS = previous[len1];


return new SqlInt32(lenLCS);
}
};



cjh200102 2010-10-13
  • 打赏
  • 举报
回复
学习了。
Sweet-Tang 2010-10-12
  • 打赏
  • 举报
回复
而且是用户自定义函数的速度会比系统提的函数慢很多
Sweet-Tang 2010-10-12
  • 打赏
  • 举报
回复
我建议用全文检索
这个数据快一些
还可以对每个关键字加权
绿色夹克衫 2010-10-12
  • 打赏
  • 举报
回复
自己弄确实比较麻烦,不过有些现成的,例如Lucense.net,像LS说的,用Sql Server的全文索引也可以,就是效果差点,做索引和搜索都比较慢(不过也有好多年没用了,不知道现在是否改进了)

[Quote=引用 8 楼 liubococoa 的回复:]

引用 6 楼 litaoye 的回复:
首先要有词库,才能对用户的输入做分词,同理,也需要对待搜索的数据做分词,并以分词做索引进行查询。

也就是说,这是一个很麻烦的事,对吗?
[/Quote]
源码小严 2010-10-12
  • 打赏
  • 举报
回复
用存储过程写吧!因为SQL里面不是有匹配函数!可以实现这样的的功能!我平时做都是这样的!希望我的回答,能够对你有帮助!谢谢
liubococoa 2010-10-12
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 litaoye 的回复:]
首先要有词库,才能对用户的输入做分词,同理,也需要对待搜索的数据做分词,并以分词做索引进行查询。
[/Quote]
也就是说,这是一个很麻烦的事,对吗?
wuyq11 2010-10-11
  • 打赏
  • 举报
回复
SQL全文检索
检索表中既包含b又包含c的所有行(注:列名不带引号)
select * from TableName where contains(列名(, 列名), 'b*' and 'c*')
检索表中包含a,b,c之一的所有列
select * from TableName where freetext(列名(, 列名), 'a b c')
绿色夹克衫 2010-10-11
  • 打赏
  • 举报
回复
首先要有词库,才能对用户的输入做分词,同理,也需要对待搜索的数据做分词,并以分词做索引进行查询。
liubococoa 2010-10-11
  • 打赏
  • 举报
回复
期待推荐文章
liubococoa 2010-10-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wuyazhe 的回复:]
select * from table wehere address like %北京市% or like %朝阳区% or like %朝阳门北大街% or like %天辰大厦% or like %东林花屋%

要我就这么写了。。。
[/Quote]

俺只是举一个例子,但TextBox中每次输入的内容都是不同的。
而且我举例子的内容中间的空格是为了让帮我解决问题的老大们看着方便,实际并不是每个词都如此。


所以,我的问题是:在TextBox中输入:北京市朝阳区朝阳门北大街天辰大厦东林花屋
会从数据库中查出很多条近似的信息,比如:
北京朝阳门北大街东林花屋
北京市朝阳区天辰大厦金枝名店
北京市海淀区知春路天辰实业
……

如果老大认为此问题比较乱,可以推荐些文章给我。
兔子-顾问 2010-10-11
  • 打赏
  • 举报
回复
select * from table wehere address like %北京市% or like %朝阳区% or like %朝阳门北大街% or like %天辰大厦% or like %东林花屋%

要我就这么写了。。。
兔子-顾问 2010-10-11
  • 打赏
  • 举报
回复
哦。数据库。听说数据库可以用正则或是like之类的
select * from table wehere address like %(北京市|朝阳区|朝阳门北大街|天辰大厦|东林花屋)%
这样?不懂数据库。1楼贴的看来用不上了。
兔子-顾问 2010-10-11
  • 打赏
  • 举报
回复
正则就算了。效率跟不上。我写了一个KMP算法改进版本,你看看能否用的上。

全文关键字检索-KMP改进算法
http://blog.csdn.net/wuyazhe/archive/2010/10/05/5922167.aspx
模糊字符串比对是一种在字符串不完全一致时进行比较的手段,广泛用于信息整理、数据处理、自动补全等场景。在Python,FuzzyWuzzy库是实现此类功能的典型工具,由Seat Geek公司开发。本文将介绍如何在C# .NET框架下复现该库的核心逻辑。FuzzyWuzzy主要依赖于Levenshtein距离,这是一种用于评估两个字符串之间差异程度的指标,其计算方式基于插入、删除或替换操作的最小次数。此外,该库还引入了Partial Ratio与Ratio两种衡量方式,分别用于评估子串匹配程度与整体匹配度。在C#实现类似功能,首先应构建一个核心类,例如`FuzzyMatcher`,并实现Levenshtein距离的计算逻辑。C#可通过递归或动态规划方式完成。以下为一种基于动态规划的Levenshtein距离计算示例: ```csharp public static int LevenshteinDistance(string s, string t) { int[,] dp = new int[s.Length + 1, t.Length + 1]; for (int i = 0; i <= s.Length; i++) dp[i, 0] = i; for (int j = 0; j <= t.Length; j++) dp[0, j] = j; for (int i = 1; i <= s.Length; i++) { for (int j = 1; j <= t.Length; j++) { if (s[i - 1] == t[j - 1]) dp[i, j] = dp[i - 1, j - 1]; else dp[i, j] = Math.Min(dp[i - 1, j - 1], Math.Min(dp[i, j - 1], dp[i - 1, j])) + 1; } } return dp[s.Length, t.Length]; } ``` 在该基础上,可进一步实现Partial Ratio和Ratio方法。Partial Ratio通过查找两个字符串之间的最长公共子序列长度,并与较短字符串长度进行比对。Ratio则通过计算Levenshtein距离并除以两字符串长度之和来评估匹配程度。 ```csharp public static double PartialRatio(string s, string t) { int maxLen = FindLongestCommonSubsequence(s, t); return (double)maxLen / Math.Min(s.Length, t.Length); } public static double Ratio(string s, string t) { int distance = LevenshteinDistance(s, t); return 1.0 - (double)distance / (s.Length + t.Length); } private static int FindLongestCommonSubsequence(string s, string t) { // 实现最长公共子序列查找逻辑 } ``` 为提升效率,可在C#利用缓存机制存储已计算的Levenshtein距离,减少重复计算。同时,可引入优化策略,如使用改进版的Wagner-Fischer算法。实际应用,`FuzzyMatcher`类可提供如`GetBestMatch`等方法,用于从字符串集合找出最匹配项,适用于用户输入建议、地址匹配等场景。将FuzzyWuzzy的核心算法移植至C# .NET环境,需准确理解并实现Levenshtein距离、Partial Ratio和Ratio等关键逻辑,并根据实际需求进行调整和优化。该过程有助于增强跨语言开发能力,并加深对字符串匹配算法的理解。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!

111,119

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧