Rechercher : dans
Par :

Perl Problèmes paramètres tableau 2 dimension

Dernière réponse le 10 sep 2008 à 00:23:02 nicolas7474, le 1 nov 2007 à 17:32:54 
 Signaler ce message aux modérateurs

Bonjour,
Je cherche désespérément de l'aide sur un sujet:
Voila, j'ai créé une fonction qui me rempli un tableau 2 dimension avec comme prmeier paramètre un chiffre et en deuxième une lettre. Cette fonction doit me retourner le tableau 2 dimension afin que je le repasse en paramètre d'entré dans une autre fonction mais cela ne marche pas!!

Je n'arrive déjà pas à afficher le tableau lorsque je fais un return de ma première fonction!!

Je vous mets mon bout de code et si quelqu'un à la solution, ça serait génial!
en vous remerciant

print "Veuillez entrer un motif \n";
$motif=<>;
chomp($motif);
$m=length($motif);

ma première fonction:

sub Calcul_Fonction_Transition {
$n= $_[0];
@sigma=('a','b','c');
$m=length($n);
for ($q=0 ; $q <= $m ; $q++) {
foreach $mot (@sigma) {
if ($m+1 < $q+2 ) {
$k=$m+1;
}else {
$k=$q+2;
}
do {
$k=$k-1;
$pk=substr($n,0,$q).$mot;
$lpk=length($pk);
} until ((substr($n,0,$k))eq(substr($pk,$lpk-$k,$k)) or ($k==0)) ;
$delta[$q][$mot]=$k;
print "$delta[$q][$mot] ";

}
print"\n";
}
return (@delta);
}


# appel par invocation de la fct suivi de la liste des valeurs des paramètres effectifs
@delt=Calcul_Fonction_Transition($motif);
print "voici delt: @delt\n";

ma deuxième fonction

sub Recherche_Automate_Fini{
$text=$_[0];
@delta=$_[1];
$m=$_[2];
$n=length($text);
$q=0;
for ($i=1;$i<=$n;$i++){
$lettre=substr($text,$i-1,1);
print "voici le tableau: $delta[$q][$lettre]\n";
$q=$delta[$q][$lettre];
if ($q==$m){
$s=$i-$m;
print "le motif apparait avec le decalage $s \n";
}
}
}

print "Veuillez entrer un texte \n";
$texte=<>;
chomp($texte);
@liste=($texte,@delt,$m);
&Recherche_Automate_Fini(@liste);

merci encore pour l'aide que vous m'apporterez

Configuration: Windows XP
Internet Explorer 7.0

Meilleures réponses pour « perl Problèmes paramètres tableau 2 dimension » dans :
GRUB - La structure de fichier de configuration VoirLe fichier de configuration de GRUB Introduction Exemple de configuration type Explications Paramètres par défaut 1. Adressage des disques 2. title 3. root 4. kernel 5. initrd 6. rootnoverify 7. chainloader OBSERVATIONS
Les tableaux en langage C++ VoirType de données complexes Les variables, telles que nous les avons vues, ne permettent de stocker qu'une seule donnée à la fois. Or, pour de nombreuses données, comme cela est souvent le cas, des variables distinctes seraient beaucoup trop lourdes...
Langage C - Les tableaux VoirType de données complexes Les variables, telles que nous les avons vues, ne permettent de stocker qu'une seule donnée à la fois. Or, pour de nombreuses données, comme cela est souvent le cas, des variables distinctes seraient beaucoup trop lourdes...
Perl - Les fonctions VoirLa notion de fonction et de procédure On appelle procédure un sous-programme qui permet d'effectuer un ensemble d'instruction par simple appel de la procédure dans le corps du programme principal. Les procédure permettent d'exécuter dans plusieurs...

1

lami20j, le 2 nov 2007 à 00:48:44

Salut,

@delta c'est un tableau de tableaux donc chaque élément du @delta est un tableau

