SORU
21 Temmuz 2010, ÇARŞAMBA


Algoritma bir dizi excel-sütun adını almak için

Bazı Excel dosyaları oluşturan bir senaryo üzerinde çalışıyorum ve sütun adını içine bir sayıya eşit dönüştürmek istiyorum. Örneğin:

1 => A
2 => B
27 => AA
28 => AB
14558 => UMX

Zaten bunu yapmak için bir algoritma yazdım, ama olsun bunu yapmak için daha basit ya da daha hızlı yol olduğunu bilmek istiyorum

function numberToColumnName($number){
    $abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $abc_len = strlen($abc);

    $result_len = 1; // how much characters the column's name will have
    $pow = 0;
    while( ( $pow  = pow($abc_len, $result_len) ) < $number ){
        $result_len  ;
    }

    $result = "";
    $next = false;
    // add each character to the result...
    for($i = 1; $i<=$result_len; $i  ){
        $index = ($number % $abc_len) - 1; // calculate the module

        // sometimes the index should be decreased by 1
        if( $next || $next = false ){
            $index--;
        }

        // this is the point that will be calculated in the next iteration
        $number = floor($number / strlen($abc));

        // if the index is negative, convert it to positive
        if( $next = ($index < 0) ) {
            $index = $abc_len   $index;
        }

        $result = $abc[$index].$result; // concatenate the letter
    }
    return $result;
}

Bunu yapmak için daha iyi bir yol biliyor musunuz? Daha basit tutmak için bir şey olabilir mi? yoksa performans artışı mı?

Edit

ircmaxell uygulaması gayet iyi çalışıyor. Ama, bu güzel kısa bir ekleme yapacağım:

function num2alpha($n)
{
    for($r = ""; $n >= 0; $n = intval($n / 26) - 1)
        $r = chr($n&   0x41) . $r;
    return $r;
}

CEVAP
21 Temmuz 2010, ÇARŞAMBA


İşte güzel basit bir özyinelemeli işlev (sıfır endeksli sayılar, 0 == anlamı, 1 == B Dayanan, vb.)

function getNameFromNumber($num) {
    $numeric = $num % 26;
    $letter = chr(65   $numeric);
    $num2 = intval($num / 26);
    if ($num2 > 0) {
        return getNameFromNumber($num2 - 1) . $letter;
    } else {
        return $letter;
    }
}

Ve eğer bir dizine (1 == A, vb) varsa

function getNameFromNumber($num) {
    $numeric = ($num - 1) % 26;
    $letter = chr(65   $numeric);
    $num2 = intval(($num - 1) / 26);
    if ($num2 > 0) {
        return getNameFromNumber($num2) . $letter;
    } else {
        return $letter;
    }
}

0 sayıları ile test 10000...

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • J Medema

    J Medema

    11 EKİM 2006
  • kruno j

    kruno j

    6 Mayıs 2007
  • wwjoshdu

    wwjoshdu

    18 ŞUBAT 2011