10
votes

Quel est le moyen rapide d'obtenir un index d'un élément dans un tableau?

On m'a posé cette question dans une interview. Bien que l'entretien soit pour la position de Dot Net, il m'a posé cette question dans le contexte de Java, car j'avais mentionné Java également dans mon CV.

Comment trouver l'index d'un élément ayant une valeur x dans un tableau?

J'ai dit itération du premier élément jusqu'à la dernière fois et vérifiez si la valeur est X donnerait le résultat. Il a posé une question sur une méthode impliquant moins de nombre d'itérations, j'ai dit à l'aide de la recherche binaire mais qui n'est possible que pour le tableau trié. J'ai essayé de dire en utilisant l'index de la fonction dans la classe Array. Mais rien de mon côté n'a répondu à cette question.

Y a-t-il un moyen rapide d'obtenir l'index d'un élément ayant une valeur x dans un tableau?


6 commentaires

Cela ressemble à une mauvaise façon d'interviewer les candidats IMHO


@Samuel_xl pourquoi? Quel est le problème avec la question?


Je pense que l'index de la méthode fera également une itération sur la matrice. Ne pensez pas qu'il y ait un tel moyen rapide de le faire.


Si vous pouviez en quelque sorte mettre en oeuvre l'algorithme de grofre en Java, vous pouvez faire mieux. Je suppose que vous avez besoin d'un appel JNI vers l'ordinateur quantique sous-jacent. Non indépendant de la plate-forme.


@emory: Trop de voyage trop chronologique spécifique.


Peut-être voulait-il que vous fassiez un haschmap inversé redondant?


10 Réponses :


16
votes

Tant qu'il n'y a aucune connaissance de la matrice (est-elle triée? Ascendant ou descendant? etc), il n'y a aucun moyen de trouver un élément sans inspecter chacun.

En outre, c'est exactement ce que indexof fait (lors de l'utilisation des listes).


4 commentaires

"... sans inspecter chacun jusqu'à ce que vous le trouviez.", En fait. Si votre élément est le premier, vous n'avez pas besoin d'inspecter chaque élément N le tableau / liste.


Désolé, je pensais que c'était évident! Toute personne qui ne vous dérange pas que dans sa mise en œuvre ne mérite pas de le courir ...


Mais cela ne signifie pas que cela ne pouvait pas être fait plus vite, c'est-à-dire par la parallélisation.


La parrabialisation n'est que potentiellement plus rapide. Si l'article se trouve à proximité du début de la matrice, vous effectuez plus de travail pour parrelaliser la tâche que de commencer à rechercher le tableau. La parrelalisation n'est pas une balle magique qui rend tout ce qui est plus rapide, il vaut mieux pour les grandes tâches, mais il y a un coût des frais généraux qui le rend moins efficace pour les petites tâches.



1
votes

Puneet - En .NET Son: XXX PRE>

[EDIT] STRORT> - Ayant lu la question correctement, :) Une alternative à Linq serait: P>

string[] testArray = { "cat", "dog", "banana", "orange" };
int firstItem = testArray.Select((item, index) => new
{
    ItemName = item,
    Position = index

}).Where(i => i.ItemName == "banana")
  .First()
  .Position;


5 commentaires

Cette méthode n'existe pas dans Java ... a) Quelle classe de tableau utilisez-vous? b) Les noms de méthodes ne commencent pas avec des lettres majuscules en Java


Il semble que vous n'avez pas lu la question entière, je leur ai demandé d'utiliser la fonction index de l'index, mais ils me demandaient d'écrire la logique moi-même. Ils disaient que la boucle simple que vous avez écrite est correcte, mais cela peut être amélioré et réalisé en moins d'itérations. Pensez-y juste !!!


F1SH - Oups, correct et corrigé ... Puneet - oui, peut voir cela maintenant. Un peu précipité ça un peu !!


