किसी नंबर का एक्सेल जैसा कॉलम नाम पाने के लिए एल्गोरिदम


95

मैं एक स्क्रिप्ट पर काम कर रहा हूं जो कुछ एक्सेल दस्तावेज़ों को उत्पन्न करता है और मुझे एक संख्या को इसके स्तंभ नाम के समकक्ष बदलने की आवश्यकता है। उदाहरण के लिए:

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

मैंने पहले ही ऐसा करने के लिए एक एल्गोरिथ्म लिखा है, लेकिन मैं यह जानना चाहूंगा कि क्या यह करने के लिए सरल या तेज तरीके हैं:

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;
}

क्या आप इसे करने का एक बेहतर तरीका जानते हैं? शायद कुछ सरल रखने के लिए? या एक प्रदर्शन में सुधार?

संपादित करें

ircmaxell का कार्यान्वयन बहुत अच्छा काम करता है। लेकिन, मैं इस छोटे से छोटे को जोड़ने जा रहा हूं:

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

3
इस आदमी पृष्ठ में पहली टिप्पणी सहायक हो सकती है: php.net/manual/en/function.base-convert.php#96304
सर्गेई

वाह! यह एक छोटा कार्यान्वयन है। धन्यवाद!
क्रिस्टियन

क्या आपने किसी भी मौजूदा पुस्तकालयों को PHP से एक्सेल दस्तावेज़ बनाने के लिए देखा है?
मार्क बेकर

हां बिल्कुल। मैं अपने भयानक पुस्तकालय, मार्क का उपयोग कर रहा हूं। मुझे एल्गोरिदम लिखने में अपने कौशल को सुधारना पसंद है ... इसके बारे में क्या अच्छा है कि आप एक को समाप्त करने के बाद, आप अन्य एल्गोरिदम पा सकते हैं जो बिल्कुल वैसा ही करते हैं लेकिन कम होते हैं।
क्रिस्टियन

2
आपका लघु एल्गोरिथ्म आपके अनुरोध में 1 -> A के बजाय 1 -> A का उपयोग करता है, जो अनुरोध के अनुसार थोड़ा भिन्न होता है ... यदि आप चाहते हैं, तो PHPExcel का PHPExcel_Cell :: stringFromColumnIndex () विधि देखें, हालांकि आपका num2alpha () कार्यान्वयन हो सकता है तेज़ हो जाओ ... मैं कुछ परीक्षण चला रहा हूँ, और इसे (अनुमति के साथ) "उधार" ले सकता हूँ
मार्क बेकर

जवाबों:


155

यहाँ एक अच्छा सरल पुनरावर्ती कार्य है (शून्य अनुक्रमित संख्याओं के आधार पर, जिसका अर्थ है 0 == ए, 1 == बी, आदि ...)

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;
    }
}

और यदि आप चाहते हैं कि यह एक अनुक्रमित (1 == ए, आदि):

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 से 10000 तक की संख्या के साथ परीक्षण ...


धन्यवाद! मुझे 1/2 घंटे बचाया!
डैरिल हेन

मैंने इस PHP स्क्रिप्ट को JS में अनुवादित किया है
terox

मुझे संदेह है कि अगर लूप में उपयोग किया जाता है तो रिक्यूसिव फ़ंक्शन अच्छा है या नहीं? क्या यह स्टैक स्पेस समस्या का कारण बन सकता है?
स्कॉट चू

92

PhpSpreadsheet ( PHPExcel का उपयोग किया गया है )

// result = 'A'
\PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex(1);

नोट इंडेक्स 0 परिणाम 'Z' में

https://phpspreadsheet.readthedocs.io/en/develop/


सही उत्तर (यदि आप PHPExcel लाइब्रेरी का उपयोग करते हैं ) है:

// result = 'A'
$columnLetter = PHPExcel_Cell::stringFromColumnIndex(0); // ZERO-based! 

और पीछे की ओर:

// result = 1
$colIndex = PHPExcel_Cell::columnIndexFromString('A');

12
stringFromColumnIndex (1) रिटर्न 'बी'
उल्टी

1
अति उत्कृष्ट! मैं PHPExcel का उपयोग करने के लिए होता हूं। यह साफ-साफ जवाब है।
स्कॉट चू

PHPExcel_Cell::stringFromColumnIndex(1)वास्तव में रिटर्न 'B', कृपया अपना उत्तर संपादित करें।
१२:२२

13

1 -> ए, 2 -> बी, आदि के लिए अनुक्रमित

function numToExcelAlpha($n) {
    $r = 'A';
    while ($n-- > 1) {
        $r++;
    }
    return $r;
}

0 -> ए, 1 -> बी, आदि के लिए अनुक्रमित

function numToExcelAlpha($n) {
    $r = 'A';
    while ($n-- >= 1) {
        $r++;
    }
    return $r;
}

इस तथ्य का लाभ उठाता है कि चरित्र चर पर अंकगणितीय संचालन से निपटने के दौरान PHP पर्ल के सम्मेलन का अनुसरण करता है और सी का नहीं। ध्यान दें कि वर्ण चर में वृद्धि की जा सकती है, लेकिन घटती नहीं।


यह एक अच्छा समाधान है, लेकिन मुझे लगता है कि यह 1234567789 जैसे बड़ी संख्या में सर्वर को समय देगा।
ताहिर रजा

5

यह रूपांतरण (पूर्णांक अंकगणित मानकर) करेगा, लेकिन मैं अन्य पोस्टरों से सहमत हूं; महज प्रयोग करेंbase_convert

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

    $result = "";
    while ($number > 0) {
       $index  = $number % $len;
       $result = $abc[$index] . $result;
       $number = floor($number / $len);
    }

    return $result;
}

