Как мне проверить, содержит ли 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
Другие вопросы по тегам