2013-08-15 3 views
0

привет мне нужно найти самую большую плотную область в список значений на основе заданного диапазонаКак найти плотную область в списке <int>

пример:

var radius =5; //Therm edited 
var list = new List<int>{0,1,2,3,4,5,12,15,16,22,23,24,26,27,28,29}; 

//the following dense regions exist in the list above 
var region1 = new List<int> { 0, 1, 2, 3, 4, 5 };   // exist 6 times (0, 1, 2, 3, 4, 5) 
var region2 = new List<int> { 12, 15, 16};     // exist 3 times (12, 15, 16) 
var region3 = new List<int> { 22, 23, 24, 26, 27};   // exist 1 times (22) 
var region4 = new List<int> { 22, 23, 24, 26, 27, 28};  // exist 1 times (23) 
var region5 = new List<int> { 22, 23, 24, 26, 27, 28, 29 }; // exist 3 times (24, 26, 27) 
var region6 = new List<int> { 23, 24, 26, 27, 28, 29 };  // exist 1 times (28) 
var region7 = new List<int> { 24, 26, 27, 28, 29 };   // exist 1 times (29) 

//var result{22,23,24,26,27,28,29} 

решение не действительно нужно быть быстрым, потому что максимальное количество значений равно 21 есть ли способ свободно использовать это?

я только знаю, как получить наиболее близкое значение

int closest = list.Aggregate((x,y) => Math.Abs(x-number) < Math.Abs(y-number) ? x : y); 

и как получить значения от 2-х номеров

var between = list.Where(value=> min < value && value < max); 

Редактировать

дополнительной информации заключается в

Ok диапазон возможно, неправильный термометр Радиус был бы лучшим словом.

Я определяю плотную область в качестве наибольшего кола всех значений между currenvalue-диапазоном и currenvalue + диапазоном мы получим область плотной

+0

Что вы подразумеваете под * cluster * Это набор последовательных элементов, которые попадают в '2 * range'? –

+0

@ JoachimIsaksson диапазон будет задан алгоритмом, и не нужно беспокоиться об этом ^^ – WiiMaxx

+0

@ lazyberezovsky, так, другими словами, самая большая последовательность чисел, которые в данном случае не более 10 друг от друга? –

ответ

4

Довольно загадочный (но короткий) путь будет:

int w = 5; // window size 
var list = new List<int> { 0, 1, 2, 3, 4, 5, 12, 15, 16, 22, 
          23, 24, 26, 27, 28, 29 }; 

var result = list.Select(x => list.Where(y => y >= x - w && y <= x + w)) 
       .Aggregate((a, b) => (a.Count() > b.Count()) ? a : b); 

Console.WriteLine(string.Join(",", result.ToArray())); 

печать

22,23,24,26,27,28,29 

Этот код состоит из 3 этапов:

  • Для данного x фрагмент list.Where(y => y >= x - w && y <= x + w) содержит все элементы из списка, которые находятся в кластере около x.
  • list.Select(x => ...) вычисляет этот кластер для каждого элемента списка.
  • .Aggregate((a, b) => (a.Count() > b.Count()) ? a : b) берет кластер максимального размера.
+0

работает очень хорошо спасибо – WiiMaxx

+1

Вы можете просто использовать 'Max' вместо агрегата. Это не позволит вам потребовать повторить в два раза больше исходных последовательностей, сколько вам нужно. Также обратите внимание, что это метод грубой силы вообще; вы вычисляете все значения, а затем находите лучшее. Это намного менее результативно, чем вы могли бы получить, поэтому, если это нужно масштабировать, это не произойдет. – Servy

+0

@Servy мы не можем использовать 'Max' здесь напрямую, потому что нам нужно сравнить значения' Count() '. Я согласен с тем, что это не эффективное решение, но ОП прямо заявляет, что эффективность не является проблемой. –

Смежные вопросы