C# 在第一个列表中按保留顺序将两个列表相交
我面临一个问题,我甚至不知道在Google/Stack Overflow中搜索什么。 因此,如果您觉得需要进一步解释,请发表评论,并回答问题 基本上,我希望将两个列表相交,并返回与原始第一个字符串值的保留顺序的相似性 例如: 我有两个字符串,我把它们转换成一个字符。 我希望将这两个数组相交,并返回相似的值,包括/具有第一个字符串(s1)的顺序。C# 在第一个列表中按保留顺序将两个列表相交,c#,arrays,string,linq,C#,Arrays,String,Linq,我面临一个问题,我甚至不知道在Google/Stack Overflow中搜索什么。 因此,如果您觉得需要进一步解释,请发表评论,并回答问题 基本上,我希望将两个列表相交,并返回与原始第一个字符串值的保留顺序的相似性 例如: 我有两个字符串,我把它们转换成一个字符。 我希望将这两个数组相交,并返回相似的值,包括/具有第一个字符串(s1)的顺序。 如您所见,第一个字符串包含E15(按特定顺序),第二个字符串也包含E15 所以这两个字符串将返回:{E',1',5'} string s1 = "E1
如您所见,第一个字符串包含E15(按特定顺序),第二个字符串也包含E15 所以这两个字符串将返回:{E',1',5'}
string s1 = "E15QD(A)";
string s2 = "NHE15H";
我面临的问题是,如果我将“s2”替换为:
我的操作将返回:{'Q','E','1'}
结果应该是:{E',1'},因为Q不跟随字母1
目前我的操作并不是最大的努力,因为我不知道在.NET中使用哪些方法才能做到这一点
当前代码:
List<char> cA1 = s1.ToList();
List<char> cA2 = s2.ToList();
var result = cA1.Where(x => cA2.Contains(x)).ToList();
List cA1=s1.ToList();
List cA2=s2.ToList();
var result=cA1.Where(x=>cA2.Contains(x)).ToList();
请随时帮助我,正确方向的指针是可以接受的,也是一个完整的解决方案。我认为应该这样做:
string similar = null;
for (int i = 0; i < s1.Length; i++)
{
string s = s1.Substring(0, i + 1);
if (s2.Contains(s))
{
similar = s;
}
}
char[] result = similar.ToCharArray();
字符串相似=null;
对于(int i=0;i@TimSchmelter在原始帖子的评论中提供了这个答案的链接
public int LongestCommonSubstring(string str1, string str2, out string sequence)
{
sequence = string.Empty;
if (String.IsNullOrEmpty(str1) || String.IsNullOrEmpty(str2))
return 0;
int[,] num = new int[str1.Length, str2.Length];
int maxlen = 0;
int lastSubsBegin = 0;
StringBuilder sequenceBuilder = new StringBuilder();
for (int i = 0; i < str1.Length; i++)
{
for (int j = 0; j < str2.Length; j++)
{
if (str1[i] != str2[j])
num[i, j] = 0;
else
{
if ((i == 0) || (j == 0))
num[i, j] = 1;
else
num[i, j] = 1 + num[i - 1, j - 1];
if (num[i, j] > maxlen)
{
maxlen = num[i, j];
int thisSubsBegin = i - num[i, j] + 1;
if (lastSubsBegin == thisSubsBegin)
{//if the current LCS is the same as the last time this block ran
sequenceBuilder.Append(str1[i]);
}
else //this block resets the string builder if a different LCS is found
{
lastSubsBegin = thisSubsBegin;
sequenceBuilder.Length = 0; //clear it
sequenceBuilder.Append(str1.Substring(lastSubsBegin, (i + 1) - lastSubsBegin));
}
}
}
}
}
sequence = sequenceBuilder.ToString();
return maxlen;
}
public int LongestCommonSubstring(字符串str1、字符串str2、out字符串序列)
{
sequence=string.Empty;
if(String.IsNullOrEmpty(str1)| | String.IsNullOrEmpty(str2))
返回0;
int[,]num=新int[str1.Length,str2.Length];
int maxlen=0;
int=0;
StringBuilder sequenceBuilder=新的StringBuilder();
for(int i=0;imaxlen)
{
maxlen=num[i,j];
int=i-num[i,j]+1;
如果(lastSubsBegin==thisSubsBegin)
{//如果当前LCS与上次运行此块时相同
sequenceBuilder.Append(str1[i]);
}
else//如果找到不同的LCS,此块将重置字符串生成器
{
lastSubsBegin=此SUBSBEGIN;
sequenceBuilder.Length=0;//清除它
sequenceBuilder.Append(str1.Substring(lastsubsbeing,(i+1)-lastsubsbeing));
}
}
}
}
}
sequence=sequenceBuilder.ToString();
返回maxlen;
}
这是一个问题
您可以使用此扩展延迟获取所有子字符串:
public static class StringExtensions
{
public static IEnumerable<string> GetSubstrings(this string str)
{
if (string.IsNullOrEmpty(str))
throw new ArgumentException("str must not be null or empty", "str");
for (int c = 0; c < str.Length - 1; c++)
{
for (int cc = 1; c + cc <= str.Length; cc++)
{
yield return str.Substring(c, cc);
}
}
}
}
因为它使用一个集合,所以也非常有效。注意:如果两个字符串中的一个大于另一个,那么首先使用它会更有效(在内存方面):
longString.GetSubstrings().Intersect(shortString.GetSubstrings())
使用Intersect
将给出从第一个字符串开始的顺序。但是您的需求表明,您可能希望为s1=“AXBYC”
和s2=“ABACUS”
?@CoderofCode将立即查看该输出。我猜您正在寻找一种方法来查找。这里还有一个C#实现:@dasblinkenlight,它应该返回{'a'}。因为在我的初始测试中,两个单词中的第一个字符是相似的(没有前一个字母),所以这很有效!谢谢你,伙计@TimSchmelter在原始帖子的评论中也为Longeststring的解决方案提供了链接。我也会上传答案。
string longestIntersection = "E15QD(A)".GetSubstrings()
.Intersect("NQE18H".GetSubstrings())
.OrderByDescending(s => s.Length)
.FirstOrDefault(); // E1
longString.GetSubstrings().Intersect(shortString.GetSubstrings())