यह वापस आ जाएगी Bके लिए $number = 1के बजाय Aके बाद से 1 % 26है1
जलाल

5

देर से जवाब, लेकिन यहाँ मैंने क्या किया (1 == एक अनुक्रमित के लिए):

function num_to_letters($num, $uppercase = true) {
    $letters = '';
    while ($num > 0) {
        $code = ($num % 26 == 0) ? 26 : $num % 26;
        $letters .= chr($code + 64);
        $num = ($num - $code) / 26;
    }
    return ($uppercase) ? strtoupper(strrev($letters)) : strrev($letters);
}

फिर अगर आप दूसरे तरीके को बदलना चाहते हैं:

function letters_to_num($letters) {
    $num = 0;
    $arr = array_reverse(str_split($letters));

    for ($i = 0; $i < count($arr); $i++) {
        $num += (ord(strtolower($arr[$i])) - 96) * (pow(26,$i));
    }
    return $num;
}

3

एक्सेल कॉलम अक्षरों में नंबर कन्वर्ट करें:

/**
 * Number convert to Excel column letters
 * 
 * 1 = A
 * 2 = B
 * 3 = C
 * 27 = AA
 * 1234567789 = CYWOQRM
 * 
 * @link https://vector.cool/php-number-convert-to-excel-column-letters-2
 * 
 * @param int  $num       欄數
 * @param bool $uppercase 大小寫
 * @return void
 */
function num_to_letters($n)
{
    $n -= 1;
    for ($r = ""; $n >= 0; $n = intval($n / 26) - 1)
        $r = chr($n % 26 + 0x41) . $r;
    return $r;
}

उदाहरण के लिए:

echo num_to_letters(1);          // A
echo num_to_letters(2);          // B
echo num_to_letters(3);          // C
echo num_to_letters(27);         // AA
echo num_to_letters(1234567789); // CYWOQRM

एक्सेल कॉलम अक्षर संख्या में परिवर्तित होते हैं:

/**
 * Excel column letters convert to Number
 *
 * A = 1
 * B = 2
 * C = 3
 * AA = 27
 * CYWOQRM = 1234567789
 * 
 * @link https://vector.cool/php-number-convert-to-excel-column-letters-2
 * 
 * @param string $letters
 * @return mixed
 */
function letters_to_num($a)
{
    $l = strlen($a);
    $n = 0;
    for ($i = 0; $i < $l; $i++)
        $n = $n * 26 + ord($a[$i]) - 0x40;
    return $n;
}

उदाहरण के लिए:

echo letters_to_num('A');       // 1
echo letters_to_num('B');       // 2
echo letters_to_num('C');       // 3
echo letters_to_num('AA');      // 27
echo letters_to_num('CYWOQRM'); // 1234567789

2
<?php
function numberToColumnName($number){
    $abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $abc_len = strlen($abc);

    $result = "";
    $tmp = $number;

    while($number > $abc_len) {
        $remainder = $number % $abc_len;
        $result = $abc[$remainder-1].$result;
        $number = floor($number / $abc_len);
    }
    return $abc[$number-1].$result;
}

echo numberToColumnName(1)."\n";
echo numberToColumnName(25)."\n";
echo numberToColumnName(26)."\n";
echo numberToColumnName(27)."\n";
echo numberToColumnName(28)."\n";
echo numberToColumnName(14558)."\n";
?>

अच्छा प्रयास! हालांकि यह विफल हो जाएगा ... इसे 2049 के साथ आज़माएं और आप देखेंगे: D
क्रिस्टियन

2

Ircmaxell के पुनरावर्ती उत्तर के संयोजन से मुझे यह मिल गया है:

    फ़ंक्शन getNameFromNumber ($ num, $ index = 0) {
        $ इंडेक्स = एब्स ($ इंडेक्स * 1); // सुनिश्चित करें कि सूचकांक एक सकारात्मक पूर्णांक है
        $ संख्यात्मक = ($ संख्या - $ सूचकांक)% २६; 
        $ पत्र = chr (65 + $ संख्यात्मक);
        $ num2 = intval (($ num - $ index) / 26);
        अगर ($ num2> 0) {
            रिटर्न getNameFromNumber ($ num2 - 1 + $ इंडेक्स)। पत्र $;
        } अन्य {
            $ पत्र लौटाओ;
        }
    }

मैं 0 के रूप में डिफ़ॉल्ट अनुक्रमणिका का उपयोग कर रहा हूं, लेकिन यह PHP में सरणियों के साथ काम करते समय किसी भी सकारात्मक पूर्णांक हो सकता है।


2

मैं उत्पादन में इसका इस्तेमाल कभी नहीं करूंगा क्योंकि यह पठनीय नहीं है, लेकिन मज़े के लिए ... केवल ZZ तक ही है।

<?php
    $col = 55;
    print (($n = (int)(($col - 1) / 26)) ? chr($n + 64) : '') . chr((($col - 1) % 26) + 65);
?>

0

एक की तलाश में किसी को भी करने के लिए जावास्क्रिप्ट इस का कार्यान्वयन, यहाँ है @ ircmaxell के जवाब में जावास्क्रिप्ट ..

function getNameFromNumber(num){
    let numeric = num%26;
    let letter = String.fromCharCode(65+numeric);
    let num2 = parseInt(num/26);
    if(num2 > 0) {
      return getNameFromNumber(num2 - 1)+letter;
    } else {
      return letter;
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.