2016-04-02 2 views
0

Я пишу программу, которая должна сортировать список домов на основе их координат с Евклидовым расстоянием. Чтобы отсортировать список, я использую алгоритм сортировки слиянием.C#: Слияние сортировки с векторами

Координаты Vector2: координаты зданий. Vector2 house: координаты главного здания.

Ниже класс, который делает вид слияния:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Microsoft.Xna.Framework; 

namespace EntryPoint 
{ 
public static class MergeSorter 
{ 
    public static void DoMergeSort(this Vector2[] numbers) 
    { 
     var sortedNumbers = MergeSort(numbers); 

     for (int i = 0; i < sortedNumbers.Length; i++) 
     { 
      numbers[i] = sortedNumbers[i]; 
     } 
    } 

    private static Vector2[] MergeSort(Vector2[] numbers) 
    { 
     if (numbers.Length <= 1) 
     { 
      return numbers; 
     } 

     var left = new List<Vector2>(); 
     var right = new List<Vector2>(); 

     for (int i = 0; i < numbers.Length; i++) 
     { 
      if (i % 2 > 0) 
      { 
       left.Add(numbers[i]); 
      } 
      else 
      { 
       right.Add(numbers[i]); 
      } 
     } 

     left = MergeSort(left.ToArray()).ToList(); 
     right = MergeSort(right.ToArray()).ToList(); 

     return Merge(left, right); 
    } 

    private static Vector2[] Merge(List<Vector2> left, List<Vector2> right) 
    { 
     var result = new List<Vector2>(); 

     while (left.Count > 0 && right.Count > 0) 
     { 
      if (**left.First() <= right.First()**) 
      { 
       MoveValueToResult(left, result); 
      } 
      else 
      { 
       MoveValueToResult(right, result); 
      } 
     } 
     while (left.Count > 0) 
     { 
      MoveValueToResult(left, result); 
     } 
     while (right.Count > 0) 
     { 
      MoveValueToResult(right, result); 
     } 
     return result.ToArray(); 
    } 

    private static void MoveValueToResult(List<Vector2> list, List<Vector2> result) 
    { 
     result.Add(list.First()); 
     list.RemoveAt(0); 
    } 

    private static double GetEuclideanDistance(Vector2 coordinates, Vector2 house) 
    { 
     double distance = Math.Sqrt(Math.Pow((house.X - coordinates.X), 2) + Math.Pow((house.Y - coordinates.Y), 2)); 
     return distance; 
    } 
} 

}

На линии с двумя звездочками: left.First() < = right.First(). Мне кажется, нужен метод GetEuclideanDistance(), но я не понимаю, как это сделать?

Я пробовал примерно следующее: GetEuclideanDistance (первого элемента в левом списке) < = GetEuclideanDistance (первого элемента в правом списке). Но тогда я не знаю, какие параметры мне нужно дать тогда.

+0

Есть ли какой-либо причине вы не реализует компаратор и позволяя ядро ​​решить, как сортировать? –

+1

Вы хотите отсортировать их по расстоянию до главного здания, не так ли? Тогда сначала вам нужно будет определить mainbuilding как-то. 'Vector2 main = new Vector2 (некоторые координаты)'. Затем вы можете сравнить: 'if (GetEucledianDistance (left.First(), main) <= GetEucledianDistance (right.First(), main)) ...' – derpirscher

+0

Непонятно, что такое ключ сортировки. Действительно ли (как полагают предыдущие комментарии), что все предметы сортируются в соответствии с их расстоянием от одного места? Если это так, вам нужно передать это единственное место, чтобы метод «GetEuclideanDistance()» мог быть вызван с этим местоположением. Если нет, то вам нужно объяснить, что вы пытаетесь сортировать. Без хорошего [mcve] невозможно точно знать, что намерение здесь, неважно, как помочь с вашей проблемой. –

ответ

1

Если вы правильно поняли, чего хотите, то Collection из Vector2 Координаты отсортированы по их Euclidean Расстояние по отношению к house Координаты. Если да, то, что должно быть достаточно:

//Coordinates - coordinates list to sort 
//housePosition - position to which Euclidean distance should be calculated for every coordinate 
private static List<Vector2> SortByDistance(IEnumerable<Vector2> coordinates, Vector2 housePosition) 
{ 
    return coordinates.OrderBy(coordinate => GetEuclideanDistance(coordinate, housePosition)).ToList(); 
} 


private static double GetEuclideanDistance(Vector2 coordinates, Vector2 house) 
{ 
    double distance = Math.Sqrt(Math.Pow((house.X - coordinates.X), 2) + Math.Pow((house.Y - coordinates.Y), 2)); 
    return distance; 
} 
+0

+1 но, скорее всего, вы неправильно догадались. Лучше всего, чтобы такие неясные вопросы проходили и закрывали их (как только вы достигнете репутации, чтобы сделать это). – usr

+0

Поскольку вы просто сравниваете одно расстояние относительно другого, вы можете ускорить это с помощью специализированной функции, которая оставила бы квадратный корень. –