我需要合并两个枚举,同时保持源枚举中定义的项目的相对顺序。 例如,如果 enumerable1 包含“foxtrot”、“uniform”和“kilo”,而 enumerable2 包含“uniform”、“charlie”和“kilo”,则生成的枚举应包含“foxtrot”、“uniform”、“charlie”、“公斤”。
解释:从 enumerable1 中我们知道“foxtrot”出现在“uniform”之前,从 enumerable2 中我们知道“uniform”出现在“charlie”之前。因此我们可以假设“foxtrot”出现在“uniform”出现在“charlie”之前。 另外,我们从 enumerable1 中知道“uniform”出现在“kilo”之前,并且从 enumerable2 中知道“charlie”出现在“uniform”之后、“kilo”之前。 结合所有这些,我们可以说出“foxtrot”、“uniform”、“charlie”和“kilo”的最终顺序。
然而,在某些情况下这不起作用,因为无法确定顺序或者两个源枚举相互矛盾。 例如,如果 enumerable3 包含“foxtrot”和“charlie”,而 enumerable4 包含“uniform”和“kilo”,则它们无法合并,因为无法区分任何顺序。或者,如果 enumerable5 包含“foxtrot”和“uniform”,而 enumerable6 包含“uniform”和“foxtrot”,则它们无法合并,并且应返回空枚举。
虽然这在我的脑海中很容易想象,但我很难将其转化为代码。最好是 C#。 在这个非常具体的例子中,每个可枚举的最大项目数是 4,但我认为拥有独立于该项目的代码不会有什么坏处。
有人有什么想法吗?
你可以尝试以下方法,尽管我还没有彻底测试过。
class Program {
static void Main(string[] args) {
IEnumerable<string> l1 = new List<string> { "foxtrot", "uniform", "kilo" };
IEnumerable<string> l2 = new List<string> { "uniform", "charlie", "kilo", "extra1", "extra2" };
try {
IEnumerable<string> result = Merge(l1, l2);
foreach (string s in result) {
Console.WriteLine(s);
}
}
catch (InvalidOperationException e) {
Console.WriteLine(e.Message);
}
Console.ReadKey();
}
public static IEnumerable<T> Merge<T> (IEnumerable<T> list1, IEnumerable<T> list2) {
if ((list1.Count() == 0)) {
return list2;
}
if ((list2.Count() == 0)) {
return list1;
}
List<T> newList = new List<T>();
bool matchfound = false;
for(int i = 0; i< list1.Count(); i++) {
for (int j = 0; j < list2.Count(); j++) {
if (list1.ElementAt(i).Equals(list2.ElementAt(j))) {
matchfound = true;
newList.AddRange(Merge(list1.Take(i), list2.Take(j)));
newList.Add(list1.ElementAt(i));
newList.AddRange(Merge(list1.Skip(i + 1), list2.Skip(j + 1)));
break;
}
}
if (matchfound) {
break;
}
}
if (!matchfound) {
throw new InvalidOperationException("Could not merge");
}
return newList;
}
}