2015-11-18 20 views
5

Ho bisogno di verificare che un int [] contenga solo determinati valori (in questo caso 0s & 1s) e genera un'eccezione se non lo fa.Come posso verificare se int [] contiene solo determinati numeri?

Esiste un modo più efficiente per farlo rispetto a una delle seguenti soluzioni?

semplice (ma O (n)):

for(int n = 0; n < myArray.Length; n++) 
    if(!(myArray[n] == 0 || myArray[n] == 1)) 
     throw new Exception("Array contains invalid values"); 

Utilizzando Dove():

if(myArray.Where(n => !(n==1 || n==0)).ToArray().Length > 0) 
    throw new Exception("Array contains invalid values"); 
+0

Interrompere l'elaborazione quando si incontra un valore non valido o si desidera convalidare l'intera raccolta? – BentOnCoding

+0

Sotto i vincoli, il tuo ciclo 'for' è il meglio che puoi ottenere. Sembra che tu pensi che LINQ possa fare "magia" perché non hai detto O (N) per "usare Dove()" –

+3

Inoltre, non posso fare a meno di pensare a [questo] (http: //i.imgur. com/dAEp7Wu.jpg? 1) –

risposta

12

Non è possibile controllare un array senza l'iterazione attraverso di essa. Quindi O(n) è il meglio che otterrai. L'altra soluzione sarebbe controllare il caricamento dell'array e generare un'eccezione quando qualcuno tenta di inserire un valore che non sia 0 o 1 in esso. Un'altra soluzione potrebbe essere quella di utilizzare uno bool[] che ha comunque solo due valori possibili, ma che richiederebbe una conversione se effettivamente avete bisogno di numeri. (Nota: se avete bisogno di più di due valori, potrebbe avere senso per guardare un enum, soprattutto se si suppone quei valori per rappresentare qualcosa)

Inoltre, Where non è la soluzione migliore qui perché si è costretti per controllare l'intero array (nessuna uscita anticipata). Utilizzare invece Any (ma sta ancora facendo in pratica ciò che fa il ciclo for - best case O(1), peggio O(n) medio O(n)).

if (myArray.Any(a => a != 0 && a != 1)) 
{ 
    // .... 
} 
+0

Grazie per il puntatore verso Qualsiasi() Devo attenersi a ints, come il resto del programma si basa su di loro. – LeftRight92

0

È possibile tenta di utilizzare Array.TrueForAll:

if (!Array.TrueForAll(myArray, n => n == 0 || n == 1)) 
    throw new Exception("Array contains invalid values"); 
+0

Per documentazione MSDN qui: https://msdn.microsoft.com/en-us/library/kdxe4x4w(v=vs.110).aspx Questo è ancora O (n), anche se è almeno un pulitore comunque. – user2366842

0

Ecco blog ricerca post in base alla tua domanda http://www.tkachenko.com/blog/archives/000682.html

testato su

int[] data = new int[100000000]; 

se siete veramente interessati in termini di prestazioni non dovresti usare Any() di sicuro)))))

così tanto che è necessario cercare i valori di coppia nell'array lo stato di unswer è - per la ricerca del ciclo o foreach (nel caso di int [] compilato nel ciclo CIL as for) è il migliori opzioni per voi

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 
+2

'non dovresti usare Any() per sicuro', se non hai un array di 100 milioni di elementi, non me ne preoccuperei a meno che non venga rivelato un * collo di bottiglia * reale * nel tuo * codice reale * . –

+0

@MattBurland hai ragione, ma ho scritto "se sei veramente interessato alle prestazioni ...", anche se dai un'occhiata a Any() compilato nel CIL vedrai come Any() si differenzia dal per i numeri di loop e test mostrano questa differenza sulla pratica – makison

Problemi correlati