|
| Byte swapping Fra : Jimmy |
Dato : 06-12-03 11:02 |
|
Hej
Jeg nogle telefonnummerstrenge af variabel længde, som skal vendes korrekt.
F.eks: 5404939099 skal blive til 4540390999.
Jeg har tænkt over hvordan dette gøres, og kan ikke finde på noget bedre end
at lave en løkke og bygge en ny streng op af substr(a,1) og substr (a-1,1).
Dette må kunne gøres bedre!
Hvad ville I foreslå?
Mvh
Jimmy
| |
Bertel Lund Hansen (06-12-2003)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 06-12-03 13:07 |
|
Jimmy skrev:
>Jeg nogle telefonnummerstrenge af variabel længde, som skal vendes korrekt.
>Hvad ville I foreslå?
Bruger du rekursion?
Hvordan ser din funktion ud?
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Thomas Lindgaard (10-12-2003)
| Kommentar Fra : Thomas Lindgaard |
Dato : 10-12-03 01:18 |
|
Davs
"Jimmy" <nyhedsgruppe2@get2net.danmark> wrote in message
news:PNhAb.435$0_.96@news.get2net.dk...
> Hej
>
> Jeg nogle telefonnummerstrenge af variabel længde, som skal vendes
korrekt.
>
> F.eks: 5404939099 skal blive til 4540390999.
>
> Jeg har tænkt over hvordan dette gøres, og kan ikke finde på noget bedre
end
> at lave en løkke og bygge en ny streng op af substr(a,1) og substr
(a-1,1).
>
> Dette må kunne gøres bedre!
Hvis jeg har forstået problemet rigtigt, så skal tallene parvis byttes
rundt...?
<?php
$phone = '5404939099';
for ($i = 0; $i < strlen($phone) - 2; $i + 2)
{
$reversed .= $phone[$i + 1].$phone[$i];
}
?>
Utestet...
Mvh.
/Thomas
| |
Jimmy (10-12-2003)
| Kommentar Fra : Jimmy |
Dato : 10-12-03 08:49 |
|
"Thomas Lindgaard" <thomas@it-snedkeren.BLACK_HOLE.dk> wrote in message
news:br5onb$gfl$1@sunsite.dk...
> Davs
>
> "Jimmy" <nyhedsgruppe2@get2net.danmark> wrote in message
> news:PNhAb.435$0_.96@news.get2net.dk...
> > Hej
> >
> > Jeg nogle telefonnummerstrenge af variabel længde, som skal vendes
> korrekt.
> >
> > F.eks: 5404939099 skal blive til 4540390999.
> >
> > Jeg har tænkt over hvordan dette gøres, og kan ikke finde på noget bedre
> end
> > at lave en løkke og bygge en ny streng op af substr(a,1) og substr
> (a-1,1).
> >
> > Dette må kunne gøres bedre!
>
> Hvis jeg har forstået problemet rigtigt, så skal tallene parvis byttes
> rundt...?
Jeps.
> <?php
>
> $phone = '5404939099';
> for ($i = 0; $i < strlen($phone) - 2; $i + 2)
> {
> $reversed .= $phone[$i + 1].$phone[$i];
> }
>
> ?>
Hvordan kan det være du trækker to fra længden?
Det jeg selv gør er følgende:
$a = 0;
while ($a<=strlen($Input))
{
$String .= substr($Input, $a+1, 1) . substr($Input, $a, 1);
$a += 2;
}
Begge dele vil virke, men jeg tænkte man kunne optimere koden ved et eller
andet smart kald.
Overvejede chunk_split på 2 og array_walk, men det koster flere resourcer
end ovenstående to forslag.
Tak for hjælpen,
Jimmy
| |
Thomas Lindgaard (10-12-2003)
| Kommentar Fra : Thomas Lindgaard |
Dato : 10-12-03 16:08 |
|
On Wed, 10 Dec 2003 08:49:03 +0100, Jimmy wrote:
> Hvordan kan det være du trækker to fra længden?
Det er muligvis en fejl :) - som sagt: utestet...
[snip - Jimmys egen version]
> Begge dele vil virke, men jeg tænkte man kunne optimere koden ved et eller
> andet smart kald.
> Overvejede chunk_split på 2 og array_walk, men det koster flere resourcer
> end ovenstående to forslag.
Mjaeh - jeg tror såmænd ikke at der er nogen smarte php-funktioner som kan
klare opgaven hurtigere end en simpel løkke - de smarte kald skal jo
alligevel løbe strengen igennem og gøre noget ved alle tegnene. En simpel
løkke kører i tid proportional med længden af strengen og hurtigere kan
det ikke gøres.
Mvh.
/Thomas
| |
Bertel Lund Hansen (10-12-2003)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 10-12-03 11:00 |
|
Jimmy skrev:
>Hej
>
>Jeg nogle telefonnummerstrenge af variabel længde, som skal vendes korrekt.
>
>F.eks: 5404939099 skal blive til 4540390999.
>
>Jeg har tænkt over hvordan dette gøres, og kan ikke finde på noget bedre end
>at lave en løkke og bygge en ny streng op af substr(a,1) og substr (a-1,1).
>
>Dette må kunne gøres bedre!
>
>Hvad ville I foreslå?
Her er to metoder, men jeg kender ikke PHP godt nok til at kunne
sige om det reelt er bedre (hvordan det internt arbejder med
ændringer af Strings).
Version 1 bytter tegnene internt i samme variabel.Version 2
opbygger én ny varabel og henter tegnene i den ønskede rækkefølge
fra den gamle.
<?
print '<p>Version 1:<br>';
$nummer='1234567890';
$pos=0;
$len=strlen($nummer);
while ($pos<$len) {
$temp=$nummer{$pos};
$nummer{$pos}=$nummer{$pos+1};
$nummer{$pos+1}=$temp;
$pos+=2;
}
print $nummer.'</p>';
print '<p>Version 2:<br>';
// $nummer='1234567890';
$pos=0;
$len=strlen($nummer);
$temp='';
while ($pos<$len) {
$temp.=$nummer{$pos+1}.$nummer{$pos};
$pos+=2;
}
$nummer=$temp;
print $nummer.'</p>';
?>
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Jimmy (10-12-2003)
| Kommentar Fra : Jimmy |
Dato : 10-12-03 15:35 |
|
"Bertel Lund Hansen" <nospamius@lundhansen.dk> wrote in message
news:gerdtvs7j51os0shp5hdum1gt9pt34d6qr@news.stofanet.dk...
> Jimmy skrev:
>
> >Hej
> >
> >Jeg nogle telefonnummerstrenge af variabel længde, som skal vendes
korrekt.
> >
> >F.eks: 5404939099 skal blive til 4540390999.
> >
> >Jeg har tænkt over hvordan dette gøres, og kan ikke finde på noget bedre
end
> >at lave en løkke og bygge en ny streng op af substr(a,1) og substr
(a-1,1).
> >
> >Dette må kunne gøres bedre!
> >
> >Hvad ville I foreslå?
>
> Her er to metoder, men jeg kender ikke PHP godt nok til at kunne
> sige om det reelt er bedre (hvordan det internt arbejder med
> ændringer af Strings).
>
> Version 1 bytter tegnene internt i samme variabel.Version 2
> opbygger én ny varabel og henter tegnene i den ønskede rækkefølge
> fra den gamle.
>
>
>
> <?
> print '<p>Version 1:<br>';
> $nummer='1234567890';
> $pos=0;
> $len=strlen($nummer);
> while ($pos<$len) {
> $temp=$nummer{$pos};
> $nummer{$pos}=$nummer{$pos+1};
> $nummer{$pos+1}=$temp;
> $pos+=2;
> }
> print $nummer.'</p>';
>
> print '<p>Version 2:<br>';
> // $nummer='1234567890';
> $pos=0;
> $len=strlen($nummer);
> $temp='';
> while ($pos<$len) {
> $temp.=$nummer{$pos+1}.$nummer{$pos};
> $pos+=2;
> }
> $nummer=$temp;
> print $nummer.'</p>';
> ?>
Tak for forslaget.
Dog ser de ud til at være væsentligt mindre letlæselige og længere end
Thomas' og min egen version.
Jeg fik nok ikke forklaret tydeligt nok i første idnlæg, at jeg ikke havde
noget problem med at løse selve opgaven - Jeg mente blot at min egen løsning
var ineffektiv og håbede på at der var en eller anden indbygget funktion der
lige kunne den slags.
Mvh
Jimmy
| |
Bertel Lund Hansen (10-12-2003)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 10-12-03 16:04 |
|
Jimmy skrev:
>Jeg fik nok ikke forklaret tydeligt nok i første idnlæg, at jeg ikke havde
>noget problem med at løse selve opgaven -
Jo, det forstod jeg godt. Jeg tænkte bare at det kunne være mere
effektivt ikke hele tiden at skulle opbygge nye strengvariable.
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Thomas Lindgaard (10-12-2003)
| Kommentar Fra : Thomas Lindgaard |
Dato : 10-12-03 16:23 |
|
On Wed, 10 Dec 2003 16:04:00 +0100, Bertel Lund Hansen wrote:
>>Jeg fik nok ikke forklaret tydeligt nok i første idnlæg, at jeg ikke havde
>>noget problem med at løse selve opgaven -
>
> Jo, det forstod jeg godt. Jeg tænkte bare at det kunne være mere
> effektivt ikke hele tiden at skulle opbygge nye strengvariable.
Jap - besparelsen i metoden med $streng[$i] i stedet for substr() ligger i
at der ikke bliver foretaget to funktionskald som hver returnerer en
streng i hver iteration af løkken.
Mvh.
/Thomas
| |
Jimmy (10-12-2003)
| Kommentar Fra : Jimmy |
Dato : 10-12-03 18:07 |
|
"Thomas Lindgaard" <thomas@it-snedkeren.BLACK_HOLE.dk> wrote in message
news:pan.2003.12.10.15.23.21.579650@it-snedkeren.BLACK_HOLE.dk...
> On Wed, 10 Dec 2003 16:04:00 +0100, Bertel Lund Hansen wrote:
>
> >>Jeg fik nok ikke forklaret tydeligt nok i første idnlæg, at jeg ikke
havde
> >>noget problem med at løse selve opgaven -
> >
> > Jo, det forstod jeg godt. Jeg tænkte bare at det kunne være mere
> > effektivt ikke hele tiden at skulle opbygge nye strengvariable.
>
> Jap - besparelsen i metoden med $streng[$i] i stedet for substr() ligger i
> at der ikke bliver foretaget to funktionskald som hver returnerer en
> streng i hver iteration af løkken.
Jeg har lavet en mindre benchmark, og min formodning om at min tilgang til
problemet var ineffektiv holdt stik.
Se koden nedenfor - det er noget hurtigt hacket kode lavet på den bærbare
mens jeg lavede mad, så tag den med et gran salt.
Jeg skal dog ikke parse 100000 tegn i produktion, hvorfor jeg accepterer det
lille performance tab og glæder mig over læsbarheden.
Jimmy_02 og 3 er tilpasninger af Thomas' version.
Jimmy_01 2.1094890832901
Jimmy_02 1.9621099233627
Jimmy_03 3.0770670175552
Bertel_01 1.6317590475082
Bertel_02 2.2418260574341
Mvh
Jimmy
<?php
function getmicrotime()
{
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
function Byte_Swapper_01($Input)
{
# Swap phonenumber
############################################################################
######
$a = 0;
while ($a<=strlen($Input))
{
$String .= substr($Input, $a+1, 1) . substr($Input, $a, 1);
$a += 2;
}
# echo $String ."<br>";
############################################################################
######
}
function Byte_Swapper_04($Input)
{
# Swap phonenumber
############################################################################
######
$a = 0;
while ($a<=strlen($Input))
{
$String .= $Input[$a+1] . $Input [$a];
$a += 2;
}
# echo $String ."<br>";
############################################################################
######
}
function Byte_Swapper_05($Input)
{
# Swap phonenumber
############################################################################
######
for ($a=0; $a<=strlen($Input); $a++)
{
$String .= $Input[$a+1] . $Input [$a];
}
# echo $String ."<br>";
############################################################################
######
}
function Byte_Swapper_02($nummer)
{
# Swap phonenumber
############################################################################
######
$pos=0;
$len=strlen($nummer);
while ($pos<$len) {
$temp=$nummer{$pos};
$nummer{$pos}=$nummer{$pos+1};
$nummer{$pos+1}=$temp;
$pos+=2;
}
# print $nummer.'<br>';
############################################################################
######
}
function Byte_Swapper_03($nummer)
{
# Swap phonenumber
############################################################################
######
$pos=0;
$len=strlen($nummer);
$temp='';
while ($pos<$len) {
$temp.=$nummer{$pos+1}.$nummer{$pos};
$pos+=2;
}
$nummer=$temp;
# print $nummer.'<br>';
############################################################################
######
}
function timers($Item)
{
$time_start = getmicrotime();
for ($a=0; $a<10000; $a++)
{
switch ($Item)
{
case "Jimmy_01":
Byte_Swapper_01 ("2143658709");
break;
case "Jimmy_02":
Byte_Swapper_04 ("2143658709");
break;
case "Jimmy_03":
Byte_Swapper_05 ("2143658709");
break;
case "Bertel_01":
Byte_Swapper_02 ("2143658709");
break;
case "Bertel_02":
Byte_Swapper_01 ("2143658709");
break;
}
}
$time_end = getmicrotime();
$time = $time_end - $time_start;
echo $Item ." ". $time ."<br>";
}
timers("Jimmy_01");
timers("Jimmy_02");
timers("Jimmy_03");
timers("Bertel_01");
timers("Bertel_02");
?>
| |
Jimmy (10-12-2003)
| Kommentar Fra : Jimmy |
Dato : 10-12-03 22:55 |
|
"Bertel Lund Hansen" <nospamius@lundhansen.dk> wrote in message
news:gerdtvs7j51os0shp5hdum1gt9pt34d6qr@news.stofanet.dk...
> Jimmy skrev:
>
> >Hej
> >
> >Jeg nogle telefonnummerstrenge af variabel længde, som skal vendes
korrekt.
> >
> >F.eks: 5404939099 skal blive til 4540390999.
> >
> >Jeg har tænkt over hvordan dette gøres, og kan ikke finde på noget bedre
end
> >at lave en løkke og bygge en ny streng op af substr(a,1) og substr
(a-1,1).
> >
> >Dette må kunne gøres bedre!
> >
> >Hvad ville I foreslå?
>
> Her er to metoder, men jeg kender ikke PHP godt nok til at kunne
> sige om det reelt er bedre (hvordan det internt arbejder med
> ændringer af Strings).
>
> Version 1 bytter tegnene internt i samme variabel.
Faktisk en sjov ide.
Jeg optimerede den i nedenstående:
function Byte_Swapper_07($Input)
{
# Swap phonenumber
############################################################################
######
$Offset = 1;
$Input = "_". $Input;
while ($Offset<strlen($Input))
{
$Input[$Offset-1] = $Input[$Offset+1];
$Offset += 2;
}
return substr($Input, 0, strlen($Input)-1);
############################################################################
######
}
Det skal .3 sekunder af den i forhold til din ved input på 10 tegn og 10.000
iterationer.
Mærkeligt tiden ikke blev halveret?
Til dit spørgsmål om jeg brugte rekursion er svaret nej, da det er alt for
resourcekrævende til opgaven. Man skal som udgangspunkt undgå rekursion,
hvis det samme job kan klares med en løkke.
Mvh
Jimmy
En lidt kortere version med samme performance:
for ($Offset=1; $Offset<strlen($Input); $Offset+=2)
{
$Input[$Offset-1] = $Input[$Offset+1];
}
| |
Bertel Lund Hansen (10-12-2003)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 10-12-03 23:12 |
|
Jimmy skrev:
>> Version 1 bytter tegnene internt i samme variabel.
>Faktisk en sjov ide.
Sjov? Det er det første jeg tænker på ved den slags problemer.
>Jeg optimerede den i nedenstående:
Ja, det var smart.
> return substr($Input, 0, strlen($Input)-1);
>Mærkeligt tiden ikke blev halveret?
Vi så jo i din tidstest at strenghåndtering er dyrt. Måske er det
den sidste linje der koster. Prøv at fjerne den og mål tiden
(selvom det så bliver forkert).
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
|
|