给出带有一些垃圾的字符串: “猫是黑的”; “猫是蓝色的”; “这只猫是白色的”; 黄狗不是猫“;
我们需要获得近似的字符串。在上面的例子中,所有引用cat的字符串都足以满足我们的商业案例,而最后一个字符串应该被丢弃。
我们认为将字符串中所有字符的十进制值相加,如果它们在给定范围内;说+/- 350,然后我们会说这个字符串是近似的。
还有其他方法吗?我们在Visual Studio中使用C#。
我见过Levenshtein的东西,但是想知道是否还有其他可能不那么科学的方法。
答案 0 :(得分:3)
这里有几个不是非常科学但相对简单的方法来说明两个字符串是多么相似,第一个只是看他们有多少常用字。
string[] words1 = inputString.Split(" ");
string[] words2 = otherInputString.Split(" ");
int diff = words1.Intersect(words2).Count();
从这里你可以做diff / words1.Count()
之类的事情以获得百分比差异。
另一种选择,因为所有'喜欢'字符串都有共同的子字符串,直到最后一个字(猫的颜色)将使用longestCommonSubstring.Length / inputString.Length
所以说它们是X%相似的。您可以使用类似的东西获得最长的公共子字符串;
public static string LongestCommonSubstring(List<string> strings)
{
var firstString = strings.FirstOrDefault();
var allSubstrings = new List<string>();
for(int substringLength = firstString.Length -1; substringLength >0; substringLength--)
{
for(int offset = 0; (substringLength + offset) < firstString.Length; offset++)
{
string currentSubstring = firstString.Substring(offset,substringLength);
if (!System.String.IsNullOrWhiteSpace(currentSubstring) && !allSubstrings.Contains(currentSubstring))
{
allSubstrings.Add(currentSubstring);
}
}
}
return allSubstrings.OrderBy(subStr => subStr.Length).FirstOrDefault();
}
你会这样称呼它;
string subString = LongestCommonSubString(new List<string> { inputstring, otherInputString } );
另一种选择是使用差异库。我过去曾使用过Googles diff-match-patch库,并对此感到满意。我不打算发布示例代码,因为我没有使用它的任何东西,但是如果你走这条路线,那么提供的例子就足够了。
答案 1 :(得分:2)
这是Levenshtein algorithm编写的C#,可能就是这个伎俩
答案 2 :(得分:1)
通过结合使用System.String类中的方法和巧妙使用正则表达式,我认为您可以实现这一点,而无需为您正在寻找的功能提供专门的库。
正则表达式运行得足够快,但如果你不小心(太多的字符串拆分等),String类中的方法会变得很快。
我不是正则表达式向导,但您可以根据接受的输入或预期输入按需建立正则表达式(在运行时),并使用它们来检测近似值。
答案 3 :(得分:1)
为什么重新发明轮子。是否有任何理由“soundex”算法无法满足您的需求。您可以找到几个可满足您需求的现有实现。
答案 4 :(得分:1)
最终,我们最终对Soundex示例代码与我们构建的字典以及在pastebin中找到的tinstaafl示例进行了大量比较。
然后,我们必须构建一个额外的规则集,循环遍历所有异常以提高我们的赔率。两项计算都没有正确完成。
我们曾考虑通过语音转换器运行所有内容并返回 - 只是因为客户希望看到可能发生的事情;但是,我们谈论了它们。