2012-10-26 59 views
0

我有一個字符串[]數組的通用列表,我需要構建一個字符串列表以及這些數組中的項目的所有可能的組合。我很難用最好的方法包紮我的頭。C#字符串與n^n個可能性的連接

so: List mylist = new List; //我然後從分貝填充此...

MYLIST的內容是這樣的:

Buildings ||| Facilities ||| Fields ||| Files; Groups; Entity; ||| Controllers; FX; Steam; 

管子「|||」在MYLIST分隔每個字符串數組,分號是表示分隔符這些數組中的每個項目。所以數組的最小長度爲1,最大長度爲N.我需要用上述所有可能的組合構建連字符「---」分隔的字符串列表,但保持它們在名單。因此,使用上面的例子,我會拿出該字符串列表:

Buildings---Facilities---fields---Files---Controllers 
Buildings---Facilities---fields---Groups---Controllers 
Buildings---Facilities---fields---Entity---Controllers 

Buildings---Facilities---fields---Files---Fx 
Buildings---Facilities---fields---Groups---Fx 
Buildings---Facilities---fields---Entity---Fx 

Buildings---Facilities---fields---Files---Steam 
Buildings---Facilities---fields---Groups---Steam 
Buildings---Facilities---fields---Entity---Steam 

如果在列表中的第三個數組有兩個項目,而不是1(「字段」) - 我們就會有一個18個字符串的列表,而不是9個(3x3x2)。我試過使用循環,知道哪個數組有最大的長度,並循環每個列表項,但我只是無法讓它工作。睡在上面並沒有真正的幫助。

有人嗎?

+0

看看這個問題。可能幫助:http://stackoverflow.com/questions/10515449/generate-all-combinations-for-a-list-of-strings – itsmatt

+0

你在問某些領域的排列。看看這裏的一些想法:http://stackoverflow.com/questions/5128615/c-sharp-string-permutation –

+0

我讀這些,他們看起來相關,但我認爲我想要做的是一個級別複雜。我不只是從列表中創建字符串,我從列表中創建它們...(?),但至少我知道它現在稱爲排列... – TheRedDwarf

回答

1

我會嘗試遞歸:

private void button1_Click(object sender, EventArgs e) 
     { 
      List<string[]> strs = new List<string[]>(); 
      strs.Add(new string[] {"Buildings"}); 
      strs.Add(new string[] {"Facilities"}); 
      strs.Add(new string[] {"Fields"}); 
      strs.Add(new string[] {"Files", "Groups", "Entity"}); 
      strs.Add(new string[] {"Controllers", "FX", "Steam"}); 
      List<string> list = AddStringsToList(strs, 0); 

     } 

     List<string> AddStringsToList(List<string[]> list, int level) 
     { 
      List<string> listOfStrings = new List<string>(); 
      if (level == list.Count - 1) 
      { 
       foreach (string s in list[level]) 
       { 
        listOfStrings.Add(s); 
       } 
      } 
      else if(level<list.Count-1) 
      { 
       List<string> list1 = AddStringsToList(list, level + 1); 
       foreach (string s in list[level]) 
       { 
        foreach(string s1 in list1) 
         listOfStrings.Add(s + "---" + s1); 
       } 
      } 
      return listOfStrings; 
     } 

測試和它的作品!

+0

這是它......謝謝你!!!!!! 也有:http://pastebin.com/VzTs71u1 - 有很多例子 – TheRedDwarf

0

讓我們產生這個代替:

Buildings---Facilities---fields---Files---Controllers 
Buildings---Facilities---fields---Files---Fx 
Buildings---Facilities---fields---Files---Steam 

Buildings---Facilities---fields---Groups---Controllers 
Buildings---Facilities---fields---Groups---Fx 
Buildings---Facilities---fields---Groups---Steam 

Buildings---Facilities---fields---Entity---Controllers 
Buildings---Facilities---fields---Entity---Fx 
Buildings---Facilities---fields---Entity---Steam 

首先,我們假設數據從數據庫的格式如下:

List<List<string>> dataFromDb; 

如果一些內藏品只有沒關係一個值。然後,這樣的事情應該做的伎倆:

void ConcatString(string prefix, int index, List<List<string>> collection, List<string> output) 
{ 
    if(index == collection.Count) 
    { 
     output.Add(prefix); 
     return; 
    } 
    var subCollection = collection[index]; 
    foreach(var str in subCollection) 
    { 
     string newPrefix = ((prefix.Length > 0)? "---" : "") + str; 
     ConcatString(newPrefix, index+1, collection, output); 
    } 
} 

調用,如:

var output = new List<string>(); 
ConcatString("", 0, dataFromDb, output); 

你要找的應該是輸出列表。現在請注意,我沒有運行過這個(哎呀,我甚至沒有編譯過),所以你需要調試它,但它應該讓你至少朝正確的方向前進。

+0

現在試試這個 – TheRedDwarf

+0

我試過了,並輸出最終長度爲2,值「---」和「---」 – TheRedDwarf

2

我想這可能做你要找的內容:

static IEnumerable<string> Combinations(IEnumerable<IEnumerable<string>> items) 
{ 
    return items.Aggregate((outs, ins) => outs.SelectMany(o => ins.Select(i => o + "---" + i))); 
} 

而且這裏有一個例子使用

static void Main(string[] args) 
{ 
    IEnumerable<IEnumerable<string>> items = new string[][] 
    { 
     new [] { "Buildings" }, 
     new [] { "Facilities" }, 
     new [] { "Fields" }, 
     new [] { "Files", "Groups", "Entity" }, 
     new [] { "Controllers", "FX", "Steam" } 
    }; 

    foreach (var c in Combinations(items)) 
     Console.WriteLine(c); 

    Console.ReadLine(); 
} 

對於每一組的可能性,它需要所有它有這麼琴絃遠(例如「建築物---設施---領域---文件」,「建築物---設施---領域---實體」等),然後針對每種可能性(例如{「控制者」, 「FX」,「Steam」})它將這種可能性附加到輸出字符串以獲得一組新的輸出字符串。聚合重複這個過程,從第一個元素作爲輸出字符串的可能性開始,然後連續重複這個「笛卡爾乘積」,直到所有輸入被消耗完。

編輯

作爲參考,這是從樣本程序的輸出:

Buildings---Facilities---Fields---Files---Controllers 
Buildings---Facilities---Fields---Files---FX 
Buildings---Facilities---Fields---Files---Steam 
Buildings---Facilities---Fields---Groups---Controllers 
Buildings---Facilities---Fields---Groups---FX 
Buildings---Facilities---Fields---Groups---Steam 
Buildings---Facilities---Fields---Entity---Controllers 
Buildings---Facilities---Fields---Entity---FX 
Buildings---Facilities---Fields---Entity---Steam 

我想指出的是,該解決方案是相當有效的。它不使用遞歸,這使得它對於長鏈的情況特別有效。此外,如果您處理多個結果組合(記住這些組合可以隨鏈長指數增長),它會懶惰地評估結果,這樣會更有效地提高內存效率。