J'aimerais me considérer comme un programmeur assez expérimenté. Je programme depuis plus de 5 ans maintenant. Mon point faible est cependant la terminologie. Je suis autodidacte, alors même si je sais programmer, je ne connais pas certains des aspects les plus formels de l'informatique. Alors, quels sont les algorithmes/structures de données pratiques que je pourrais reconnaître et connaître par leur nom?
Remarque, je ne demande pas de recommandation de livre sur l'implémentation d'algorithmes. Je ne me soucie pas de les implémenter, je veux juste pouvoir reconnaître quand un algorithme/une structure de données serait une bonne solution à un problème. Je demande davantage une liste d'algorithmes/structures de données que je devrais "reconnaître". Par exemple, je connais la solution à un problème comme celui-ci:
Vous gérez un ensemble de casiers étiquetés 0-999. Les gens viennent chez vous pour louer le casier puis reviennent pour rendre la clé du casier. Comment construiriez-vous un logiciel pour gérer en sachant quels casiers sont gratuits et lesquels sont utilisés?
La solution serait une file d'attente ou une pile.
Ce que je recherche, ce sont des choses comme "dans quelle situation un arbre B doit-il être utilisé - quel algorithme de recherche doit être utilisé ici", etc. les algorithmes fonctionnent.
J'ai essayé de regarder la liste de Wikipedia de structures de données et algorithmes mais je pense que c'est un peu exagéré. Je cherche donc plus quelles sont les choses essentielles que je devrais reconnaître?
Alors que ma réponse initiale à cette question était basée sur mon expérience empirique en tant qu'étudiant CS bientôt diplômé et sur mon opinion projetée sur le type de personnes avec lesquelles je voulais travailler dans le domaine CS. Il y a en fait une réponse objective (par rapport aux opinions subjectives des sociétés informatiques ACM SIGCSE et IEEE). Tous les 10 ans, les corps ACM et IEEE coopèrent sur un publication conjointe qui détaille des suggestions pour un programme de premier cycle en informatique basé sur une connaissance professionnelle de l'état de l'industrie informatique. Plus d'informations peuvent être trouvées sur cs2013.org . Le comité publie un rapport final énumérant la recommandation de leur programme d'études .
Cela dit, je pense toujours que ma liste est assez bonne.
Réponse originale ci-dessous.
Je pense qu'un programmeur adepte devrait avoir au moins des connaissances de premier cycle en informatique. Bien sûr, vous pouvez être efficace dans de nombreux emplois avec seulement un petit sous-ensemble d'informatique en raison de la communauté solide comme CS et de la focalisation restreinte de la plupart des postes professionnels. En outre, de nombreuses personnes se spécialiseront davantage après des études de premier cycle. Cependant, je ne pense pas non plus que ce soit une excuse pour ne pas être au courant des connaissances fondamentales de la CS.
Pour répondre à la question du titre, voici ce qu'un étudiant CS de premier cycle (la base d'un programmeur adepte) devrait savoir lors de l'obtention de son diplôme:
Pour entrer dans ce que vous demandez plus tard dans votre question, si vous êtes familier avec ce qui précède, vous devriez être en mesure d'identifier facilement le modèle, l'algorithme et la structure de données appropriés pour un scénario donné. Cependant, vous devez reconnaître qu'il n'y a souvent pas de meilleure solution. Parfois, vous devrez peut-être choisir le moindre de deux maux ou même simplement choisir entre deux solutions également viables. Pour cette raison, vous avez besoin des connaissances générales pour pouvoir défendre votre choix contre vos pairs.
Voici quelques conseils pour les algorithmes et les structures de données:
Certains des éléments ci-dessus peuvent sembler évidents, et certains peuvent sembler vagues. Si vous voulez que j'entre dans les détails, je le peux. Mais, j'espère que lorsque vous rencontrez une question plus concrète telle que "Concevoir une fonction qui compte le nombre d'occurrences de chaque caractère dans une chaîne", vous regardez la pointe sur le ASCII table et 128 tableaux d'éléments formant des tables de hachage implicites soignées pour la réponse.
Sur la base de ces idées, je proposerai une réponse au problème de casier décrit dans votre question.
Ce n'est peut-être pas la meilleure réponse à votre question, mais je pense que c'est une réponse intéressante qui ne nécessite rien de trop complexe. Et cela dépassera certainement la complexité temporelle de l'utilisation d'une file d'attente ou d'une pile qui nécessite un temps linéaire pour déterminer si un casier est libre ou non.
Vous avez 0 à 999 casiers. Maintenant, comme vous avez un nombre fixe de casiers, vous pouvez facilement concevoir une fonction de hachage sans collision sur la plage 0-999. Cette fonction est simplement h(x) = x mod 1000. Maintenant, [conceptuellement] construisez une table de hachage avec des clés entières et le contenu d'un tableau de caractères de 1000 éléments comme vos valeurs. Si un client souhaite réserver le casier 78, utilisez simplement 78 dans la fonction de hachage (retour 78), puis ajoutez ce nombre au pointeur de base du tableau - en stockant une valeur vraie à l'emplacement indiqué par la valeur de décalage. De même, si vous avez besoin de vérifier si 78 est en cours d'utilisation, il vous suffit de lire la valeur stockée à cet emplacement et de vérifier par rapport à true.
Cette solution fonctionne en temps constant pour les recherches et le stockage, par opposition à un stockage et une recherche de temps log (n) dans le cas d'une file d'attente prioritaire soutenue par un arbre binaire. La description est intentionnellement verbeuse afin que vous puissiez voir les concepts supérieurs se résumer en un algorithme efficace.
Maintenant, vous pourriez vous demander, si j'ai besoin de connaître tous les casiers disponibles, une file d'attente prioritaire ne serait-elle pas meilleure? S'il y a k casiers disponibles dans la file d'attente prioritaire, l'itération sur chacun d'eux prendra k étapes. De plus, selon votre implémentation de file d'attente prioritaire, vous devrez peut-être reconstruire votre file d'attente prioritaire pendant que vous regardez tout cela. Ce qui prendrait k * log (k): (k <1000) étapes. Dans la solution de tableau, il vous suffit d'itérer un tableau de 1000 éléments et de vérifier ceux qui sont ouverts. Vous pouvez également ajouter une liste disponible ou utilisée à l'implémentation pour vérifier uniquement k time.
Le manuel de conception d'algorithmes de Steven S. Skiena semble être la source que vous recherchez. La deuxième partie est une liste classée des problèmes avec une revue des algorithmes associés. Il y a version web .
Il n'y a pas de "devrait". A. Familiarisez-vous avec les classes de complexité de base (linéaire, logarithmique, etc.) B. Réalisez que vous pouvez faire à peu près n'importe quoi avec un tableau simple comme vous le pouvez avec une structure de données fantaisie comme un arbre B. L'astuce pour choisir la structure/l'algorithme approprié réside dans l'équilibre entre les performances, la taille d'entrée attendue et la complexité de mise en œuvre.
Ensuite, il y a des choses abstraites mais extrêmement utiles (bien que l'utilité ne soit pas immédiatement évidente): machines à états, théorie des graphes, théorie de la convexité (programmation linéaire, etc.).
Le MIT publie gratuitement des notes de cours, des vidéos, des devoirs et du matériel d'examen pour Introduction to Algorithms . Les titres des cours listent les algorithmes/structures de données couverts.
Il s'agit d'un évalué par les pairs consensus sur ce que vous devez savoir. C'est probablement aussi une excellente ressource d'apprentissage.