我对如何比较两个字符串有疑问。
这是代码。
string stringA = "This is a test item";
string stringB = "item test a is This";
显然,stringB包含来自stringA的每个单词,但顺序不同。
我想要的结果应该是正确的。
我的问题是,我该怎么办?我曾尝试使用.Contains()方法,但结果为FALSE。
谢谢大家。
更新
感谢大家的亲切回复。
以下是我的澄清
我实际上是使用LINQ和EF构建数据库搜索功能。
假设一个项目的名称为“这是一个测试项目”。
如果用户输入“test a is this”,我希望该功能足够智能以捕捉上述项目。
有什么建议吗?
另一个更新
再次感谢您的帮助。
我确实喜欢Peter Ritchie,代码密码,Dave和EdFred的建议。
答案 0 :(得分:6)
'String.Split'带有空格分隔符的单词,将结果数组排序到List中,然后比较列表。例如:
var x = new List<string>(stringA.Split(' '));
x.Sort();
var y = new List<string>(stringB.Split(' '));
y.Sort();
bool areEqual = x.SequenceEqual(y);
更新如果您想要不区分大小写:
var x = new List<string>(stringA.Split(' '));
x.Sort();
var y = new List<string>(stringB.Split(' '));
y.Sort();
bool areEqual = x.SequenceEqual(y, StringComparer.OrdinalIgnoreCase);
但是,如果您正在寻找将在SQL Server中执行的内容,那么您可能还需要其他内容。
答案 1 :(得分:4)
尝试这种方法:
答案 2 :(得分:2)
我会将字符串拆分为tokens并测试stringA中令牌列表中是否存在stringA中的所有标记。类似的东西:
var stringBTokens = stringB.Split(" ");
foreach(string token in stringA.Split(" "))
{
if(stringBTokens.Contains(token) == false) return false;
}
return true;
可能有一些奇怪的正则表达式可以做到这一点,但这是一个相当直接的测试。如果你想获得幻想,你可以使用Linq Any方法,如下所示:
var stringBTokens = stringB.Split(" ");
return !stringBTokens.Any(token => stringA.Contains(token));
这基本上是做同样的事情,只是后者我发现更优雅。我希望没有错误,我在我的macbook pro上,并且没有安装.net相关(或单声道等等)以验证这是否有效。
<强>更新强>
根据您的澄清,我会看一下http://en.wikipedia.org/wiki/Inverted_index
这听起来像你想要实现的。我之前创建了这些,在数据库中进行快速文本搜索,并且它非常有效。
答案 3 :(得分:2)
模仿伯纳德的解释。
许多人遗漏了关键部分。在进行比较之前,需要转换字符串.ToLower()。
编辑:这就是你需要的。使Linq更具可读性。
public static bool Compare (string wordOne, string wordTwo)
{
//split into words
var wordsOne = wordOne.ToLower().Split(' ').ToList();
var wordsTwo = wordTwo.ToLower().Split(' ').ToList();
if (wordsOne.Count() != wordsTwo.Count()) {
return false;
}
//sort alphabetically
wordsOne.Sort((x,y) => string.Compare(x, y));
wordsTwo.Sort((x,y) => string.Compare(x, y));
//compare
for (int i = 0; i < wordsOne.Count(); i++) {
if(wordsOne[i] != wordsTwo[i])
return false;
}
return true;
}
答案 4 :(得分:1)
stringA.OrderBy(c => c).SequenceEqual(stringB.OrderBy(c => c));
修改强> 哎呀。错误的做法。这会教我回答得太快。
我相信这应该有效:
stringA.Split(' ').OrderBy(w => w).SequenceEqual(stringB.Split(' ').OrderBy(w => w));
答案 5 :(得分:1)
我会进行两阶段比较:
使用.Split('')方法拆分字符串并确保它们具有相同数量的元素(.Count属性)。
将新创建的数组(拆分字符串)转换为集合并执行A设置差异B联盟B设置差异A.
然后如果测试1通过并且设置差异的联合所创建的集合中没有元素(在测试2中),则您已成功比较了字符串中的单词,如上所述。
Michael G。
答案 6 :(得分:1)
在Peter Richie提出的出色建议的基础上,使用Array.Sort()
代替List<T>.Sort()
,没有重复但是打包成一个简洁的扩展方法:
public static bool ContainsSameWordsAs(this string first, string second)
{
return first.GetSortedWords().SequenceEqual(second.GetSortedWords());
// if upper and lower case words should be seen as identical, use:
// StringComparer.OrdinalIgnoreCase as a second argument to SequenceEqual
}
private static IEnumerable<string> GetSortedWords(this string source)
{
var result = source.Split().ToArray();
Array.Sort(result);
return result;
}
<强>用法强>
string stringA = "This is a test item";
string stringB = "item test a is This";
string stringC = "Not the Same is This";
bool result = stringA.ContainsSameWordsAs(stringB); // true
bool different = stringA.ContainsSameWordsAs(stringC); // false
编辑: 很难理解为什么您接受了不符合您问题中所述要求的答案。如果您真的想要字符串{{1}和"This is a test item"
匹配,你需要使用更多涉及的东西,例如:
"test a is this"
你可能想要提出一个更好的算法,因为这个算法非常宽松 - 两个相同的词足以算作匹配。但是这个将符合您在问题中所述的要求。
答案 7 :(得分:0)
您可以在空白处拆分字符串,并比较两个结果集合。您可以使用linq中的set operations:
如果第一个字符串中的单词位于集合单词1中,而第二个字符串中的单词位于单词2中,则可以执行以下操作:
if(!words1.Intersect(words2).Except( words1).Any()) -> your sentences are 'equal'
答案 8 :(得分:0)
bool match = true;
string[] stringBSplit = stringB.Split(' ');
foreach (string aString in stringA.Split((' ')))
{
if (!stringBSplit.Contains(aString))
{
match = false;
break;
}
}