C#Linq如何比较两个字符串并报告第一个不同的字符,它本身不同于'';通配符
我有一个比较两个字符串并报告第一个不同字符的函数:C#Linq如何比较两个字符串并报告第一个不同的字符,它本身不同于'';通配符,c#,linq,C#,Linq,我有一个比较两个字符串并报告第一个不同字符的函数: public static int Diff(this string str1, string str2) { try { if (str1 == null || str2 == null) return 0; int index = str1.Zip(str2, (c1, c2) => c1 == c2).TakeWhile(b => b).Count();
public static int Diff(this string str1, string str2)
{
try
{
if (str1 == null || str2 == null)
return 0;
int index = str1.Zip(str2, (c1, c2) => c1 == c2).TakeWhile(b => b).Count();
return index;
}
catch (Exception)
{
return 0;
}
}
所有的魔力都在这里:
int index = str1.Zip(str2, (c1, c2) => c1 == c2).TakeWhile(b => b).Count();
假设我们有两个字符串:
输入,1,1,0,0,0,0,0,0,0,0,0,0
输入、、、1、、、、、、、、、、、、、
01234567890
那么,考虑到所有的字符,第一个不同的是?所以答案是6(从0开始)。这很有效
现在我想介绍一下?作为通配符字符,因此必须跳过,因此答案应为10(从0开始)
我不知道如何更改上面linq表达式中的代码来实现这一点。
我尝试了intindex=str1.Zip(str2,(c1,c2)=>c1==c2&&c2!='?')。TakeWhile(b=>b.Count()代码>但这不会改变任何事情,并且总是报告6而不是9
我想坚持使用linq,而不是通过(更简单的)for循环
谢谢我想你只需要稍微改变一下逻辑条件
如果Zip
中使用的条件为假,我们将停止查找。只有当两个字符不相同且其中一个不是通配符时,我们才应该停止查找
因此,条件应该是:
!(c1 != c2 && (c1 != '?' || c2 != '?'))
显然,这可以用德摩根定律来简化:
c1 == c2 || c1 != '?' || c2 != '?'
因此,该行变为:
index = str1.Zip(str2, (c1, c2) => c1 == c2 || c1 != '?' || c2 != '?').TakeWhile(b => b).Count();
您需要通配符作为附加的可能true
条件进行计数。因此,您需要使用OR|
而不是AND&
:
不是:
int index=str1.Zip(str2,(c1,c2)=>c1==c2&&c2!='?').TakeWhile(b=>b.Count()代码>
相反:
int index=str1.Zip(str2,(c1,c2)=>c1==c2 | | c2='?')).TakeWhile(b=>b.Count()代码>
如果还希望忽略第一个输入中的通配符,则可以在表达式中添加额外的|
。使用linq
以下是经过全面测试的解决方案:
string input1 = "1,1,0,0,0,0,0,0,0,0,0,0";
string input2 = "\u003F,\u003F,1,\u003F,\u003F,\u003F,\u003F,\u003F,\u003F,\u003F,\u003F,\u003F";
int results = input1.Select((x, i) => new { chr = x, index = i }).Where(x => (x.chr != input2[x.index]) && (x.chr != '\u003F') && (input2[x.index] != '\u003F')).Min(x => x.index);
c1==c2 | c2=='?'
string input1 = "1,1,0,0,0,0,0,0,0,0,0,0";
string input2 = "\u003F,\u003F,1,\u003F,\u003F,\u003F,\u003F,\u003F,\u003F,\u003F,\u003F,\u003F";
int results = input1.Select((x, i) => new { chr = x, index = i }).Where(x => (x.chr != input2[x.index]) && (x.chr != '\u003F') && (input2[x.index] != '\u003F')).Min(x => x.index);