Comparer valeurs int et array

Résolu
Jockill Messages postés 102 Date d'inscription jeudi 17 juillet 2014 Statut Membre Dernière intervention 13 mai 2019 - 25 mai 2018 à 09:52
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 - 30 mai 2018 à 17:26
Bonjour,
je crée un système de déplacement en c++ dans lequel un personnage évolue dans une carte représentée par des cases numérotées (comme les cartes de randonnée par exemple).
Le problème est que sur sa route se trouvent des cases inaccessibles.
J'ai ca pour le moment :

    int valeursInterdites[5] = {1 ,2 ,3 ,4 ,5};
    int position = 6;

    char sensMouvement;
    cout << "Dans quelle direction voulez-vous vous deplacer ?" << endl << "(N,S,E,O)" << endl; 
    cin >> sensMouvement; 

    do {
        switch(sensMouvement){

        case 'N':
            direction = nord;
            position = position+10;
            //SI POSITION INCLUSE DANS valeursInterdites ALORS ERRORMVT SINON ON CONTINUE
            errorMvt(); // FONCION ENVOYANT UN MESSAGE D'ERREUR A L'UTILISATEUR
            mvtCheck = false; 
        break;

        ...
        
        }
    }while(mvtCheck==false);


Est ce que quelqu'un aurait une idée ?
J'ai essayé d'utiliser std::begin et std::end mais elles ne semblent pas fonctionner, je ne pense pas utiliser c++11

Merci énormément !
JøckIll
A voir également:

12 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
25 mai 2018 à 15:27
Bonjour.

Je ne comprends pas bien ta question. Pas facile de t'aider :(. Quel est ton souci ? Est-ce trouver une valeur actuelle dans un tableau (std::find) ? Est-ce trouver une série de valeur dans un tableau (std::find_if) ?

Quelques remarques:
- Evite les "using namespace", c'est ultra dégueux, voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace/
- Utilise C++11 si tu as le choix (meilleure performance, meilleurs rapports d'erreurs, plein de choses en plus, pas mal d'outils simplifiés, et pas d'obligation de changer de syntaxe). Aucune raison de se brider donc !
- Si tu as besoin de faire un tableau fixe qui ne change jamais de taille, utilise plutôt un std::array (qui possède begin et end) au lieu d'un tableau "C".
- Si ton but est de vérifier qu'un élément n'est pas dans une collection, alors ce n'est pas du tout un tableau qu'il te faut, mais un std::set (voir même un std::unordered_set !)
- Un booléen se compare plutôt comme suit: "while (!mvtCheck)". On évite de faire "bool == true/false", c'est assez redondant.
0
Jockill Messages postés 102 Date d'inscription jeudi 17 juillet 2014 Statut Membre Dernière intervention 13 mai 2019
Modifié le 27 mai 2018 à 18:06
Bonjour !
Desole pour la reponse tardive ^^'
En gros ma question est : comment est ce que je peux faire pour voir si ma variable int est incluse dans mon array.
Du coup faire quelquechose du type

if (MaVariable == NimporteQuelleValeurDuTableau) ...


Je vais aller jeter un oeil aux std::set
Merci :)
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
27 mai 2018 à 20:45
La réponse est dans mon post précédent: std::find :)
0
Jockill Messages postés 102 Date d'inscription jeudi 17 juillet 2014 Statut Membre Dernière intervention 13 mai 2019
28 mai 2018 à 11:49
Salut
jai été voir sur cpp ref mais je n'ai pas tres bien compris la syntaxe de std::find ...
j'aurais du coup :

int interdites[5]  {1 ,2 ,3 ,4 ,5};
int position;
...
int posInterdite = std::find(std::begin(interdites), std::find(interdites), pi);
if (position == pi) {
cout << "Position interdite" << endl;
}
...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié le 29 mai 2018 à 09:54
Voici 4 manières différentes de faire les choses:
#include <iostream>
#include <array>
#include <vector>
#include <set>
#include <unordered_set>

int main()
{
  int position = 3;

  // Moche, mélange C et C++
  int interdites[5] = {1 ,2 ,3 ,4 ,5};
  auto found = std::find(std::begin(interdites), std::end(interdites), position);
  if (found != std::end(interdites))
    std::cout << "Position interdite trouvée" << std::endl;
  else
    std::cout << "Position interdite NON trouvée" << std::endl;

  // Mieux, si tu sais que ton tableau ne changera jamais de taille
  std::array<int, 5> interdites2 = {1 ,2 ,3 ,4 ,5};
  auto found2 = std::find(interdites2.begin(), interdites2.end(), position);
  if (found2 != interdites2.end())
    std::cout << "Position interdite trouvée" << std::endl;
  else
    std::cout << "Position interdite NON trouvée" << std::endl;

  // Si ton tableau peut changer de taille
  std::vector<int> interdites3 = {1 ,2 ,3 ,4 ,5};
  auto found3 = std::find(interdites3.begin(), interdites3.end(), position);
  if (found3 != interdites3.end())
    std::cout << "Position interdite trouvée" << std::endl;
  else
    std::cout << "Position interdite NON trouvée" << std::endl;

  // Si tu veux savoir si un élément n'est pas dans une série, un set est plus adapté
  // (un ordre de grandeur plus rapide, de l'ordre de 0(log(n)) au lieu de 0(n) pour un tableau).
  std::set<int> interdites4 = {1 ,2 ,3 ,4 ,5};
  if (interdites4.find(position) != interdites4.end())
    std::cout << "Position interdite trouvée" << std::endl;
  else
    std::cout << "Position interdite NON trouvée" << std::endl;

  // La version la plus rapide, mais plus "gourmande" en mémoire
  // (ordre de grandeur de l'ordre de 0(1)).
  std::unordered_set<int> interdites5 = {1 ,2 ,3 ,4 ,5};
  if (interdites5.find(position) != interdites5.end())
    std::cout << "Position interdite trouvée" << std::endl;
  else
    std::cout << "Position interdite NON trouvée" << std::endl;


  return 0;
}


