How to get all possibilities from an incomplete string

Asked

Viewed 58 times

3

I have a string, for example, with 5 characters but I need the same to have 10 characters in total, I did the following code to try to get the 5 characters remaining to get a total of 10 characters:

<?php
$letras = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$numeros = '0123456789';
$tudo = $letras.$numeros;

$string = 'XXXXX';

for($i = 0; $i < strlen($tudo); $i++) {
    echo $string.$tudo[$i].PHP_EOL;
}

Return:

XXXXXA
...
XXXXX9

I would like the return to be, for example, XXXXXAAAAA, XXXXXAAAAB and so it goes, so I made another code to try to get the exact amount of 10 characters:

<?php
$letras = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$numeros = '0123456789';
$tudo = $letras.$numeros;

$minimo = 10;
$string = 'XXXXX';

for($i = 0; $i < strlen($tudo); $i++) {
    $base = $string.$tudo[$i];
    for($j = 0; $j < strlen($tudo); $j++) {
        $base .= $tudo[$j];
    }
    echo $base.PHP_EOL;
}

But the above code returned the following:

XXXXXXXAABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
...
XXXXXXX9ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789

I did not understand why return to variable $tudo rather than return the most logical result being:

XXXXXAAAAA
XXXXXAAAAB
...
XXXXX9AAAA
XXXXX9AAAB

In the codes written here, I used echo line by line to observe the return of each attempt, but in the final code I would like to return an array, for example:

array(
'XXXXXAAAAA',
'XXXXXAAAAB',
...
)

I appreciate any solution and/ or tip!

1 answer

2


One of several possibilities would be to convert your character string into a class instance ArrayObject create some iterators with the method Arrayobject::getIterator() and iterate them in string to compose the result.

The iterator is a position marker within a list of moving objects as it is iterated. Arrayobject::Heart() returns the value where the iterator is pointing and Arrayobject::next() makes you point to the next element. To find out if the iterator has extrapolated the test list of subscripted items with Arrayobject::Valid()

inserir a descrição da imagem aqui

The working logic is simple, first are created m indexed iterators of 0 to n where n = m-1 and m is the number of digits to be operated per gross.

A function is then created that tests by convolution if the indexed iterators of n to 1 are valid or if the iterador[n] ran out of iterador[n-1] advances a position and the iterador[n] is restored if the iterador[n-1] ran out of iterador[n-2] advances a position and the iterador[n-1] is restored,.... if the case iterador[1] ran out of iterador[0] advances a position and the iterador[1] is restored. Finally the function ends by testing the validity of the iterador[0] if it has been exhausted is returned false indicating that all combinations have been obtained.

The code itself operates in a loop where the matching strings are mounted with each loop iteration, and with each loop iteration generating a new combination of characters.

inserir a descrição da imagem aqui

<?php
$letras = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$numeros = '0123456789';
//Junta letras e números e os separa num array para então criar instância ArrayObject.
$tudo = new ArrayObject(str_split ($letras.$numeros));

$minimo = 5;            //Define o número de caracteres a serem iterados.
$string = 'XXXXX';      //Define o prefixo do resultado.
$iteradores = [];       //Inicializa o array contendo os iteradores.

//Inicializa e armazena o número especificado de iteradores.
for($i=1; $i<=$minimo; $i++){
   $iteradores[] = $tudo->getIterator();
}

//Função de validação aplicada aos iteradores.
function iterar($iter){
    //Do iterador[n](último) ao iterador[1](segundo iterador)... 
    for($i=count($iter) - 1; $i>0; $i--){
        //...se o iterador se esgotou....
        if (!$iter[$i]->valid()) {                 
            $iter[$i]->seek(0);                   //...o renova.
            $iter[$i-1]->next();                  //...itera o seu antecessor.
        }
    }
    return $iter[0]->valid();                     //Retorna o estado do primeiro iterador, enquanto for válido ainda existem combinações a serem geradas.
};

//Enquanto houver combinações...
while(iterar($iteradores)){
    $str = $iteradores[0]->current();                //...obtém o primeiro caractere após o prefixo.
    //...Obtém os caracteres consecutivos da esquerda para direita...
    for($i=0; $i<count($iteradores); $i++){
        $str .= $iteradores[$i]->current();
    }
    $iteradores[count($iteradores) - 1]->next();     //Prepara a nova combinação.

    $base = $string.$str;                            
    echo $base.PHP_EOL;                              
}

Test the code on ideone.. PS: In free mode only 5s of code execution are allowed, so it stops abruptly, copy test in your development environment.

  • 1

    Incredible, had never used or studied on the class ArrayObject. I will certainly go deeper into it! Thank you very much.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.