Можно ли использовать LINQ для поиска пробелов в отсортированном списке?
Возможно ли использовать LINQ таким образом, чтобы я мог определить, что "9"
является первым отсутствующим значением в отсортированном списке без использования цикла for и сравнения каждого значения с соседним с ним?
var listStringVals = new [] { "7", "13", "8", "12", "10", "11", "14" };
// sort list to "7","8","10","11","12","13","14"
var sortedList = listStringVals.OrderBy(c => int.Parse(c)).ToList();
// need some magic here to get the first gap in the sorted list
Ответы
Ответ 1
Пусть
var strings = new string[] { "7", "13", "8", "12", "10", "11", "14" };
Тогда
var list = Array.ConvertAll(strings, s => Int32.Parse(s)).OrderBy(i => i);
// or
var list = strings.Select(s => int.Parse(s)).OrderBy(i => i);
// or
var list = strings.OrderBy(s => int.Parse(s));
(обратите внимание на этот вопрос)
а затем
var result = Enumerable.Range(list.Min(), list.Count).Except(list).First(); // 9
// or
int min = list.Min(), max = list.Max();
var result = Enumerable.Range(min, max - min + 1).Except(list).First();
Ответ 2
Здесь вы можете начать (я использовал здесь значения int
):
List<int> listStringVals = (new int[] { 7, 13, 8, 12, 10, 11, 14 }).ToList();
List<int> SortedList = listStringVals.OrderBy(c => c).ToList();
List<int> Gaps = Enumerable.Range(SortedList.First(),
SortedList.Last() - SortedList.First() + 1)
.Except(SortedList).ToList();
Ответ 3
var listStringVals = new string[] {"7", "13", "8", "12", "10", "11", "14"};
var sortedInts = listStringVals.Select(c => int.Parse(c)).OrderBy(x => x);
var noGaps = Enumerable.Range(sortedInts.First(),
sortedInts.Last() - sortedInts.First() + 1);
var missing = noGaps.Except(sortedInts).Select(x => x.ToString()).First();
Изменить: создание фиксированного диапазона благодаря Ответу BeemerGuy. Все еще оставляя мое, так как он не игнорирует уродство списка представлений string
int
:)
Ответ 4
(абатищев избил меня до удара, но его ответ в любом случае лучше. Однако, поскольку альтернативные решения одной и той же проблемы могут быть забавными, я все равно размещаю это.)
Взламывание взлома. Но работайте, если вы действительно хотите это сделать. Производительность будет ужасной, потому что эта техника не остановится, когда найдет ответ - она всегда будет перебирать все числа! Но он будет работать:
public static int FindFirstMissing(IEnumerable<int> sequence)
{
bool found = false;
int agg = sequence.Aggregate((aggregate, next) => {
if (found)
return aggregate;
if (next - aggregate != 1) {
found = true;
return aggregate + 1;
}
return next;
});
if (!found)
throw new ArgumentException("sequence", "Contains no missing numbers.");
return agg;
}
Ответ 5
string firstGap = sortedList
.Zip(sortedList.Skip(1), (f, s) => Tuple.Create(f, s))
.First(tup => (int.Parse(tup.Item1) + 1) != int.Parse(tup.Item2)).Item1;
Должен дать вам первый элемент перед первым зазором, поэтому первый отсутствующий элемент:
string gap = (int.Parse(firstGap) + 1).ToString();
Ответ 6
Немного поздно, но я думаю, что это классный способ сделать это:
List<int> listStringVals = (new int[] { 7, 13, 8, 12, 10, 11, 14 }).ToList();
listStringVals.Sort();
return listStringVals.Skip(1).Select((x, i) => x - listStringVals[i] == 1).Any(x => !x);
Ответ 7
Почему бы просто не использовать All
, поскольку все члены коллекции должны соответствовать критериям...
Пример
someVar.All(v => someVar.Contains(v + 1) || v == someVar.Last())
Тогда вам не нужно заказывать и лучше.
Вы можете сортировать после этого шага или даже во время, если вам нужно, но я лично просто использую отсортированную коллекцию и сделаю это для меня.
Вы могли бы получить значения, если вам нужно после выполнения проверки, а затем вернуть результат проверки или скрыть ее, если хотите по какой-либо причине с помощью многострочной модификации выше вместе со списком для хранения значений в.
например.
someVar.All((v) => {
bool result = someVar.Contains(v + 1) || v == someVar.Last();
if(!result) someList.Add(v);
return true;
});
Проверка счетчика списка (который может быть заказан) для ненулевого значения, чтобы указать, удовлетворен ли он или нет.