@Puneet Dudeja Eh bien, puisque il n'est pas possible de le faire en moins d'itérations, ils voulaient que vous le disiez et expliquez pourquoi. Soit cela ou ils sont tout simplement faux.


C'est fondamentalement le opposé de ce que veut (!); Vous ajoutez simplement plus surcharge (la construction de nombreux nouveaux objets de type anonyme) à ce qui est effectivement toujours la détermination de l'indice d'un élément par dénombrement (en utilisant où / Premier ).



3
votes

Si une recherche binaire n'est pas possible (Beacuse le tableau n'est pas trié) et vous n'avez pas une sorte d'index de recherche avancé, la seule façon dont je pouvais penser que ce n'est pas O (n ) Si la position de l'élément dans la matrice est une fonction de l'élément lui-même (comme si le tableau est [10, 20, 30, 40] , la position d'un élément < code> n est (n / 10) - 1 ).


2 commentaires

Avoir la valeur d'un tableau dépend de son indice est une sorte de tri - au moins vous donne une très bonne idée de la manière dont les éléments sont disposés.


C'est fondamentalement comment fonctionne les tables de hasards.



1
votes

C'est une question sur les structures et les algorithmes de données (algorithlore une structure de données très simple). Il va au-delà de la langue que vous utilisez.

Si le tableau est commandé, vous pouvez obtenir O (journal N) à l'aide de la recherche binaire et une version modifiée de celle-ci pour les cas de frontière (sans utiliser toujours (A + B) / 2 comme point de pivotement, mais c'est une quirk assez sophistiquée. ).

Si le tableau n'est pas commandé, alors ... bonne chance.

Il peut vous poser des questions sur les méthodes que vous avez pour trouver un article en Java. Mais de toute façon ils ne sont pas plus rapides. Ils peuvent être plus simples d'olny à utiliser (qu'un pour chacun - comparer - retour).

Il existe une autre solution qui crée une structure auxiliaire pour effectuer une recherche plus rapide (comme un hashmap) mais, bien sûr, il est plus coûteux de le créer et de l'utiliser une fois de faire une simple recherche linéaire.


1 commentaires

Je pense que vous vouliez dire O (log n) pour un tableau commandé.



0
votes

Prenez un tableau parfaitement non formé, juste une liste de chiffres en mémoire. Toute la machine peut faire est de regarder des nombres individuels en mémoire et de vérifier s'ils sont le bon nombre. C'est le "problème du biscuit de mot de passe". Il n'y a pas de moyen plus rapide que de rechercher depuis le début jusqu'à ce que la valeur correcte soit touchée.


0 commentaires

0
votes

Êtes-vous sûr de la question? J'ai quelque peu des questions similaires à votre question.

Compte tenu d'un tableau trié, il y a un élément "X" dont la valeur est identique que son index trouver l'index de cet élément. p>

Par exemple: P>

         //0,1,2,3,4,5,6,7,8,9, 10     
int a[10]={1,3,5,5,6,6,6,8,9,10,11};


2 commentaires

Quelle serait une réponse correcte à votre question? Y a-t-il un moyen de faire cela


Autant que je me souvienne, la question était de savoir ce que j'ai demandé ici, car je l'ai confirmé 2 à 3 fois avant de répondre.



9
votes

Un moyen pratique de la trouver plus rapidement est par traitement parallèle.

Divisez simplement la matrice en n parties et attribuez chaque partie à un fil qui itère à travers les éléments de sa pièce jusqu'à ce que la valeur soit trouvée. N devrait de préférence être le nombre de cœurs du processeur.


5 commentaires

Bonne idée. Mais est-il vraiment utile de l'adapter à l'utilisation du noyau du processeur? Le VM ne divise pas le fil de manière égale parmi tous les cœurs ou le fait-il?


Java a le parallélarray (générique) et Parallellongrama (primitif) pour cela. gee.cs.oswego.edu/dl/jsr166/ dist / extra166YDOCS / extra166Y / ... . L'opération est implémentée à l'aide du système N partitions.


