Trouver un caractère dans un tableau 2D

labo1 - Modifié le 5 janv. 2024 à 16:37
mamiemando Messages postés 33076 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 avril 2024 - 5 janv. 2024 à 17:11

Bonjour,

Je souhaiterais faire un code qui permette de trouver un caractère bien précis dans un tableau de caractères à deux dimensions.


J'ai effectué une première tentative, où j'ai d'abord rempli mon tableau avec des caractères aléatoires à l'aide de multiples boucles for (remplir mon tableau dès sa déclaration aurait été beaucoup plus rapide mais tant pis).

Puis j'ai crée une fonction qui, j'espérais, allait me donner l'indice (ou numéro) de la ligne où se trouve le caractère en sachant que je recherche le caractère 'R' qui signifie pion Rouge.

A terme, le but de ce programme est de trouver l'indice de la ligne où se trouvent différents pions sur un plateau de jeu.

Lorsque j'exécute le programme, il m'affiche le tableau (jusqu'ici, rien d'anormal) mais il m'affiche ensuite un chiffre proche de 22000 au lieu de 1 (j'ai mis 'R' à la ligne n°1 lorsque j'ai rempli mon tableau). Lorsque je relance le programme plusieurs fois, j'obtiens un chiffre à chaque fois différent mais toujours proche de 22000.

Je ne sais pas comment faire en sorte d'avoir le bon indice. Je remercie toute personne qui pourrait m'éclairer.

Ci-dessous le code (la partie réellement importante du code est la fonction qui se trouve en bas, comme je l'ai dit, le reste est simplement du remplissage et de l'affichage) :

#include <stdio.h>

int Recuperation_indice_ligne_pion_rouge(
    char tab[][8],
    int nligne,
    int ncolonne
);

int main(void) {
    char tableau[3][8];
    int i, j;

    /* Remplissage du tableau */
    tableau[0][0] = '|';
    for (j = 1; j <= 2; j++) {
        tableau[0][j] = '.';
    }
    tableau[0][3] = 'p';
    tableau[0][4] = '.';
    tableau[0][5] = '|';
    tableau[0][6] = '.';
    tableau[0][7] = '|';

    for (j = 0; j <= 1; j++) {
        tableau[1][j] = '|';
    }
    for (j = 2; j <= 3; j++) {
        tableau[1][j] = '.';
    }
    tableau[1][4] = 'R';
    for (j = 5; j <= 6; j++) {
        tableau[1][j] = '.';
    }
    tableau[1][7] = '|';
    tableau[2][0] = '|';
    tableau[2][1] = '.';
    tableau[2][2] = 'p';
    for (j = 3; j <= 5; j++) {
        tableau[2][j] = '.';
    }
    for (j = 6; j <= 7; j++) {
        tableau[2][j] = '|';
    }

    /* ----------------------------------------- */
    /* Affichage du tableau */
    for (i = 0; i <= 2; i++) {
        for (j = 0; j <= 7; j++) {
            printf("%c", tableau[i][j]);
        }
        printf("\n");
    }

    /* ----------------------------------------- */
    /* Affichage de l'indice retournee par la fonction
     * Recuperation_indice_ligne_pion_rouge */
    printf(
        "%d",
        Recuperation_indice_ligne_pion_rouge(tableau, 3, 8)
    );
    /* ----------------------------------------- */

    printf("\n");
    return 0;
}


int Recuperation_indice_ligne_pion_rouge(
    char tab[][8],
    int nligne,
    int ncolonne
) {
    int i;
    int indice_ligne;
    for(i = 0;  i < nligne * ncolonne; i++)
        if(**tab + i == 'R')
            indice_ligne = i / ncolonne;
    return indice_ligne;
}
A voir également:

2 réponses

Dans ton main, tu sembles savoir comment afficher ton tableau avec deux boucles imbriquées.

Pourquoi ne fais-tu pas la même chose dans ta fonction de recherche?

1
mamiemando Messages postés 33076 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 avril 2024 7 748
5 janv. 2024 à 17:11

