2012-03-23 62 views
0

我试图维护较大列表中较小列表的顺序。假设有三个列表:重新排列具有多个子列表的主列表

List A = { Beef, Ham, Chicken } 
List B = { Cat, Monkey, Dog } 

List C = { Veal, Ham, Beef, Chicken, Deer, Dog, Cat, Monkey } 

名单A和B是C的子集,你可以看到,在一个项目都按顺序在C.我想维持内A和B的顺序C.因此,C的输出应为:

{ Veal, Beef, Ham, Chicken, Deer, Cat, Monkey, Dog } 

记住不在A或B项保持C(牛肉和鹿)有原始位置。而且,A或B中的项目总是在一起。 C的排序必须在创建C之后完成,因为A和B的顺序可能会发生变化,如果发生这种情况,C必须更新。

如何实现这一目标?谢谢。

+0

你使用的是什么语法?它是数组还是列表?这是否需要正好用于三个列表或任意数量的列表?性能是一个问题吗? – 2012-03-23 18:56:43

+3

如果不能保留不在A或B中的物品的原始位置,该怎么办?例如。如果C是“{火腿,小牛肉,牛肉,鸡,狗,猫,鹿,猴子}算法完成后C应该变成什么? – 2012-03-23 19:01:35

+0

提示:通过提供(多件)真实代码,使答案更容易。 – 2012-03-23 19:02:26

回答

0

你可以做这样的事情。

var A = new List<string> { "Beef", "Ham", "Chicken" }; 
var B = new List<string> { "Cat", "Monkey", "Dog" }; 
var C = new List<string> { "Veal", "Ham", "Beef", "Chicken", "Deer", "Dog", "Cat", "Monkey" }; 

// To quickly check if C[i] belongs to the corresponding list. 
var sA = new HashSet<string>(A); 
var sB = new HashSet<string>(B); 
List<string> currentList = null; 
int pos = 1; 
for (int i = 0; i < C.Count; i++) 
{ 
    string el = C[i]; 
    if (currentList != null) 
    { 
     if (pos == currentList.Count) 
     { 
      pos = 1; 
      currentList = null; 
     } 
     else 
     { 
      C[i] = currentList[pos]; 
      pos++; 
     } 
    } 
    else if (sA.Contains(el)) 
    { 
     currentList = A; 
     C[i] = currentList[0]; 
    } 
    else if (sB.Contains(el)) 
    { 
     currentList = B; 
     C[i] = currentList[0]; 
    } 
} 

// Outputs "Veal,Beef,Ham,Chicken,Deer,Cat,Monkey,Dog" 
Console.WriteLine(string.Join(",", C)); 
2

的C不应该是一个列表,它应该是列表的列表。

这样,C从未有它自己的子列表元素单独订购,所以重新排序子列表会自动反映到C,无任何多余的动作。届时,您可以使用SelectMany轻松“平整”C语言。

例如:

class Program { 

    static void Main(string[] args) { 

     var A = new List<string> { "Ham", "Beef", "Chicken" }; 
     var B = new List<string> { "Cat", "Dog", "Monkey" }; 
     var C = new List<List<string>> { 
      new List<string> { "Veal" }, 
      A, 
      new List<string> { "Deer" }, 
      B 
     }; 

     Console.WriteLine("ORIGINAL LIST:"); 
     foreach (var element in C.SelectMany(l => l)) 
      Console.WriteLine(element); 

     // Now reorder one of the sub-lists (swap "Ham" and "Beef"): 
     var tmp = A[0]; 
     A[0] = A[1]; 
     A[1] = tmp; 

     Console.WriteLine("\nREORDERED LIST:"); 
     foreach (var element in C.SelectMany(l => l)) 
      Console.WriteLine(element); 

    } 

} 

此打印:

ORIGINAL LIST: 
Veal 
Ham 
Beef 
Chicken 
Deer 
Cat 
Monkey 
Dog 

REORDERED LIST: 
Veal 
Beef 
Ham 
Chicken 
Deer 
Cat 
Monkey 
Dog 

此假设下,所有作品的子列表是不相交的。如果某些元素在多个子列表之间共享,但只需在C中存在一次,则此模型会崩溃。但是,再一次,你的原始模型也会崩溃,所以我冒昧地认为情况并非如此。

+0

不相交的假设是正确的。我喜欢你的解决方案,但是,Gebb的答案也是正确的,但他首先回答。这种情况下的礼仪礼仪是什么?我想接受你的答案。 – morechitlins 2012-03-23 21:39:58

+0

@morechitlins一旦你获得了足够的声望,你就可以同时胜利;)除此之外,如果你认为新的答案比旧的答案更有用,你可以不接受旧答案并接受新答案。如果你认为它们大致相等,那么可以使用任何标准_你认为合适,包括谁是第一。 – 2012-03-23 23:31:34