2016-10-09 2 views
-3

정수 목록을 가능한 한 많이 퍼뜨리는 방식으로 정렬하고 싶습니다. 베이스 (8)을 가정하면, 1 내지 7의 항목 순서가되어야한다 : 당연 모호성 상당량이있다 enter image description here최대 스프레드를 사용하여 숫자 정렬하기

모두 6과 2는 동일 멀리 4, 0에서 그대로 : {4, 6, 2, 7, 1, 5, 3} 따라 8이므로 6과 2의 특정 순서는 부적합합니다. 내가 달성하고자하는 것은 먼저 0base에서 가장 멀리 떨어진 번호를 선택한 다음 0, basefirst number 등에서 가장 멀리 떨어진 번호를 선택하는 것입니다. 처리됩니다.

주어진베이스에 대한 정렬 순서를 수동으로 설계 할 수 있지만 base >= 2에서 작동하려면이 항목이 필요합니다. 이것을 계산하는 영리한/빠른 방법이 있습니까? 아니면 나중에 정렬 매핑 테이블을 빌드하고 캐시해야합니까?

int SortOrder(int radix, int value) 
{ 
    int offset = value % radix;  
    int[] table = {int.MinValue, 4, 2, 6, 0, 5, 1, 3}; // Hand-crafted for base-8 
    return table[offset]; 
} 

답변

-3

내 원래 대답은 최대 델타를 찾는 것이 었습니다. 에서 밖으로에서 당신의 방법을 작동하려면 동일한 비교하지만 서로 다른 선택을 사용

List<double> answer = new List<double>(); 
     List<double> doub = new List<double>() { 0, -1, 2, 3, 4, -5, 7 };//SORT this list for sorted results! 
     List<double> lowerHalf = new List<double>(); 
     List<double> upperHalf = new List<double>(); 
     for (int i = 0; i < doub.Count; i++) 
     { 
      if (i <= (int)Math.Floor((double)doub.Count/2)) 
       lowerHalf.Add(doub[i]); 
      else 
       upperHalf.Add(doub[i]); 
     } 

     if (upperHalf.Count < lowerHalf.Count) 
     { 
      upperHalf.Insert(0,lowerHalf[lowerHalf.Count-1]); 
     } 
     //if(upperHalf[0]==lowerHalf[lowerHalf.Count-1]){double median = lowerHalf[lowerHalf.Count-1]+upperHalf[1])/2;lowerHalf[lowerHalf.Count-1] = median; upperHalf[0]=median;}//use Math.Round or Math.Floor/Ceiling if necessary 
     for (int i = 0; i < lowerHalf.Count; i++) 
     { 
      double deltas = Math.Sqrt(Math.Pow(upperHalf[upperHalf.Count - (i + 1)] - lowerHalf[i], 2)); 
      answer.Add(deltas); 
      Console.WriteLine("The answer for {1}, {2} is: {0}", deltas, lowerHalf[i], upperHalf[upperHalf.Count - (i+1)]); 
     } 



     Console.ReadLine(); 

이것은 제공합니다 :

대답은 0, 7 인 : 7

대답 -1 -5이다 4

답은 2, 4는 다음 2

답은 3, 3은 0

원본 범위에 홀수 개의 항목이있는 경우이 메서드는 위쪽 목록과 아래쪽 목록에 동일한 항목을 사용합니다. 나는 당신의 이익을 위해 "실제"중간을 사용하는 라인

는, 중복 제거 얻을 HashSet의, 노동 조합을 사용하거나 대상을 추가 한 별개의()

원래 대답 - 최대 델타를 찾을 수) :

당신처럼, 당신의 Linq에에서 수학을 사용할 수 있습니다

012 : 당신의 값이 음수 갈 경우, 사각형을 사용해야 할 것

List<double> doub = new List<double>() { 0, 1, 2, 3, 4, 5, 7 }; 
     double deltas = doub.Select(p => p - doub.First()).OrderBy(p => p).Last(); 
     Console.WriteLine("The answer is: {0}",deltas); 
     Console.ReadLine(); 

또는 Math.Abs ​​또는 더 큰 것을보기위한 테스트 - 그러나 시작하는 방법에 대한 아이디어를 제공해야합니다. 번호가 원래 목록에서 순서가 맞지 않으면 선택 전에 orderby를 호출 할 수 있습니다.

그대로 :

  List<double> doub = new List<double>() { 0, 1, 2, 3, 4, 5, 7 }; 
     double deltas = Math.Sqrt(doub.Select(p => Math.Pow(p - doub.First(), 2)).OrderBy(p => p).Last()); 
     Console.WriteLine("The answer is: {0}",deltas); 
     Console.ReadLine(); 

답이

'OilTracker.vshost.exe' (CLR v4.0.30319: OilTracker.vshost.exe): Loaded 'C:\Users\User\Documents\Visual Studio 2015\Projects\OilTracker\OilTracker\bin\Debug\TDAInterface.dll'. Symbols loaded. 
'OilTracker.vshost.exe' (CLR v4.0.30319: OilTracker.vshost.exe): Loaded 'C:\Users\User\Documents\Visual Studio 2015\Projects\OilTracker\OilTracker\bin\Debug\BackFeeder.exe'. Symbols loaded. 

생산 7

리스트 정렬에 앞으로도 이용 :