Bonjour,

Merci d'indenter ton code et de partager ton code code comme expliqué ici. J'ai modifié ton message initial en conséquence.

Comme le souligne Pierrot, si tu utilises un tableau en deux dimensions, il faut faire la recherche sur chaque ligne et sur chaque colonne de la ligne courante, donc deux boucles for imbriquées comme tu l'as fait pour l'initialisation. Ta fonction de recherche telle qu'elle est écrite suppose que le plateau du jeu est stocké dans un tableau à une dimension.

De plus tu dis :

A terme, le but de ce programme est de trouver l'indice de la ligne où se trouvent différents pions sur un plateau de jeu.

Dans le cas général, les pions rouges ne sont pas forcément tous sur la même ligne, voire il n'y a pas de pion rouge du tout. Donc cela signifie que tu recherches un ensemble potentiellement vide.

Pour aller plus loin

Tout ce qui suit est en rapport avec ton programme, mais fait appel à des notions en C que tu n'as peut-être pas encore abordées. Donc j'en parle, mais sens-toi libre de les ignorer si c'est prématuré.

Concernant le tableau :

  • Idéalement, il faudrait utiliser une structure (disons plateau_t) pour stocker ton plateau qui contiendrait ton tableau et ses dimensions. Cela permettrait à la fonction de recherche de ne prendrait en paramètre qu'un argument plateau de type plateau_t.
  • Pour le moment, tu fais une allocation statique, c'est-à-dire que la taille du plateau est connue à la compilation (pas à l'exécution). Lorsque tu voudras qu'elle soit choisie par l'utilisateur, il faudra allouer la mémoire à l'exécution. On parle alors d'allocation dynamique.
    • Concrètement une allocation dynamique se fait avec malloc ou calloc. Si l'allocation réussit, malloc (resp. calloc) retourne l'adresse du début du bloc mémoire alloué. On stocke cette adresse dans un pointeur, généralement typé pour spécifier la taille typique d'une case.
    • Quand tu n'as plus besoin de la mémoire allouer dynamiquement, il faut libérer cet espace avec free en passant le pointeur du bloc à libérer.
  • En terme de design, l'idéal serait d'avoir une fonction :
    • pour le créer (qui ne fait rien tant que tu fais une allocation statique, et qui fera les malloc/calloc adéquats en cas d'allocation dynamique) ;
    • pour chercher dedans (c'est la fonction que tu es en train d'écrire) ;
    • pour le détruire (qui ne fait rien tant que tu fais une allocation statique, et qui fera les free adéquats en cas d'allocation dynamique).

Plusieurs implémentation sont possibles pour un tableau dynamique de taille (m, n) :

  • Avec un "tableau de tableau" :
    • on crée un premier tableau (de type char **) contenant m cases de (qui sont donc de type char *)
    • dans chacun de ses cases, on crée un tableau (de type char *) de n cases (qui sont donc de type char).
  • Avec un seul tableau : c'est plus efficace, mais c'est moins pratique, car il faut convertir une case (i, j) dans l'index adéquat, avec 0 <= i < m et 0 <= j < n.
    • on crée un tableau de type char *, de taille m * n
    • pour accéder à la case (i, j), on lit la case n * i + j

Concernant les ensembles :

  • Si tu n'as pas besoin de mémoriser leur positions, par exemple, tu veux juste itérer dessus et afficher leur position.
  • Par contre, si tu as besoin de les mémoriser, c'est plus problématique, car en C, il n'y a pas de type permettant de stocker nativement un ensemble.
    • En C++, on pourrait utiliser std::set (typiquement std::set<unsigned> pour mémoriser un ensemble de lignes, voire std::set<std::pair<unsigned, unsigned> > pour mémoriser un ensemble de cases)
    • En C, il faut utiliser :
      • soit des fonctions comme tsearch, tfind, etc
      • soit une structure de donnée plus simple, mais suffisante pour ce que tu veux faire (peut-être une liste chaînée)
0