我在网上搜索了一个差异算法,但没有一个做我想要的。这是一个短信比赛(如在手机中),我需要输入文本与主文本相比记录错误。我是C#的半新手,我得到了大部分的字符串函数,并且认为这不会是一个很难的问题,但是我只是无法绕过它。
我有一个包含2个富文本框(一个在另一个上面)和2个按钮的表单。顶部框是主文本(字符串),底部框是条目文本(字符串)。每位参赛者都会将文本发送到电子邮件帐户,从我们复制的电子邮件中将文本粘贴到条目RTB中并与主RTB进行比较。对于每个单个单词和单个空间计数作为要检查的事物。一句话,无论它有多少错误,仍然是1错误。并为每个错误添加1秒。他们的时间。
示例:
到目前为止我所拥有的: 我创建了6个数组(3个用于主数据,3个用于输入),它们是
我最大的麻烦是输入文字是错误的,它比主人更短或更长。我一直得到IndexOutOfRange异常(可以理解),但无法理解如何检查和编写代码来补偿。 我希望自己能够清楚地知道自己需要什么帮助。如果有人可以提供一些代码示例或某些东西来拍摄我正确的道路将是非常有帮助的。
答案 0 :(得分:2)
您是否研究过Levenshtein distance算法?它返回两个字符串之间的差异数,在您的情况下将是短信错误。基于维基百科页面上的伪代码实现算法会传递您的4个用例中的前3个:
Assert.AreEqual(2, LevenshteinDistance("Hello there!", "Helothere!");
Assert.AreEqual(1, LevenshteinDistance("Hello there!", "Hello there!!"));
Assert.AreEqual(4, LevenshteinDistance("Hello there! How are you?", "Helothere!! How a re you?"));
Assert.AreEqual(3, LevenshteinDistance("Hello there! How are you?", "Hello there!@ Ho are yu??")); //fails, returns 4 errors
所以虽然不是完美的开箱即用,但它可能是一个很好的起点。此外,如果您在实施评分规则时遇到太多麻烦,可能值得重新审视它们。
HTH
以下是您在评论中请求的字符串的结果:
Assert.AreEqual(7, LevenshteinDistance("Hello there! How are you?", "Hlothere!! Hw a reYou?"); //fails, returns 8 errors
这是我对Levenshtein距离算法的实现:
int LevenshteinDistance(string left, string right)
{
if (left == null || right == null)
{
return -1;
}
if (left.Length == 0)
{
return right.Length;
}
if (right.Length == 0)
{
return left.Length;
}
int[,] distance = new int[left.Length + 1, right.Length + 1];
for (int i = 0; i <= left.Length; i++)
{
distance[i, 0] = i;
}
for (int j = 0; j <= right.Length; j++)
{
distance[0, j] = j;
}
for (int i = 1; i <= left.Length; i++)
{
for (int j = 1; j <= right.Length; j++)
{
if (right[j - 1] == left[i - 1])
{
distance[i, j] = distance[i - 1, j - 1];
}
else
{
distance[i, j] = Min(distance[i - 1, j] + 1, //deletion
distance[i, j - 1] + 1, //insertion
distance[i - 1, j - 1] + 1); //substitution
}
}
}
return distance[left.Length, right.Length];
}
int Min(int val1, int val2, int val3)
{
return Math.Min(val1, Math.Min(val2, val3));
}
答案 1 :(得分:0)
一个简单的算法就是逐字检查。如果字母不同则增加错误数量。如果下一对字母匹配,那么它的切换字母就会继续。如果该混乱与下一个字母匹配,则为遗漏并相应地对待它。如果下一个字母与混乱的字母匹配,则插入并相应地处理它。这个人真的搞砸了并继续。
这不会得到所有东西,只需要做一些修改就可以变得全面。
伪代码的弱尝试: 编辑:新想法。看看评论。我不知道我的头顶上的字符串功能所以你必须弄清楚那个部分。对于那些重复很多的单词,算法有点失败......
string entry; //we'll pretend that this has stuff inside
string master; // this too...
string tempentry = entry; //stuff will be deleted so I need a copy to mess up
int e =0; //word index for entry
int m = 0; //word index for master
int errors = 0;
while(there are words in tempentry) //!tempentry.empty() ?
string mword = the next word in master;
m++;
int eplace = find mword in tempentry; //eplace is the index of where the mword starts in tempentry
if(eplace == -1) //word not there...
continue;
else
errors += m - e;
errors += find number of spaces before eplace
e = m // there is an error
tempentry = stripoff everything between the beginning and the next word// substring?
all words and spaces left in master are considered errors.
有一些边界检查错误需要在这里修复,但它是一个良好的开端。
答案 2 :(得分:0)
你需要提出一个适合你的评分系统。
我会在每个空格后制作一个单词数组。
etc.etc。匹配单词很难,使用规则引擎起作用更容易&#39;
答案 3 :(得分:0)
我曾经实现过一种算法(我现在找不到,我会在找到它时发布代码),它会查看目标字符串中的PAIRS总数。即“你好,世界!”会有11对,{“他”,“el”,“ll”,......,“ld”,“d!” }。
然后你在输入字符串上执行相同的操作,例如“Helo World”,所以你有{“他”,......,“ld”}。
然后,您可以将精度计算为正确对的函数(即目标对列表中的输入对),不正确的对(即目标对列表中不存在的输入对),与总数相比较目标对列表。超过足够长的句子,这个措施将非常<打击>准确公平。