List<double> answer = new List<double>(); 
     List<double> doub = new List<double>() { 0, 1, 2, 3, 4, 5, 7 }; 
     //sort doub if necessary 
     foreach (double num in doub) 
     { 
      double deltas = Math.Sqrt(Math.Pow(doub.Select(p => p - num).OrderBy(p => p).Last(), 2)); 
      answer.Add(deltas); 
      Console.WriteLine("The answer for {1} is: {0}", deltas,num); 
     } 
     Console.ReadLine(); 

(다시 목록이 순서가 맞지 않으면 다른 orderby를 사용하십시오).

는 생산 :

'OilTracker.vshost.exe' (CLR v4.0.30319: OilTracker.vshost.exe): Loaded 'C:\Users\User\Documents\Visual Studio 2015\Projects\OilTracker\OilTracker\bin\Debug\TDA_Stream_Interface.dll'. Symbols loaded. 
The answer for 0 is: 7 
The answer for 1 is: 6 
The answer for 2 is: 5 
The answer for 3 is: 4 
The answer for 4 is: 3 
The answer for 5 is: 2 
The answer for 7 is: 0 

사각형/제곱근은 우리가 표지판 및 네거티브 필름을 다루는 데 도움이 - 그래서

List<double> doub = new List<double>() { 0, -1, 2, 3, 4, -5, 7 }; 

가 생산 :에없는

The answer for 0 is: 7 
The answer for -1 is: 8 
The answer for 2 is: 5 
The answer for 3 is: 4 
The answer for 4 is: 3 
The answer for -5 is: 12 
The answer for 7 is: 0 

(주문을 인바운드 또는 아웃 바운드 쪽에서 정렬하지 못했기 때문에).

실행 후 "응답"목록에 결과가 포함됩니다. 가장 낮은 델타는 answers.First() 및 answers.Last()에서 가장 높게 액세스 할 수 있습니다. 비슷한 수의 단위에 대해 동일한 수의 델타가 존재합니다. 중복 델타를 제거하려는 경우 수식에서 HashSet 변환을 사용할 수 있습니다. 도움이 필요하면 알려주세요.

델타와 델타 자체를 만든 번호를 저장해야하는 경우에는 For/Each 루프에서 Console.WriteLine()이 나타내는대로 사용할 수 있습니다.

중앙값의 양쪽에서 범위 - 중간 값을 사용하려면 목록을 분리하여 쌍으로 작업하는 것이 좋습니다. 하나의 목록에서 중앙값을 0으로 만들고 두 번째 목록에서 중간 값을 endRange로 만들고 첫 번째 및 두 번째 목록에서 계산합니다. 이것은 당신을 거기에 데려다 줄 것이다. 그러나 만일 당신이 그 최종 고비를 극복하는 데 도움이 필요하면, 나에게 알려주세요.

희망이 도움이됩니다!

+0

무엇이 double로 'p.First()'입니까? –

+0

p.First는 정렬 할 목록의 첫 번째 항목입니다 (이 경우 num). nums.Select (p => p.First())는 목록의 첫 번째 항목에서 각 항목의 델타 목록을 선택합니다. 당신은 그것을 실행할 수 있고 당신은 dv를 체크 할 수 있습니다 - 대답은 7입니다. –

+1

게시하기 전에 코드를 테스트하지 않은 것처럼 보입니다. 아니요, 컴파일 할 수 없습니다 .... –

-1

답변을 신속하게 찾으려하지 않으므로이 질문에 대한 답변이 아닙니다. 오히려 각 기수에 대해 캐시 된 정렬 값의 사전을 빌드합니다.

#region sorting logic 
/// <summary> 
/// Maintains a collection of sorting maps for all used number bases. 
/// </summary> 
private static readonly Dictionary<int, int[]> _sortingTable = new Dictionary<int, int[]>(); 
private static readonly object _sortingLock = new object(); 

/// <summary> 
/// Compute the sorting key for a given multiple. 
/// </summary> 
/// <param name="radix">Radix or base.</param> 
/// <param name="multiple">Multiple.</param> 
/// <returns>Sorting key.</returns> 
public static int ComputeSortingKey(int radix, long multiple) 
{ 
    if (radix < 2) 
    throw new ArgumentException("Radix may not be less than 2."); 

    if (multiple == 0) 
    return int.MinValue; // multiple=0 always needs to be sorted first, so pick the smallest possible key. 

    int[] map; 
    if (!_sortingTable.TryGetValue(radix, out map)) 
    lock (_sortingLock) 
    { 
     map = new int[radix]; 
     map[0] = -1; // Multiples of the radix are sorted first. 

     int key = 0; 
     HashSet<int> occupancy = new HashSet<int> { 0, radix }; 
     HashSet<int> collection = new HashSet<int>(1.ArrayTo(radix)); // (ArrayTo is an extension method in this project) 
     while (collection.Count > 0) 
     { 
     int maxValue = 0; 
     int maxDistance = 0; 
     foreach (int value in collection) 
     { 
      int distance = int.MaxValue; 
      foreach (int existingValue in occupancy) 
      distance = Math.Min(distance, Math.Abs(existingValue - value)); 

      if (distance > maxDistance) 
      { 
      maxDistance = distance; 
      maxValue = value; 
      } 
     } 
     collection.Remove(maxValue); 
     occupancy.Add(maxValue); 
     map[maxValue] = key++; 
     } 

     _sortingTable.Remove(radix); // Just in case of a race-condition. 
     _sortingTable.Add(radix, map); 
    } 

    long offset = multiple % radix; 
    if (offset != 0) 
    if (multiple < 0) 
     offset = radix - (Math.Abs(multiple) % radix); 

    return map[(int)offset]; 
} 
#endregion