2017-02-09 13 views
0

Допустим, у меня есть массив целых чисел. Я узнал, что я могу рандомизации порядок элементов просто, выполнив:Рандомизированная часть массива в C#

Random rnd = new Random(); 
array = array.OrderBy(x => rnd.Next()).ToArray(); 

Но позволяет сказать, что я хочу, чтобы сохранить первый и последний элементы в их первоначальном месте. Могу ли я сделать это, используя тот же подход (используя OrderBy()) или мне нужно переосмыслить мою ситуацию?

+0

Возможно, существует более чистое решение, но просто сохраните первый и последний элементы, а затем вставьте их в рандомизированный список. – KDecker

ответ

1

Вы не можете сделать это в одном выражении, но, возможно, List<int> может помочь:

Random rnd = new Random(); 
var list = new List<int>(); 
list.Add(array[0]); 
var partialArray = array.Skip(1).Take(array.Length - 2); 
list.AddRange(partialArray.OrderBy(x => rnd.Next())); 
list.Add(array[array.Length -1 ]); 
1

Конечно, вы можете использовать тот же подход, но вы должны заботиться о первой и последней стоимость. Просто пример для ввода array: пример

var list = array.Skip(1).Take(array.Length - 2).OrderBy(x => rnd.Next()).ToList(); 
list.Insert(0, array.First()); 
list.Add(array.Last()); 
array = list.ToArray(); 

Дмитрия в основном то же самое, но дает возможность сохранить больше элементов.

+1

Dang, слишком медленно, я написал почти то же самое персонаж по характеру! –

1

Вы можете сделать это:

 int[] ints = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
     ints = ints.Select((x, index) => new { Value = x, Index = index }) 
       .OrderBy(tuple => (tuple.Index >= start && tuple.Index <= stop) ? random.Next(start, stop) : tuple.Index) 
       .Select(tuple => tuple.Value) 
       .ToArray(); 
0

несколько иной подход, который не требует использования списка ....

 Random rnd = new Random(); 
     //array = array.OrderBy(x => rnd.Next()).ToArray(); 

     int lastIndexToChange = array.Length - 1; 

     for (int i = 1; i < lastIndexToChange; i++) 
     { 
      var tempStore = array[i]; 
      int newPosition = rnd.Next(1, lastIndexToChange); 

      array[i] = array[newPosition]; 
      array[newPosition] = tempStore; 
     } 
1

Вы можете просто использовать стандартный алгоритм перетасовки модифицированную использовать диапазон, например (с использованием the Fisher-Yates algorithm):

public static void Shuffle<T>(IList<T> array, Random rng, int start, int end) 
{ 
    for (int n = end+1; n > start+1;) 
    { 
     int k = rng.Next(start, n); 
     --n; 
     T temp = array[n]; 
     array[n] = array[k]; 
     array[k] = temp; 
    } 
} 

Затем вызовите его следующим образом:

Random rng = new Random(); 

for (int i = 0; i < 100; ++i) 
{ 
    var array = Enumerable.Range(1, 12).ToArray(); 
    Shuffle(array, rng, 3, 9); 
    Console.WriteLine(string.Join(", ", array)); 
} 
Смежные вопросы