2009-11-23 191 views
4

我需要按字比较两个字符串。 有点像差异,但对于文字而言,不适用于线条。逐字比较.NET中两个字符串的比较

就像是在维基百科 http://en.wikipedia.org/w/index.php?title=Horapollo&action=historysubmit&diff=21895647&oldid=21893459

在结果我想返回的话指数,这是两个不同的字符串的两个阵列完成。

是否有任何库/框架/ standalone_methods的.NET可以做到这一点?

P.S.我想比较几个千字节的文本

+0

重复http://stackoverflow.com/questions/473522/word-comparison-algorithm – 2009-11-23 22:20:38

+2

首先,将字符串分解为两个单词数组。然后找到两个数组中相同的字符串非常简单。如果你能做到这一点,那么当然你可以找到不同的单词。这是JScript中的一个简单示例;把它变成C#只需要几分钟。 http://beta.blogs.msdn.com/ericlippert/archive/2004/07/21/recursion-and-dynamic-programming.aspx – 2009-11-23 23:12:02

回答

3

看来我已经找到所需的解决方案:

DiffPlex是一个.NET版本比较图书馆既具有Silverlight和HTML差异阅读器的组合。 http://diffplex.codeplex.com/

但它有一个错误。在“Hello-Kitty”“Hello - Kitty”这两行中,单词“Hello”将被标记为差异。虽然区别是空间符号。

1

您可以使用唯一的数字替换2个文本中的所有单词,为编辑距离计算取一​​些现成的代码并将其字符替换为字符比较,完成了!

我不确定是否存在任何你想要的库。但是你肯定会找到很多编辑距离的代码。

此外,取决于您是否想要在编辑距离计算中实际允许替换,您可以更改动态编程代码中的条件。

看到这个。 http://en.wikipedia.org/wiki/Levenshtein_distance

+0

其实我已经写过比较例程,但我不喜欢它是如何工作的,因为新的错误不时出现,但我没有太多时间去争取,因为这是所有功能的和平。这就是为什么我一直在寻找已经经过良好测试的东西。它的风趣,但似乎这样的事情不存在:) – 2009-11-24 00:57:15

+0

@亚历克斯︰见我的回答上面:) – Pedery 2010-11-08 12:16:18

2

使用RegularExpressions使用/端口算法。

就像在例如:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 
using System.Collections.Specialized; 

namespace WindowsApplication10 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      decimal discrimation = 0.75M; 
      string formHeading = "The brown dog jumped over the red lazy river, and then took a little nap! Fun!"; 
      string userSearch = "The brown dog jumped over the red lazy river, and then took a little "; 
      //string userSearch = "brown dog nap fun"; 
      decimal res = CompareText(formHeading, userSearch); 

      if (res >= discrimation) 
      { 
       MessageBox.Show("MATCH!" + res.ToString()); 
      } 
      else 
      { 
       MessageBox.Show("does not match! " + res.ToString()); 
      } 
     } 


     /// <summary> 
     /// Returns a percentage of 1 on how many words were matched 
     /// </summary> 
     /// <returns></returns> 
     private decimal CompareText(string formHeading, string userSearch) 
     { 
      StringCollection formHeadingWords = new StringCollection(); 
      StringCollection userSearchWords = new StringCollection(); 
      formHeadingWords.AddRange(System.Text.RegularExpressions.Regex.Split(formHeading, @"\W")); 
      userSearchWords.AddRange(System.Text.RegularExpressions.Regex.Split(userSearch, @"\W")); 

      int wordsFound = 0; 
      for (int i1 = 0; i1 < userSearchWords.Count; i1++) 
      { 
       if (formHeadingWords.Contains(userSearchWords[i1])) 
        wordsFound += 1; 
      } 
      return (Convert.ToDecimal(wordsFound)/Convert.ToDecimal(formHeadingWords.Count)); 
     } 
    } 
} 
4

其实,你可能想实现的,我们在DNA sequence alignments使用局部对齐/全球校准算法的变化。这是因为你可能无法逐字比较两个字符串。即:

敏捷的棕色狐狸跳过 懒狗
快速狐狸跃过 懒狗

换句话说,如果你不能识别整个单词的插入和删除,你的比较算法可能变得非常sc(r)ewed。请看一下Smith-Waterman算法和Needleman-Wunsch算法,并找到一种方法使其适应您的需求。由于如果字符串很长,这样的搜索空间可能变得非常大,您还可以查看BLAST。BLAST是一种非常常见的启发式算法,几乎是基因搜索的标准。

+0

我没有得到,为什么我不能逐字比较两个字符串?我想要的就像你说的 - 识别整个单词的插入和删除。 – 2010-11-12 14:19:28

+0

因为如果逐字比较,您的比较算法可能会很快变得非常复杂。上面的例子是微不足道的,但说明了这一点我提出的序列算法被设计用于识别可比序列中的空位和插入。 PS:不要忘记奖励你认为有帮助的答案。毕竟,这就是这个社区如何保持活力。点击有用答案旁边的向上箭头图像。 – Pedery 2010-11-20 02:56:31