problème fonction récursive

plouf
Invité n'ayant pas de compte PHPfrance

19 déc. 2006, 22:25

salut, j'ai un probleme avec une fonction recursive, elle ne renvoit rien du tout, et je comprends pas pourquoi.

la voici.
function selVal( $arrX, $arrY )
{
	global $arrSel;
	$newArr = array_diff($arrSel, $arrX, $arrY);

	shuffle($newArr);
	if( empty($newArr[0]) )
		return selVal($arrX, $arrY );
	$selVal = $newArr[0];
	return $selVal;
}
en gros, elle doit me sélectionner les élément qui ne sont pas dans les array passé en argument, me mélanger cette sélection, et prendre le 1er élément de ce nouvel array.

Mais, il y a quelques problèmes qui font que parfois, je me retrouve avec une valeur vide en retour, donc j'y ai ajouté une condition pour éviter ce problème(le empty) seulement ça ne renvoi plus rien du tout.

Quelle est l'erreur ?

Eléphant du PHP | 78 Messages

19 déc. 2006, 22:41

Je ne comprend pas du tout ta fonction (ou c'est moi qui analyse mal).

Tu fait un array_diff($arrSel, $arrX, $arrY);

Qu'il y a-til dans $arrSel ????
Cordialement,
winni

plouf
Invité n'ayant pas de compte PHPfrance

19 déc. 2006, 22:49

Elle contient une série de nombre.

Eléphant du PHP | 78 Messages

19 déc. 2006, 23:23

Et si c'est vide, tu renvoi la même fonction avec les même parametres c'est normal ?
Cordialement,
winni

Invité
Invité n'ayant pas de compte PHPfrance

19 déc. 2006, 23:41

C'est parce que les fonctions de array déconnent :/

Un petit exemple plus parlant de ce que je devrais obtenir :
$arrSel = array(1=>1, 2, 3, 4, 5);

function selVal( $arrX, $arrY )
{
		global $arrSel;
		$newArr = array_diff($arrSel, $arrX, $arrY);

		shuffle($newArr);
		print_r($newArr);
		if( !array_key_exists(0, $newArr) )	
			return selVal($arrX, $arrY );
		$selVal = $newArr[0];
		return $selVal;
}


for( $x=1; $x<=5; $x++ )
{
		for( $y=1; $y<=5; $y++ )
		{
				$val = selVal($arrX[$x], $arrY[$y]);
				$arrX[$x][] = $val;
				$arrY[$y][] = $val;
				echo implode($arrX[$x]);
				echo ' => valeur sélectionnée: ' . $val . '<br>';
		}
		echo '<br><br>';
}


echo '<table>';
$i=1;
foreach( $arrX as $ligne )
{
		echo '<tr>';
		foreach( $arrX[$i] as $cel )
		{
				echo '<td>' . $cel . '</td>';
		}
		echo '</tr>';
		$i++;
}
echo '</table>';
Faites une 15aine, 20aine d'actualisation, vous comprendrez.
Est-ce que c'est php qui merde, ou c'est moi, je dirais quand même que c'est php, puisqu'une fois sur 15 ou 20, il m'affiche correctement le résultat.

Mon problème est d'éviter d'obtenir des array vident, mais j'y arrive pas.

ViPHP
ViPHP | 1961 Messages

19 déc. 2006, 23:59

Bonsoir,

Et si tu écrivais ta fonction de cette manière?
function selVal( $arrX, $arrY ){
    global $arrSel;
    $newArr = array_diff($arrSel, $arrX, $arrY);
    if(empty($newArr[0])){
    	selVal($arrX, $arrY );
    }
    shuffle($newArr);
    return($newArr[0]);
} 
Deux choses sont infinies, l'Univers et la sottise humaine!!
Mais je ne suis pas sur de ce que j'affirme au sujet de l'Univers.

A. Einstein

plouf
Invité n'ayant pas de compte PHPfrance

20 déc. 2006, 00:10

Ca ne me renvoi plus rien de cette façon :?

Et c'est un peu normal, shuffle redéfini les cles de l'array, en mettant le shuffle derrière, je suis sûr que la clef 0 devrait exister.

ant
Eléphant du PHP | 161 Messages

20 déc. 2006, 17:06

Excuse moi, mais c'est un peu le capharnaum ton code :?
D'abord je ne vois pas en quoi ta fonction demande un traitement récursif, ou alors j'ai rien compris :oops:

En testant ce code par exemple:
$arrSel = array(1=>1, 2, 3, 4, 5); 
$arrX = array(1=>2,4,6,10,12);
$arrY = array(1=>3,7,9,11,13);

function selVal( $arrX, $arrY )
{
        global $arrSel;
        $newArr = array_diff($arrSel, $arrX, $arrY);
        
        #
		echo "newArr vaut: ".print_r($newArr);"\n";
		#
		
        shuffle($newArr);
        
        #
        echo "newArr vaut maintenant apres shuffle: ". print_r($newArr);"\n";
        #
      
        $selVal = $newArr[0];
        
        #
        echo "selVal vaut: ". $selVal."\n";
        #

        return $selVal;
}

  $val = selVal($arrX, $arrY);
  echo ' => valeur sélectionnée: ' . $val . '<br>';

On s'appercoit que ta fonction effectue bien le traitement demandé et renvoie bien 5 ou 1. Par contre, elle ne traite pas les cas ou array_diff ne renverra rien (en supposant que les 3 tableaux contiennent les même valeurs)! Et ce n'est pas avec un traitement récursif que ca changera quoi que ce soit

Ensuite dans ton code du dessous, ici plus précisément:

for( $x=1; $x<=5; $x++ )
{
        for( $y=1; $y<=5; $y++ )
        { 
              $val = selVal($arrX[$x], $arrY[$y]); 

etc
tu passes en paramètres non pas les 2 tableaux demandés par la fonction, mais un élément de chacun des 2 tableaux (donc un entier, je suppose) alors que la fonction demande bien 2 tableaux!

Un peu plus loin, tu écris:
echo implode($arrX[$x]);
Alors que implode demande aussi un array et non pas un élément de celui-ci (même faute)

etc etc

Revoit un peu tout ça :)

plouf
Invité n'ayant pas de compte PHPfrance

20 déc. 2006, 20:37

Excuse moi, mais c'est un peu le capharnaum ton code :?
Ben non, il est correct, merci quand même du compliment :D
D'abord je ne vois pas en quoi ta fonction demande un traitement récursif, ou alors j'ai rien compris :oops:
Je veux faire un traitement récursif, car ça déconne, sinon je m'embêterais pas avec ça.
En testant ce code par exemple:
$arrSel = array(1=>1, 2, 3, 4, 5); 
$arrX = array(1=>2,4,6,10,12);
$arrY = array(1=>3,7,9,11,13);

function selVal( $arrX, $arrY )
{
        global $arrSel;
        $newArr = array_diff($arrSel, $arrX, $arrY);
        
        #
		echo "newArr vaut: ".print_r($newArr);"\n";
		#
		
        shuffle($newArr);
        
        #
        echo "newArr vaut maintenant apres shuffle: ". print_r($newArr);"\n";
        #
      
        $selVal = $newArr[0];
        
        #
        echo "selVal vaut: ". $selVal."\n";
        #

        return $selVal;
}

  $val = selVal($arrX, $arrY);
  echo ' => valeur sélectionnée: ' . $val . '<br>';

Oui, mais là tu défini les valeus de $arrX et arrY comme des chaines, alors que dans mon cas ce sont des arrays.
On s'appercoit que ta fonction effectue bien le traitement demandé et renvoie bien 5 ou 1. Par contre, elle ne traite pas les cas ou array_diff ne renverra rien (en supposant que les 3 tableaux contiennent les même valeurs)! Et ce n'est pas avec un traitement récursif que ca changera quoi que ce soit
Mais dans mon script array_diif doit obligatoirement me renvoyer une valeur, c'est logique.
Ensuite dans ton code du dessous, ici plus précisément:

for( $x=1; $x<=5; $x++ )
{
        for( $y=1; $y<=5; $y++ )
        { 
              $val = selVal($arrX[$x], $arrY[$y]); 

etc
tu passes en paramètres non pas les 2 tableaux demandés par la fonction, mais un élément de chacun des 2 tableaux (donc un entier, je suppose) alors que la fonction demande bien 2 tableaux!

Un peu plus loin, tu écris:
echo implode($arrX[$x]);
Alors que implode demande aussi un array et non pas un élément de celui-ci (même faute)

etc etc

Revoit un peu tout ça :)
Comme je l'ai dit $arrX et $arrY contiennent des arrays.
Donc $arrX[$x] est bien un tableau.
C'est vrai, j'aurais du initialiser les arrays.

Je remet mon code, ce coup si ça fonctionne presque, mais la moitié du temps, ça ne me renvoi rien :?
Décidément, je comprends pas pourquoi ça déconne comme ça.
for( $i=1; $i<=5; $i++ )
{
	$arrX[$i] = array();
	$arrY[$i] = array();
}

$arrSel = array(1=>1, 2, 3, 4, 5);

function selVal( $arrX, $arrY )
{
		global $arrSel;
		$newArr = array_diff($arrSel, $arrX, $arrY);
		if( count($newArr) == 1 )
				return implode('', $newArr);
		if( count($newArr) == 0 )
				return selVal($arrX, $arrY );
		shuffle($newArr);
		return $newArr[0];
}

for( $x=1; $x<=5; $x++ )
{
		for( $y=1; $y<=5; $y++ )
		{
				$val = selVal($arrX[$x], $arrY[$y]);
				$arrX[$x][$y] = $val;
				$arrY[$y][$x] = $val;
				echo implode($arrX[$x]);
				echo ' => valeur sélectionnée: ' . $val . '<br>';
		}
		echo '<br><br>';
}

echo '<table>';
$i=1;
foreach( $arrX as $ligne )
{
		echo '<tr>';
		foreach( $arrX[$i] as $cel )
		{
				echo '<td>' . $cel . '</td>';
		}
		echo '</tr>';
		$i++;
}
echo '</table>';
Pourquoi dans la fonction faire un appel à elle même ?
Testez en enlevant le
if( count($newArr) == 0 )
		return selVal($arrX, $arrY );
Et vous aurez des Notice: Undefined offset: 0

Voilà, si vous avez une :idea: pour parer ce problème.

Merci en tout cas de votre aide.