@ F1SHSH - En pratique (sous Windows, où la plupart de mes expériences réside), vous trouverez une utilisation de la CPU peut approcher 100% pour tous les noyaux lors de l'utilisation d'un ForkjoinPool dimensionné au nombre de cœurs disponibles. Et cela vous donne également l'avantage d'utiliser davantage de cache L1 qu'avec le boîtier à une seule-thread, qui puisque L1 est généralement dédié à chaque noyau / paire de cœurs.


C'est la responsabilité du VM. En général, l'utilisation de plusieurs threads sur un processeur multicœur doit toujours être plus rapide qu'un seul fil. (Cela ignore les frais généraux de diviser la matrice et de commencer les threads. Le tableau doit bien sûr être suffisamment important pour justifier la parallélisation).


Pour un plus grand parallélisme, vous pouvez toujours affecter le travail à un GPU ou deux: JCuda.de



12
votes

Comment trouver l'index d'un élément ayant une valeur x dans un tableau?

Ce serait rapide: xxx


3 commentaires

Votre fonction doit recevoir le tableau en tant que paramètre. Autre que cela, une excellente réponse (qui illustre également un danger de TDD) :)


Je dois commencer à écrire mon code comme celui-ci - ça sauve tellement de temps.


@fortran, vous faire réalisez que l'aide de Hover-Help pour le bouton UPVote dit "utile" plutôt que "drôle", oui? Je suis tout pour l'humour mais, à moins que cela ne concerne avec une réponse utile réelle , il est probablement préférable de laisser dans un commentaire :-)



2
votes

Peut-être qu'il veut tester vos connaissances sur Java.

Il existe une classe d'utilité appelée tableaux, cette classe contient diverses méthodes permettant de manipuler des tableaux (tels que le tri et la recherche) p>

http://download.oracle.com/javase/6/docs/api /java/util/arrays.html p>

en 2 lignes Vous pouvez avoir un résultat O (n * journal n): p>

    Arrays.sort(list); //O(n * log n)
    Arrays.binarySearch(list, 88)); //O(log n)


6 commentaires

