Я думаю, что я сделал бы это так
public static class StringPermutator
{
/// <summary>
/// Class to permutate input values
/// </summary>
/// <param name="inputValues">An array of inputs to be permutated</param>
/// <param name="numberOfResults">The number of outputs we want to have</param>
/// <param name="maxValuesPerRow">The number of values to be combined in each output row</param>
/// <returns>An IEnumerable of unique permutated string ouptuts</returns>
public static IEnumerable<string> Permutate<T>(T[] inputValues, int numberOfResults, int maxValuesPerRow)
{
HashSet<string> output = new HashSet<string>();
Random rnd = new Random();
//Loop until we have the number of results we want
while (output.Count < numberOfResults)
{
StringBuilder sb = new StringBuilder();
HashSet<int> usedIndexes = new HashSet<int>();
//Loop until we have the right number of values in a single row
while (usedIndexes.Count < maxValuesPerRow)
{
int index = rnd.Next(inputValues.Length);
//Ensure that each index we use is unique and only used once per row
if (usedIndexes.Add(index))
sb.Append(inputValues[index].ToString()).Append(",");
}
sb.Length--; //remove the last comma
output.Add(sb.ToString()); //value is only added if unique
}
return output.ToList();
}
}
Вы можете назвать это так
var result = StringPermutator.Permutate(stringValues, 100, 24);
foreach (var permutation in result)
{
Console.WriteLine(string.Join(",", permutation));
}
В основном, класс использует HashSet, который обеспечивает возможность ввода только уникальных значений, поэтому мы можем быть уверены, что наши выходные данные не дублируются, и мы просто зациклимся, пока у нас не будет нужного числа сгенерированных выходных значений.
В этом цикле мы случайным образом выбираем индекс для использования, и, чтобы гарантировать, что он также уникален для каждого выходного значения, мы снова используем HashSet для хранения используемых индексов и цикла, пока мы не скомбинируем правильное количество значений в один выходной ряд.
Возвращается список Enumerable.
Это должно работать с любым типом входного значения, а не только со строками.
Edit:
Просто чтобы уточнить, согласно комментариям.
Если у вас недостаточно входных данных для генерации необходимого вам количества комбинаций перестановок и строк, вы можете застрять в цикле. Таким образом, вы должны написать метод, чтобы вырваться из этого, но для простоты примера я этого не сделал.