print "voici delt: @$_\n" foreach @delt;


lami20j

Répondre à lami20j

2

nicolas7474, le 2 nov 2007 à 08:03:28

Merci pour ces infos mais cela va me servir seulement à afficher le tableau de tableau. COmment dois-je faire pour avoir accès à un élément bien spécifique du tableau dans mon autre fonction, par exemple $delt[$q][$mot] ne fonctionne pas si je l'utilise dans ma deuxième fonction.

merci d'avance

Répondre à nicolas7474

3

lami20j, le 2 nov 2007 à 09:45:04

Salut,

@liste=($texte,@delt,$m);

une fois que tu as fait ça sache que l'identité de $text,@delt et $m sont perdue, tu obtiens une liste plate

donc @delta=$_[1];
ne contient pas le @delt mais le 1ère élément de @delt (et je ne crois pas que c'est ça que tu veux) qui est un tableau anonyme

pareil pour $m=$_[2];
$m contient le 2ème élément de @delta qui est un tableau anonyme

Tu dois passer les arguments de cette façon

&Recherche_Automate_Fini($text,\@delt,$m);
Je prefererais de m'expliquer exactement ce que tu veux faire, puisque j'avoue que ton code ne'est pas trop parlant :-(
Donc si tu peux me donner une exemple concret de ce que tu veux obtenir, peut être je pourrai écrire les fonctions.
A toi.
lami20j

Répondre à lami20j

4

nicolas7474, le 2 nov 2007 à 10:23:59

Je te remercie pour l'info de comment on passe un tableau 2D en paramètre dans une fonction.

Comment récupère t-on les paramètres dans la fonctions? toujours avec $_[0] ...?
je vais voir si cela marche et je te redis!

En fait ma fonction 1 doit créer le tableau 2D avec un algorithme de modélisation du langage, l'algorithme est OK et le tableua est rempli car si j'affiche :

$delta[$q][$mot]=$k;
print "$delta[$q][$mot] ";


tout cela se passe bien, j'ai bien toutes mes valeurs.

En suite le dois pouvoir retourner ce tableau 2D afin de la passer en paramètre (comme tu ma dit) dans ma deuxième fonction qui est une recherche d'un motif dans un texte: je me sert donc du tableau 2D dans cette fonction.

Si je suis pas clair, dis le moi, je me rend pas trop compte
merci encore

Répondre à nicolas7474

5

lami20j, le 2 nov 2007 à 12:38:01

Le mecanisme des sous-programmes je le connais ainsi que les structures de données.

Ce que j'ai besoin c'est de ce que as en entrée et ce que tu veux en sortie

En bref, ton algo

Un exemple concre :
entrée <- $motif
entrée <- $texte
affiche -> résultat

C'est ça que je veux savoir, pour que je puisse t'aider.
Déjà $lettre peut être une lettre, en ce cas je ne vois pas comment tu peux utiliser une lettre en tant qu'indice dans tableau.

lami20j

Répondre à lami20j

6

nicolas7474, le 2 nov 2007 à 14:02:07

En fait un entrée de ma première fonction j'ai un mot et en sortie le tableau 2D en question qui se présente sous cette forme:
Si je donne le motif 'ababaca' à ma fonction , le tableau qu'elle doit sortir sera:
(la longueur du motif est 7 et l'alphabet ('a','b','c')

Etat a b c
0 1 0 0
1 1 2 0
2 3 0 0
3 1 4 0
4 5 0 0
5 1 4 6
6 7 0 0
7 1 2 0

Je souhaite ensuite pouvoir afficher ce tableau et le passer en paramètre dans ma deuxième fonction
Elle prend en entrée un texte (avec le motif caché dedans), le tableau 2D et la longueur du motif (ici 7)
Elle doit me retourner le décalage du motif dans le texte (l'affichage se fait avec print dans ma deuxième fonction)

Le problème est la sortie du tableau 2D pour le passer en paramètre dans la 2ème fonction!

merci d'avance encore, j'espère que je t'ai éclairé

Répondre à nicolas7474

7

lami20j, le 2 nov 2007 à 17:59:05

Quand on essaie d'accèder à un élément de ton tableau de tableaux je dois faire $tableau[$i][$j]
A savoir que $i et $j sont des indices, donc des nombres entiers 0,1,2..........
Dans ton cas tu n'utilise pas un nombre mais une lettre
Tu utilises $mot et $lettre comme des indices pour le tableau mais c'est aberrant puisque $mot et $lettre contient une lettre et pas un nombre.
lami20j

Répondre à lami20j

8

lami20j, le 2 nov 2007 à 18:16:50

Pour comprendre ce que je veux dire voici un test, pour te monter l'erreur d'interprétation que tu fait
En gras tu verras les tests que j'ai mis, certaines lignes je l'ai mis en commentaire, je traite que la 1ère fonction que tu as l'impression qu'elle fonction mais c'est totalement faux ;-)

Le script

#!/usr/bin/perl
use warnings;
print "Veuillez entrer un motif \n";
$motif=<>;
chomp($motif);
$m=length($motif);

sub Calcul_Fonction_Transition {
  $n= $_[0];
  @sigma=('a','b','c');
  $m=length($n);
  for ($q=0 ; $q <= $m ; $q++) {
    foreach $mot (@sigma) {
      if ($m+1 < $q+2 ) {
        $k=$m+1;
      }else {
        $k=$q+2;
      }
      do {
          $k=$k-1;
          $pk=substr($n,0,$q).$mot;
          $lpk=length($pk);
      } until ((substr($n,0,$k))eq(substr($pk,$lpk-$k,$k)) or ($k==0));
      $delta[$q][$mot]=$k;
#     print "$delta[$q][$mot] ";
      print "q = $q - mot = $mot - $k => $delta[$q][$mot]\n";
    }
#    print"\n";
  }
  return (@delta);
}
# appel par invocation de la fct suivi de la liste des valeurs des paramÃ~Cštres effectifs
# $tableau[$i][$j]@delt=Calcul_Fonction_Transition($motif);
#print "voici delt: @$_\n" foreach @delt;
L'exécution
lami20j@debian:~/trash$ perl ccm.pl
Name "main::delt" used only once: possible typo at ccm.pl line 33.
Veuillez entrer un motif
ababaca
Argument "a" isn't numeric in array element at ccm.pl line 24, <> line 1.
q = 0 - mot = a - 1 => 1
Argument "b" isn't numeric in array element at ccm.pl line 24, <> line 1.
q = 0 - mot = b - 0 => 0
Argument "c" isn't numeric in array element at ccm.pl line 24, <> line 1.
q = 0 - mot = c - 0 => 0
q = 1 - mot = a - 1 => 1
q = 1 - mot = b - 2 => 2
q = 1 - mot = c - 0 => 0
q = 2 - mot = a - 3 => 3
q = 2 - mot = b - 0 => 0
q = 2 - mot = c - 0 => 0
q = 3 - mot = a - 1 => 1
q = 3 - mot = b - 4 => 4
q = 3 - mot = c - 0 => 0
q = 4 - mot = a - 5 => 5
q = 4 - mot = b - 0 => 0
q = 4 - mot = c - 0 => 0
q = 5 - mot = a - 1 => 1
q = 5 - mot = b - 4 => 4
q = 5 - mot = c - 6 => 6
q = 6 - mot = a - 7 => 7
q = 6 - mot = b - 0 => 0
q = 6 - mot = c - 0 => 0
q = 7 - mot = a - 1 => 1
q = 7 - mot = b - 2 => 2
q = 7 - mot = c - 0 => 0
Explication

Tu vois bien le message de warning Argument "a" isn't numeric in array element at ccm.pl line 24,
Ben la ligne 24 c'est celle ci (voir en gras)
lami20j@debian:~/trash$ sed '24!d' ccm.pl
      $delta[$q][$mot]=$k;
En bref Perl te dit que $mot ne peux pas être un indice pour le tableau puisqu'il n'est pas numerique
Donc ton algo, que tu ne l'a toujours pas dit ne peux pas fonctionner.

Tu m'as parler de ce que fait la 1ère fonction, ben je ne suis pas convaincu vu que l'algo n'est pas bon.
Pour la 2ème partie tu ne m'as rien dit.

Voici un exemple de ce que j'ai besoin de savoir (dans l'exemple tu vois le script ainsi que explication de ce qu'il fait) perl trier un tableau sans sort

lami20j

Répondre à lami20j

9

nicolas7474, le 5 nov 2007 à 09:13:45

Je te remercie pour tes infos mais comment doit-on faire pour réaliser ce tableau afin de le réutiliser?

Si tu as une idée....

en te remerciant,
cordialement

Répondre à nicolas7474

10

lami20j, le 5 nov 2007 à 11:26:28

Salut,

je veux bien t'aider mais je n'ai pas compris ce que tu veux faire.
si tu arrives à me faire comprendre ce que tu veux, je vais pouvoir t'aider.
lami20j

Répondre à lami20j

11

nicolas7474, le 5 nov 2007 à 18:56:14

Je veux bien t'expliquer mais il s'agit d'un cours de modélisation du langage!
Je vais te montrer sur un exemple en fait: si tu prend le motif 'ababaca'
la fonction doit te retourner le tableau a 2 dimension que j'ai mis dans un post plus haut. Pour ce mot, l'alphabet est compsé de 'a', de 'b' et de 'c' donc il nous faut 3 colonnes. De plus le mot a une longueur de 7 donc il faut 8 lignes (q va de 0 à m)
pour le premier état, je regarde 'a' (première lettre de mon motif) avec chaque lettre de mon alphabet et je met 1 dans le tableau quand c'est égal d'où la première ligne
1 0 0
donc si tu as un 'a' à l'état 0, tu passe à l'état 1
tu as donc ton 'a' et tu regarde si en concaténant avec chaque lettre de l'alphabet tu obtiens le début du mot

ex:
'aa' <> de 'ab' donc on met 1 car on retombe à l'état 1 où on avait un a
'ab'='ab' donc on met 2 car on peut passer à l'état 2
'ac'<>'ab' donc on met 0 car 'c'<>'a' (notre première lettre du mot)

Je pense pas que tu comprenne grand chose étant donné que c'est difficile à expliquer par écrit! en fait tu as deux fenêtre de lecture, une se déplace vers la gauche et l'autre vers la droite en se réduisant jusqu'à trouver l'égalité!

la ligne 1 4 6 pour l'état 5 signifie que l'on a 'ababa' si on met un 'c', on passe à la 6, si on met un 'a' on revient à l'état 1 car on a 'aa' que l'on ne retrouve nulle part dans le mot. En revanche, si on met un 'b', on a 'ababab' , or on retrouve 'abab' a l'état 4, on met donc 4.


Je pense pas que tu comprenne tout mais je veux juste comprendre comment sortir un tel tableau 2D!!

Répondre à nicolas7474

12

lami20j, le 5 nov 2007 à 21:02:40

Salut,

Ne soit pas préoccupé si je comprends ou pas.
Concentre toi sur les explications, ne t'inquiètes pas pour moi.

Voici la 1er partie avec le résultat (en gras tu as les lignes qui créent ton tableau @delta)

lami20j@debian:~$ cat automate.pl
#!/usr/bin/perl
print "Veuillez entrer un motif \n";
$motif=<>;
chomp($motif);
$m=length($motif);

sub Calcul_Fonction_Transition {
  $n= $_[0];
  @sigma=('a','b','c');
  $m=length($n);
  for ($q=0 ; $q <= $m ; $q++) {
    foreach $mot (@sigma) {
      if ($m+1 < $q+2 ) {
        $e1 = $k=$m+1;
      }else {
        $e2 = $k=$q+2;
      }
      do {
          $k=$k-1;
          $pk=substr($n,0,$q).$mot;
          $lpk=length($pk);
      } until ((substr($n,0,$k))eq(substr($pk,$lpk-$k,$k)) or ($k==0)) ;
      push @{$delta[$q]},$k;
    }
    unshift @{$delta[$q]},$q;
  }
  return @delta;
}

@delt = Calcul_Fonction_Transition ($motif);
print "voici le tableau\n";
for (@delt) {
        print "@{$_}\n";
}
lami20j@debian:~$ perl automate.pl
Veuillez entrer un motif
ababaca
voici le tableau
0 1 0 0
1 1 2 0
2 3 0 0
3 1 4 0
4 5 0 0
5 1 4 6
6 7 0 0
7 1 2 0

Maintenant tu as le tableau.
Je pense que tu dois commencer expliquer la 2ème partie ;-))
Explique bien, et je vais comprendre ;-DD
lami20j

Répondre à lami20j

13

nicolas7474, le 5 nov 2007 à 21:44:53

Oula tu m'impressionnes!!voila c'est ce que je cherchais pour le début, comment créer un tableau double entré!en fait tu dis qu'une ligne du tableau est une liste et tu ajoute soit à la fin soit au début!fallait y penser, merci!

je t'expliques la suite! allez chaud!
alors en fait je dois créer une fonction qui prend en paramètre un texte quelconque, la longueur du motif précédent et le tableau précédent. Le but de la fonction est de trouver si le motif est présent dans le texte passé en paramètre et pour cela on se sert du tableau retourné par la fonction 1. Si on le trouve, on indique via un print le décalage par rapport au début du texte:
pti exemple ('salut ababaca' => la fonction doit me dire le motif apparait avec le décalage 6)

Pour cela, on fait une boucle de q=0 à n (longueur du texte)
on regarde si la valeur de delt[q][q ième lettre du texte] (tableau sorti de la fonction 1 et assé en paramètre) est égale à la longueur du motif:
si oui alors on a le motif et sinon on n'a pas le motif
le décalage s'obtient en faisant q-m

voila celle la est plus simple à comprendre mais il faut juste passer le tableau en paramètre.

En te remerciant encore, tu m'aides bcp

Répondre à nicolas7474

14

nicolas7474, le 6 nov 2007 à 19:17:15

Tu as compris mon problème? parce que j'ai essayé ce que tu m'as dit, ça marche nikel mais comment je fais pour retrouver dan sle tableau la ligne 2 pour la lettre a par exemple quand je parcours mon texte??

si tu as une idée...

Répondre à nicolas7474

15

lami20j, le 6 nov 2007 à 19:37:37

Salut,

disons que j'ai compris ce que tu veux faire, en revanche je n'ai pas compris ta façon de le faire.

1. en fait ce n'est pas le tableau qui est difficile d'obtenir, ça c'est un jeu d'enfant, c'est son utilisation qui pose des problèmes
2. la deuxième fonction je la trouve incomplète
Tu dois chercher un motif, je pense qu'il faut passer le motif à la fonction sinon je ne vois pas comment tu peux faire la comparaison

A savoir que le tableau généré par la 1ère fonction ne contient que des chiffres, donc je ne vois pas comment tu te prends pour chercher dans le texte.

La question que je me pose, si tu veux chercher un motif pourquoi n'utilise tu l'assertion \G des regex et la fonction pos qui peut te retourner la position?
Ou tu veux réinventer la roue?! Si oui alors il faut peut être penser à ton algo et ensuite on verra ce qu'on peut faire.

Pour obtenir tes combinaison dans les états regarde ça

#!/usr/bin/perl
print "Veuillez entrer un motif \n";
$motif=<>;
chomp($motif);
$m=length($motif);

sub Calcul_Fonction_Transition {
  $n= $_[0];
  @sigma=('a','b','c');
  $m=length($n);
  for ($q=0 ; $q <= $m ; $q++) {
    foreach $mot (@sigma) {
      if ($m+1 < $q+2 ) {
        $e1 = $k=$m+1;
      }else {
        $e2 = $k=$q+2;
      }
      do {
          $k=$k-1;
          $pk=substr($n,0,$q) . $mot;
      } until ((substr($n,0,$k))eq(substr($pk,$lpk-$k,$k)) or ($k==0)) ;
      push @{$delta[$q]},$k,$pk;
    }
    unshift @{$delta[$q]},$q;
  }
  return @delta;
}

@delt = Calcul_Fonction_Transition ($motif);
print "voici le tableau\n";
for (@delt) {
        print "@{$_}\n";
}
Le résultat
lami20j@debian:~$ perl automate.pl
Veuillez entrer un motif
ababaca
voici le tableau
0 1 a 0 b 0 c
1 1 aa 2 ab 0 ac
2 3 aba 0 abb 0 abc
3 1 abaa 4 abab 0 abac
4 5 ababa 0 ababb 0 ababc
5 1 ababaa 4 ababab 6 ababac
6 7 ababaca 0 ababacb 0 ababacc
7 1 ababacaa 2 ababacab 0 ababacac


Ensuite tu utilise le tableau pour chercher le mot correspondant ainsi que le nombre de lettre
lami20j

Répondre à lami20j

16

nicolas7474, le 6 nov 2007 à 20:09:05

Re!
en fait je ne cherche pas à réinventer la roue comme tu dis mais c'est un exercice demander en modélisation du langage (et oui je suis à la fac!) donc le but est d'utiliser l'algo de Recherche_Automate_Fini. Avec le tableau créé par la fonction 1, on peu le trouver sans passer le motif en paramètre si tu regarde bien:

on parcours les lettre une par une de notre texte dans l'ordre et q prend la valeur du tableau en 0 (le premier coup) pour la première lettre (q=delta[0][première lettre]), ensuite au deuxième tour, q prend la valeur du tableau a létat q (défini a l'état 1) pour la deuxième lettre du texte (q=delta[q][deuxième lettre])(c'est la l'intéret d'un tableau double entrée) et ainsi de suite donc si on rencontre notre motif dans le texte, q va prendre successivement les valeur 0,1, 2, 3 ,4, 5, 6, 7 pour q=7, la condition est vérifiée: on a trouvé notre motif avec le décalage $i-$m

j'espè-re que tu as compris le truc sinon essaie avec ababaca en motif et salut ababaca en texte parce que je n'ai plus le net ce soir!

mais j'espère que tu pourras m'aider!

Répondre à nicolas7474

17

lami20j, le 6 nov 2007 à 20:13:33

q=delta[0][première lettre])

tu ne veux toujours pas comprendre que ça c'est une abération

première lettre tu le mets en tant qu'indice dans un tableau ?????????,,
je te rappelle qu'on peut écrire tab[0][1] mais pas tab[0][a]
lami20j

Répondre à lami20j

18

lami20j, le 6 nov 2007 à 21:52:12

Je te conseil de regardé ici automate fini en C et d'adapter en Perl.
Le code est complet.
lami20j

Répondre à lami20j

19

nicolas7474, le 7 nov 2007 à 07:59:39

J'ai bien compris que sa ne marchais pas mais alors dans ce cas, il ne faut pas utiliser 2 fonction car dans le lien que tu ma donné, il mette bien une lettre comme indice dans le tableau....mais ne le retourne pas, ils font tout dans la même fonction.

Encore merci pour ton aide

Répondre à nicolas7474
Collection CommentÇaMarche.net