logi sisse meist KKK

Probleem järgmine. Alltoodud näite funktsiooni kasutan PHP-s usort-funktsioonis, kus sorditav massiiv koosneb numbreid sisaldavatest massiividest, mis esindavad versiooninumbreid. Paraku tekitab sortimine anomaaliaid. Probleemi lähemalt uurides leidsin, et järgnev funktsioon ei tagasta kunagi negatiivset väärtust. Mis võiks olla valesti?

<?php
function compare_versions($ver1,$ver2){
$l1=count($ver1);$l2=count($ver2);
$cnt=min($l1,$l2);
for($a=0;$a<$cnt;$a++)      
    if($c=$ver1[$a]<$ver2[$a]?-1:$ver1[$a]>$ver2[$a]?1:0)
        return $c;
return $l1>$l2?1:$l1<$l2?-1:0;
}

echo compare_versions(array(2,0,0),array(2,0,1));
?>

väljastab alati 1, peaks olema -1.

küsitud Jul 31 '13 at 13:46

Teet65's gravatar image

Teet65
175912

edited Jul 31 '13 at 23:41


if-i sees on ilmselt prioriteedid teised kui eeldad.

A ? B : C ? D : E

tähendab:

(A ? B : C) ? D :E

aga sa eeldad intuitiivselt:

A ? B : ( C ? D : E)

Töötav if lause (lisatud sulud):

if($c= $ver1[$a]<$ver2[$a]?-1: ($ver1[$a]>$ver2[$a]?1:0) )

Ja väheke tühikuid tuleks kasuks küll ;)

link

vastatud Aug 01 '13 at 00:43

Kaiko%20Kaur's gravatar image

Kaiko Kaur
2307711

edited Aug 01 '13 at 00:44

http://ee1.php.net/operators.comparison Example #3 Non-obvious Ternary Behaviour

(Aug 01 '13 at 00:48) Alex

Aitäh, kurja juur oligi siia peidetud.

(Aug 01 '13 at 09:33) Teet65

Tuleb selgemalt kirjutada, kasuta rohkem sulge vms. Stiilis x?y:a?b:c ei ole võimalik arusaadavalt progeda.

<?php

function compare_versions($ver1, $ver2)
{
    $l1 = count($ver1);
    $l2 = count($ver2);

    $cnt = min($l1,$l2);

    for ($a = 0; $a < $cnt; $a++)
    {
        if ($ver1[$a] < $ver2[$a])
        {
            return -1;
        }
        else if ($ver1[$a] > $ver2[$a])
        {
            return 1;
        }
    }

    if ($l1 > $l2)
    {
        return 1;
    }
    else if ($l1 < $l2)
    {
        return -1;
    }
    return 0;
}

echo compare_versions(array(2,0,1),array(3,0,1));
link

vastatud Jul 31 '13 at 15:24

Alex's gravatar image

Alex
312

edited Jul 31 '13 at 15:29

Eks see vormistamine ole natuke usu küsimus, aga tänud, sinu kood töötab tõesti. Ma siiamaani ei saa siiski pihta, miks esimene mitte.

(Jul 31 '13 at 23:24) Teet65

Aga see stiili asi jäi mind kummitama ja see on tõesti vist usu asi. Ma ei ole kindel, et pikalt lahti kirjutades ja väga rangelt iga väikese lause peale loogelisi sulgusi pannes muutub kood loetavamaks (võib-olla muutub, ma ütlen, et pole kindel). Toon näite, millele oleks huvitav tagasidet saada.

function compare_arrays($a, $b) {
  $cmp = function ($x, $y) { return
    $x < $y ? -1 : (
    $x > $y ?  1 : 0); };

  $cnt = min(count($a), count($b));
  for ($i = 0; $i < $cnt; $i++) if ($diff = $cmp($a[$i], $b[$i])) return $diff;

  return $cmp(count($a), count($b));
}
link

vastatud Aug 01 '13 at 01:29

Kaiko%20Kaur's gravatar image

Kaiko Kaur
2307711

Sama algoritm, aga tegevused on natuke rohkem lahku löödud. $cmp on protseduurimuutuja, selle asemel võiks juba defineerida eraldi funktsiooni cmp($x,$y), ent see ongi programmeerimise ilu, et asju saab teha mitut moodi.

(Aug 01 '13 at 09:37) Teet65
Sinu vastus
lülita eelvaade

Jälgi seda küsimust

By Email:

Pärast sisselogimist saad tellida muudatuse teavitusi siit

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *kaldkiri* või __kaldkiri__
  • **paks kiri** või __paks kiri__
  • link:[tekst](http://url.com/ "pealkiri")
  • pilt?![alt tekst](/path/img.jpg "pealkiri")
  • nummerdatud nimekiri: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • põhilised HTML märgendid on samuti toetatud

Pinu tööpakkumised

kõik pakkumised »

Küsimuse sildid:

×22
×3
×1

küsitud: Jul 31 '13 at 13:46

nähtud: 3,135 korda

viimati uuendatud: Aug 01 '13 at 09:37

Litsents: Creative Commons Attribution License | Kontakt: info@pinu.ee