Как мне проверить, содержит ли int[] только определенные числа?
Мне нужно проверить, что int[] содержит только определенные значения (в данном случае 0s & 1s) и выдать исключение, если это не так.
Есть ли более эффективный способ сделать это, чем любое из следующих решений?
Простой (но O(n)):
for(int n = 0; n < myArray.Length; n++)
if(!(myArray[n] == 0 || myArray[n] == 1))
throw new Exception("Array contains invalid values");
Используя Where():
if(myArray.Where(n => !(n==1 || n==0)).ToArray().Length > 0)
throw new Exception("Array contains invalid values");
3 ответа
Вы не можете проверить массив, не просматривая его. Так O(n)
это лучшее, что вы собираетесь получить. Другим решением было бы контролировать загрузку массива и выдавать исключение, когда кто-то пытается ввести значение, которое не является 0
или же 1
в этом. Другим решением может быть использование bool[]
который в любом случае имеет только два возможных значения, но потребует некоторого преобразования, если вам действительно нужны числа. (Примечание: если вам нужно более двух значений, возможно, имеет смысл рассмотреть enum
особенно если эти значения должны что-то представлять)
Также, Where
это не лучшее решение, потому что вы вынуждены проверить весь массив (без досрочного выхода). использование Any
вместо этого (но он все еще делает в основном то, что делает ваш цикл for - лучший случай O(1)
, хуже O(n)
средний O(n)
).
if (myArray.Any(a => a != 0 && a != 1))
{
// ....
}
Вы можете попробовать использовать Array.TrueForAll
:
if (!Array.TrueForAll(myArray, n => n == 0 || n == 1))
throw new Exception("Array contains invalid values");
Вот исследование блога по вашему вопросу http://www.tkachenko.com/blog/archives/000682.html
проверено на
int[] data = new int[100000000];
если вы действительно заинтересованы в производительности, вы не должны использовать Any() наверняка)))))
так что, поскольку вам нужно искать значения пары в массиве, для вас наилучшим вариантом является поиск по циклу или foreach (в вашем случае int[], скомпилированный в CIL как цикл).
foreach loop search: 39 ms
for loop search: 39 ms
Contains() method search: 56 ms
Any() method search: 446 ms
IndexOf() method search: 57 ms