A noter que ce que tu sembles vouloir faire, ne nécessite normalement pas de chercher si un élément est présent dans un ensemble. Si tu as une grille représentant une carte, alors il suffit de regarder au coordonnées si un obstacle est présent. Je réponds techniquement à ta question, mais je doute que tu partes dans la bonne direction.

0
Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 11
28 mai 2018 à 18:43
Il existe même d'autres possibilités, en particulier si la liste à parcourir est naturellement triée (est un peu plus rapide que les précédentes si y a une grande quantité de données.)
  std::vector<int> interdites5{ 1 ,2 ,3 ,4 ,5 }; // ou tableau ou array<> trié
  auto found5 = std::lower_bound( begin(interdites5), end(interdites5), position );
  if ( found5!=interdites5.end()  &&  *found5==position )
    std::cout << "Position interdite trouvée" << std::endl;
  else
    std::cout << "Position interdite NON trouvée" << std::endl;
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
29 mai 2018 à 10:04
Merci Dalfab, je n'y avais pas pensé :) (Ta deuxième vérification n'est normalement pas nécessaire).

J'ai aussi ajouté le std::unordered_set (hash set) qui est encore plus rapide que tout cela (mais au détriment de la mémoire). Il existe une dernière solution, si on ne fait que rechercher des entiers relativement contigus, avec un std::array "troué" contenant des booléen. C'est le même principe que le std::unordered_set mais on ne "paie" pas la fonction de hash (car l'index est direct).
Enfin, si on veut à la fois de la vitesse et peu d'espace mémoire pris, on partira sur un "bloom filter", (pour le prix de 3 à 4 fonctions de hash, on peut retrouver un élément en 0(1) dans un set binaire très petit).
0
Jockill Messages postés 102 Date d'inscription jeudi 17 juillet 2014 Statut Membre Dernière intervention 13 mai 2019
30 mai 2018 à 17:09
Salut
J'ai pensé aux coordonnees mais ça a été plus simple pour moi de numéroter les cases parce que j'avais pas vraiment d'idée sur comment mettre ça en place...
0
Jockill Messages postés 102 Date d'inscription jeudi 17 juillet 2014 Statut Membre Dernière intervention 13 mai 2019
30 mai 2018 à 17:12
Je vais essayer merci :)
0
Jockill Messages postés 102 Date d'inscription jeudi 17 juillet 2014 Statut Membre Dernière intervention 13 mai 2019
30 mai 2018 à 17:13
A quoi correspond 0(1)?
0
Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 11
30 mai 2018 à 17:23
o(1) : c'est une notation mathématique pour indiquer que l'élément est trouvé en temps constant.
Les autres méthodes sont:
  • en o(Log n) : très rapide (méthodes 4, 5, 6)
  • en o(n) : rapide (méthodes 1, 2 et 3)
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
30 mai 2018 à 17:26
A quoi correspond 0(1)?

https://fr.wikipedia.org/wiki/Analyse_de_la_complexit%C3%A9_des_algorithmes

J'ai pensé aux coordonnees mais ça a été plus simple pour moi de numéroter les cases parce que j'avais pas vraiment d'idée sur comment mettre ça en place...

Si tu as une carte, tu as forcément une grille, et donc un tableau à double dimension (ou un tableau à simple dimension qui se comporte comme un double). A ce moment, l'accès à une case est aisé.

Soit une grille de 4x5.

Avec un tableau double:
    std::array<std::array<char, 5>, 4> grid;
    // Init toutes les cases à "."
    for (int i = 0; i < 4; ++i)
      for (int j = 0; j < 5; ++j)
        grid[i][j] = '.';
    // tout en haut à gauche
    grid[0][0] = '#';
    // tout en bas à droite
    grid[3][4] = '#';
    // Affichage de la grille
    for (int i = 0; i < 4; ++i)
    {
      for (int j = 0; j < 5; ++j)
        std::cout << grid[i][j];
      std::cout << std::endl;
    }
    std::cout << std::endl;


Avec un tableau simple:
    std::array<char, 5*4> grid;
    // Init toutes les cases à "."
    for (int i = 0; i < 5*4; ++i)
        grid[i] = '.';
    // tout en haut à gauche
    grid[0 * 4 + 0] = '#';
    // tout en bas à droite
    grid[3 * 4 + 4] = '#';
    // Affichage de la grille
    for (int i = 0; i < 4; ++i)
    {
      for (int j = 0; j < 5; ++j)
        std::cout << grid[i * 4 + j];
      std::cout << std::endl;
    }
    std::cout << std::endl;

0
Rejoignez-nous