我在上一个问题的答案中发现了一个错误。我想知道是否有人可以帮忙修复它。
问题
Exclude Similarities in List of Strings to extract the Difference
答案
https://stackoverflow.com/a/49714706/6806643
除了书的标题外,我有一个相同的句子列表。
代码循环,找到类似的prefixes
和suffixes
,然后在中间提取标题。
这本名为蝇王的书是经典之作 这本名为To Kill a Mockingbird的书是经典之作 这本名为The Catcher in the Rye的书是经典之作。
The book named
(前缀)和is a classic
(后缀)将被删除。
演示
http://rextester.com/FXXSVN30342
http://rextester.com/DUJZN22339
如果字符串没有类似的suffix
并且书籍标题都以相同的字符结尾,则该字符最终会被删除。在这种情况下s
。
这本名为蝇王的书 这本名为“呼啸山庄”的书 这本名为Great Expectations的书
过滤
Flie之王 呼啸山庄 期待很高
注意:这是一个示例列表,我在不同于书名的字符串上使用它。
public static void Main(string[] args)
{
var sentences = new List<string>()
{
"The book named Lord of the Flies",
"The book named Wuthering Heights",
"The book named Great Expectations"
};
var titles = ExtractDifferences(sentences);
Console.WriteLine(string.Join("\n", titles));
}
static List<string> ExtractDifferences(List<string> sentences)
{
var firstDiffIndex = GetFirstDifferenceIndex(sentences);
var lastDiffIndex = GetFirstDifferenceIndex(sentences.Select(s => new string(s.Reverse().ToArray())).ToList());
return sentences.Select(s => s.Substring(firstDiffIndex, s.Length - lastDiffIndex - firstDiffIndex)).ToList();
}
static int GetFirstDifferenceIndex(IList<string> strings)
{
int firstDifferenceIndex = int.MaxValue;
for (int i = 0; i < strings.Count; i++)
{
var current = strings[i];
var prev = strings[i == 0 ? strings.Count - 1 : i - 1];
var firstDiffIndex = current
.Select((c, j) => new { CurrentChar = c, Index = j })
.FirstOrDefault(ci => ci.CurrentChar != prev[ci.Index])
.Index;
if (firstDiffIndex < firstDifferenceIndex)
{
firstDifferenceIndex = firstDiffIndex;
}
}
return firstDifferenceIndex;
}
答案 0 :(得分:2)
您可以通过回溯到最近的单词边界来处理删除单词部分的问题。在这里,我只是假设这是一个空间,但如果需要,您可能希望扩展它。
在处理带有常用词的书名时,首先想到的是假设它们将被大写。所以除了句子的第一个字母外,你还可以停在第一个作为大写字符的字符。
此外,您可以通过不比较第一个算法来改进当前算法。只比较第1和第2,然后是第2和第3,依此类推到倒数第二个,最后一个就足够了。如果它确定差异的开始为零,则可以立即返回。
static int GetFirstDifferenceIndex(IList<string> strings)
{
int firstDifferenceIndex = int.MaxValue;
for (int i = 1; i < strings.Count; i++)
{
var current = strings[i];
var prev = strings[i - 1];
// Index of first character that is different or that is a capital letter
// other than the first character of the sentence.
var firstDiffIndex = current
.Select((c, j) => new { CurrentChar = c, Index = j })
.FirstOrDefault(ci => ci.CurrentChar != prev[ci.Index]
|| (ci.Index != 0 && char.IsUpper(ci.CurrentChar)))
.Index;
// back track to the beginning or until the previous char is a space
while(firstDiffIndex > 0 && current[firstDiffIndex-1] != ' ')
{
firstDiffIndex--;
}
if(firstDiffIndex == 0) return 0;
if (firstDiffIndex < firstDifferenceIndex)
{
firstDifferenceIndex = firstDiffIndex;
}
}
return firstDifferenceIndex;
}
这将采用句子
这本名为“指环王”的书
这本名为“蝇王”的书
和输出
指环王
蝇王
由于后退跟踪
,当你翻转句子时,它也适用于具有共同结尾的书名这本名为The Old Man and The Sea的书是经典的
这本名为Alone on a Wide,Wide Sea的书是经典的
将导致
老人与海
独自在宽阔的海面上
但是,当然这依赖于书籍标题的第一个和最后一个单词以大写字母开头,只有前缀的第一个字符是大写字母(并且没有以大写字母开头的后缀)。为了处理可能失败的情况,您必须开始分析会导致非常复杂算法的词性。
答案 1 :(得分:0)