Le tri est déjà O (n * journal (n)) dans le meilleur cas pour Mergesort (c'est-------t-être implémenté dans Java Utils si je me souviens bien), votre solution est donc pire que linéaire ( O (n * journal (n) ^ 2) en effet).


devrait être O (n journal n) car le tri (supposant le modèle de comparaison) prend O (n journal n) et la recherche binaire est O (log n) de sorte que le total est O (logn + nlogn) = O (nlogn)


@Ahmed tu es tout à fait raison! Je tiens à mettre à jour mon commentaire mais le temps d'édition a expiré: -s


Vous avez raison Ahmed, je pensais que dans le problème de recherche. Je l'ai réparé, merci.


Extrait de la documentation: Trie le tableau spécifié d'octets en ordre numérique ascendant. L'algorithme de tri est ajusté Quicksort , adapté de Jon L. Bentley et de la "Fonction de la fonction de tri" de M. Douglas Mcilroy ", de la pratique logicielle et de l'expérience, vol. 23 (11) P. 1249-1265 (novembre 1993). Cet algorithme propose des performances N * journal (n) sur de nombreux ensembles de données entraînant une dégradation d'autres films rapides à des performances quadratiques.


Le problème avec c'est que c'est ne vous vous donne la position de l'élément dans la matrice comme demandé, simplement parce que Cela change l'ordre du tableau! Il n'y a pas de relation entre l'index après le tri et l'index avant le tri.



0
votes

Si les informations seules que vous avez est le fait qu'il s'agit d'une matrice non formée, sans releverions entre l'index et la valeur, et sans structures de données auxiliaires, vous devez éventuellement examiner chaque élément pour voir s'il détient les informations souhaitées.

Cependant, les entretiens sont censés séparer le blé de la palette de la paille, il est donc important de se rendre compte qu'ils veulent voir comment vous approchez des problèmes. Par conséquent, l'idée est de poser des questions à voir si plus d'informations est (ou pourrait être apportée) disponible, des informations pouvant rendre votre recherche plus efficace.

Questions comme:


1 / fait que les données changent-t-il très souvent?

Sinon, vous pouvez utiliser une structure de données supplémentaire.

Par exemple, maintenez un drapeau Dirty qui est initialement vrai. Lorsque vous souhaitez trouver un article et qu'il est vrai, construisez cette structure supplémentaire (tableau triée, arborescence, hachage ou autre) qui accéléreront considérablement les recherches, puis définissez le drapeau sale sur false, puis utilisez-le. structure pour trouver l'article.

Si vous souhaitez trouver un élément et que le drapeau sale est faux, utilisez simplement la structure, pas besoin de le reconstruire.

Bien sûr, toutes les modifications apportées aux données doivent définir le drapeau sale sur TRUE afin que la recherche suivante reconstruit la structure.

Cela accélérera grandement (par l'amortissement) des requêtes pour des données qui sont lues beaucoup plus souvent que écrites.

En d'autres termes, la première recherche après une modification sera relativement lente mais les recherches ultérieures peuvent être beaucoup plus rapides.

Vous voudrez probablement envelopper le tableau à l'intérieur d'une classe afin que vous puissiez contrôler correctement le drapeau sale .


2 / sommes-nous autorisés à utiliser une structure de données différente d'une matrice brute?

Ce sera similaire au premier point donné ci-dessus. Si nous modifions la structure de données d'un tableau dans une classe arbitraire contenant le tableau, vous pouvez toujours obtenir tous les avantages tels que l'accès aléatoire rapide à chaque élément.

Mais nous gain la possibilité de mettre à jour des informations supplémentaires dans la structure de données chaque fois que les données changent.

Ainsi, plutôt que d'utiliser un drapeau Dirty et de faire une mise à jour gros à la recherche suivante, nous pouvons faire petits modifications apportées à l'extra informations chaque fois que le tableau est modifié.

Cela se débarrasse de la réponse lente de la première recherche après une modification en amortissant le coût de tous les changements (chaque changement ayant un petit coût).


3. Combien d'articles seront généralement dans la liste?

Ceci est en fait plus important que la plupart des gens réalisent.

Tous les discussions d'optimisation ont tendance à être inutiles à moins que vos ensembles de données soient relativement importants et que la performance est en réalité importante.

Par exemple, si vous avez un tableau de 100 items, il est tout à fait acceptable d'utiliser même le tri des bulles morfains, car la différence de minutage entre cela et le tri le plus rapide que vous puissiez trouver a tendance à être non pertinents (à moins que vous n'ayez besoin de Faites-le des milliers de fois par seconde bien sûr).

Pour ce cas, rechercher le premier index pour une valeur donnée, il est probablement parfaitement acceptable de faire une recherche séquentielle tant que votre réseau reste sous une certaine taille.


Le résultat final est que vous êtes là pour prouver votre valeur et que l'intervieweur est (généralement) pour vous guider. À moins qu'ils ne soient sadistes, ils sont assez heureux que vous leur posiez des questions pour essayer d'affiner la portée du problème.

demander les questions (comme vous avez la possibilité que les données puissent être triées. Ils doivent être impressionnés par votre approche même si vous ne pouvez pas trouver avec un Solution.

En fait (et j'ai fait cela dans le passé), ils peuvent rejeter toutes vos approches possiales (non, cela n'est pas trié, non, aucune autre structure de données n'est autorisée, etc.) Juste pour voir à quelle distance vous obtenir.

Et peut-être, juste peut-être, comme le kobayashi maru, il ne s'agissait peut-être pas de gagner, c'est ainsi que vous traitez avec l'échec: -)


0 commentaires