Если опция «переписать историю» является опцией, я бы извлекла M2
, исправила и исправила ее (назовем ее M2'
с поправками), тогда я бы выбрала вишню M2..M4
и затем объединила [113 ] создание M5'
. Затем я бы указал ветку (main?) На M5'
, и это было бы ее концом (принудительный толчок туда, где она требуется).
Как примечание: нет , не должно быть конфликта при слиянии A2
с M4
, потому что код был удален, и это не имеет значения для предков (если только код не включает в себя код, который затронут работой, проделанной на A2
).
Это будет работать, неважно, сколько массивов Вы добавляете к своему myList:
static void Main(string[] args)
{
string[][] myList = new string[3][];
myList[0] = new string[] { "1", "5", "3", "9" };
myList[1] = new string[] { "2", "3" };
myList[2] = new string[] { "93" };
List<string> permutations = new List<string>(myList[0]);
for (int i = 1; i < myList.Length; ++i)
{
permutations = RecursiveAppend(permutations, myList[i]);
}
//at this point the permutations variable contains all permutations
}
static List<string> RecursiveAppend(List<string> priorPermutations, string[] additions)
{
List<string> newPermutationsResult = new List<string>();
foreach (string priorPermutation in priorPermutations)
{
foreach (string addition in additions)
{
newPermutationsResult.Add(priorPermutation + ":" + addition);
}
}
return newPermutationsResult;
}
Обратите внимание, что это не действительно рекурсивно. Вероятно, вводящее в заблуждение имя функции.
Вот версия, которая придерживается Ваших новых требований. Отметьте раздел, где я произвел к консоли, это - то, где можно сделать собственное форматирование:
static void Main(string[] args)
{
string[][] myList = new string[3][];
myList[0] = new string[] { "1", "5", "3", "9" };
myList[1] = new string[] { "2", "3" };
myList[2] = new string[] { "93" };
List<List<string>> permutations = new List<List<string>>();
foreach (string init in myList[0])
{
List<string> temp = new List<string>();
temp.Add(init);
permutations.Add(temp);
}
for (int i = 1; i < myList.Length; ++i)
{
permutations = RecursiveAppend(permutations, myList[i]);
}
//at this point the permutations variable contains all permutations
foreach (List<string> list in permutations)
{
foreach (string item in list)
{
Console.Write(item + ":");
}
Console.WriteLine();
}
}
static List<List<string>> RecursiveAppend(List<List<string>> priorPermutations, string[] additions)
{
List<List<string>> newPermutationsResult = new List<List<string>>();
foreach (List<string> priorPermutation in priorPermutations)
{
foreach (string addition in additions)
{
List<string> priorWithAddition = new List<string>(priorPermutation);
priorWithAddition.Add(addition);
newPermutationsResult.Add(priorWithAddition);
}
}
return newPermutationsResult;
}
Вы могли использовать factoradics для генерации перечисления перестановок. Попробуйте эту статью о MSDN для реализации в C#.
Нерекурсивное решение:
foreach (String s1 in array1) {
foreach (String s2 in array2) {
foreach (String s3 in array3) {
String result = s1 + " " + s2 + " " + s3;
//do something with the result
}
}
}
Рекурсивное решение:
private ArrayList<String> permute(ArrayList<ArrayList<String>> ar, int startIndex) {
if (ar.Count == 1) {
foreach(String s in ar.Value(0)) {
ar.Value(0) = "val" + startIndex + "=" + ar.Value(0);
return ar.Value(0);
}
ArrayList<String> ret = new ArrayList<String>();
ArrayList<String> tmp1 ar.Value(0);
ar.remove(0);
ArrayList<String> tmp2 = permute(ar, startIndex+1);
foreach (String s in tmp1) {
foreach (String s2 in tmp2) {
ret.Add("val" + startIndex + "=" + s + " " + s2);
}
}
return ret;
}
Рекурсивное решение
static List<string> foo(int a, List<Array> x)
{
List<string> retval= new List<string>();
if (a == x.Count)
{
retval.Add("");
return retval;
}
foreach (Object y in x[a])
{
foreach (string x2 in foo(a + 1, x))
{
retval.Add(y.ToString() + " " + x2.ToString());
}
}
return retval;
}
static void Main(string[] args)
{
List<Array> myList = new List<Array>();
myList.Add(new string[0]);
myList.Add(new string[0]);
myList.Add(new string[0]);
myList[0] = new string[]{ "1", "5", "3", "9" };
myList[1] = new string[] { "2", "3" };
myList[2] = new string[] { "93" };
foreach (string x in foo(0, myList))
{
Console.WriteLine(x);
}
Console.ReadKey();
}
Обратите внимание, что было бы довольно легко возвратить список или массив вместо строки путем изменения возврата, чтобы быть списком списков строк, и изменение retval.add звонит для работы со списком вместо того, чтобы использовать конкатенацию.
Как это работает:
Это - классический рекурсивный алгоритм. Основной случай foo(myList.Count, myList)
, который возвращает Список, содержащий один элемент, пустую строку. Перестановка списка n массивов строк s1, s2..., sN равна каждому члену sA1, снабженного префиксом к перестановке n-1 массивов строк, s2..., sN. Основной случай должен просто там обеспечить что-то для каждого элемента sN, который будет связан к.
Я удивлен, что никто не опубликовал решение LINQ.
from val0 in new []{ "1", "5", "3", "9" }
from val1 in new []{ "2", "3" }
from val2 in new []{ "93" }
select String.Format("val0={0};val1={1};val2={2}", val0, val1, val2)