Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Alguém sabe de algum estudo sobre o assunto, ou de alguma alternativa mais rápida e eficiente ao FOR?
Neste exemplo, de cálculo do dígito do CPF.
012345678-90
eu preciso multiplicar os algarismos do 0 ao 8 por 9, 8, 7,...,2..
eu estou usando o for() pra fazer isso, assim:
for($i=0; $i<8; $i++):
$soma+=substr($cpf,$i,1) * 9-$i;
endfor;então nesse caso, não tem nada mais otimizado do q o for?
Não entendi o que você quer.
Pode explicar novamente?
se for pra fazer osmente isso em específico, o que você mostrou é o suficiente.
qualquer outra forma de fazer isso seria inaropriado (tem outro tipo de denominação, não lembro agora)
pode ver a função str_split() para transformar a string num array
e dentro do loop nao precisaria do substr..
tente fazer com str_split e faça testes de comparação de velocidade da execução.
<?php
$str = array_reverse( str_split( '01234567890' ) );
$sum = 0;
foreach( $str as $k => $v )
{
$sum += $v * ($k + 1);
}
echo $sum;
?>Bom o seu tempo de execução aqui foi grande hinom ;x
@Edit
Já que você quer de 9,8,7, eu modifiquei, veja:
<?php
for ($i = 0,$j = 9;$i <= 8 && $j >= 0;$i++,$j--)
echo '<br>'.$i*$j;
?>
Se quiser de outro método é só falar.pelo que entendi a sequencia será aleatória
sendo que deve pegar até o 8 dígito.
a string pode ser
12345678
ou
46289302
ou qualquer outro
é isso?
mas se for apenas de 1 ~ 8, o método usando for() obviamente é melhor
o codigo que postei foi uma sugestão
fiz agora um benchmark
comparando esses dois
<?php
$str = array_reverse( str_split( '01234567890' ) );
$sum = 0;
foreach( $str as $k => $v )
{
$sum += $v * ($k + 1);
}
echo $sum;
?>
<?php
for ($i = 0,$j = 9;$i <= 8 && $j >= 0;$i++,$j--)
echo '<br>'.$i*$j;
?>
o primeiro retorna em média
0.000040 ~ 0.000044
o segundo, por incrível que pareça..
0.000041 ~ 0.000048
Hinom. Sim, poderia ser qualquer sequência, da realidade eu quero apenas testar uma alternativa melhor ao for, o exemplo acima não foi nada mais que um exemplo. Pois, por exemplo se eu tenho uma sequência $seq="14563446", se eu chamar $seq[1] ou $seq{1} eu recebei o "4" que está na segunda posição, ou posição de número 1, já que começa em 0.
Então o exemplo acima eu fiz assim
$cpf = "01234567";
$seq="83746283";
for($i=0;$i<8;$i++):
$soma+=$cpf[$i] * $seq[$i];
endfor;$cpf = "01234567";
for($i=0;$i<8;$i++):
$soma+=$cpf[$i] * (8-$i);
endfor;$cpf = "01234567";
for($i=7;$i>=0;$i--):
$soma+=$cpf[$i] * ($i);
endfor;
Na realidade o substr eu também tava achando meio feio, mas como digitei a dúvida aqui sem testar, acabei dando bobeira e colocando ele.
Faça aí o benchmark comparando essa solução com as duas anteriores pra gente ver o resultado. Estou sem PHP aqui por perto.
Falou
o segundo é melhor
os testes resultaram em:
1. 35 ~ 41
2. 30 ~ 36
3. 32 ~ 34
obs: o multiplicador não será fixo ?
exemplo de 7 ~ 1
voce comparou os 3 que eu passei?
O segundo teve uma mínima melhor, mas teve um máximo pior que o terceiro. o terceiro se mostrou mais consistente. quase fixo.
no caso do cpf, seria uma sequencia fixa, mas no caso do pis, ou do título eleitoral , teríamos uma diferençazinha..
esses 3 que eu passei foram melhores ou piores ou compatíveis com os anteriores desse tópico?
Bom você quer que $i multiplique por 9,8,7...1? Se for isso tenta ae: