php 按AAA000到ZZZ 999顺序生成字母数字代码

oyjwcjzk  于 4个月前  发布在  PHP
关注(0)|答案(4)|浏览(57)

我需要在PHP中创建一个唯一的字母数字代码序列,从'AAA 000'开始递增到'ZZZ 999'。代码应该遵循以下模式:

  • 从'AAA 000'到'AAA 999',然后'AAB 000'到'AAB 999',依此类推。
  • 在'AAZ 999'之后,它应该继续使用'ABA 000'而不是'ABZ 000'。
  • 最后的代码应该是'ZZZ 999'。

这个模式应该给予总共17,576,000个唯一代码。我最初不确定如何处理增量,特别是当从'AAZ 999'滚动到'ABA 000'时。然而,我已经用PHP开发了一个解决方案,似乎可以工作。

我目前的解决方案:

for($letter_code = 'aaa'; $letter_code < 'zzz'; $letter_code++){
    if($letter_code != 'zzy'){
        for($number_code = 0; $number_code <= 999; $number_code++){
            $code_str_number = str_pad($number_code, 3, "0", STR_PAD_LEFT);
            $total_records_processed_count++;
            print (strtoupper($letter_code).$code_str_number."\n");
        }
    } else {
        // Handle 'ZZZ' after 'ZZY'
        for($number_code = 0; $number_code <= 999; $number_code++){
            $code_str_number = str_pad($number_code, 3, "0", STR_PAD_LEFT);
            $total_records_processed_count++;
            print (strtoupper($letter_code).$code_str_number."\n");
        }
        for($number_code = 0; $number_code <= 999; $number_code++){
            $code_str_number = str_pad($number_code, 3, "0", STR_PAD_LEFT);
            $total_records_processed_count++;
            print ("ZZZ".$code_str_number."\n");
        }
    }
}

字符串

说明:

我使用了一个嵌套循环,外层是字母部分,内层是数字部分。为了处理数字部分,我使用了str_pad来确保数字总是有三位数。当$letter_code到达'zzy'时的特殊情况被处理为包括'ZZZ'。

问题:

当这段代码工作时,我想知道是否有更有效或更优雅的方法来实现相同的结果,特别是在处理代码从'ZZY 999'滚动到'ZZZ 000'时的特殊情况。
如果任何人有任何想法,我可以更好地这个问题,请给我一个评论,我会作出修改。

gajydyqb

gajydyqb1#

自从PHP8.3发布str_increment()(和str_decrement())以来,这个任务的所有潜在问题都被消除了。
产品编号:(Demo

$tests = [
    'AAA000',
    'AAA999',
    'AAZ999',
    'AZZ999',
    'ZZY999',
    'ZZZ999',
];

foreach ($tests as $t) {
    echo "\n$t => " . str_increment($t);
}

字符串
输出量:

AAA000 => AAA001
AAA999 => AAB000
AAZ999 => ABA000
AZZ999 => BAA000
ZZY999 => ZZZ000
ZZZ999 => AAAA000 <- throw a business logic exception if you like


要打印大量的这些字母数字值,最好使用生成器。对于较小的数据量,简单的循环就足够了。
代码:(Demo

function incGen(string $alnum = 'AAA000', string $stopBefore = 'AAAA000')
{
    if (!preg_match('/^[A-Z]{3}\d{3}$/', $alnum)) {
        throw new Exception('Invalid alnum value');
    }
    if ($stopBefore !== 'AAAA000' && !preg_match('/^[A-Z]{3}\d{3}$/', $stopBefore)) {
        throw new Exception('Invalid stopBefore value');
    }
    if ($alnum > $stopBefore) {
        throw new Exception('stopBefore cannot be reached by incrementation');
    }
    while ($alnum !== $stopBefore) {
        yield $alnum;
        $alnum = str_increment($alnum);
    }
}

foreach (incGen('AAA980', 'AAC123') as $value) {
    echo "$value\n";
}


相关阅读:

ie3xauqp

ie3xauqp2#

请找到下面的解决方案,这将帮助你。

<?php
for($i = 'aaa'; $i < 'zzz'; $i++){
  print "$i ";
} 
?>

字符串
让我知道,如果它不适合你,或者你需要具体的输出。

monwx1rj

monwx1rj3#

首先循环遍历字母,因为它们是代码的开头。
然后在字母的循环中,你可以遍历你的数字,并将两者合并以创建字符串。
下面是此功能的工作解决方案。

for($letter_code = 'aaa'; $letter_code < 'zzz'; $letter_code++){
    if($letter_code != 'zzy'){
// Reason for the if != 'zzy' is that I couldn't write <= 'zzz'
// This : <= 'zzz' breaks the loop.
        for($number_code = 0; $number_code <= 999; $number_code++){
            if($number_code > 99){
                $code_str_number = $number_code;
            }elseif($number_code > 9){
                $code_str_number = "0".$number_code;
            }else{
                $code_str_number = "00".$number_code;
            }
            $total_records_processed_count++;
            print (strtoupper($letter_code).$code_str_number."\n");
        }
    }else{
// Once reaching zzy we loop through zzy and then after do zzz
        for($number_code = 0; $number_code <= 999; $number_code++){
            if($number_code > 99){
                $code_str_number = $number_code;
            }elseif($number_code > 9){
                $code_str_number = "0".$number_code;
            }else{
                $code_str_number = "00".$number_code;
            }
            $total_records_processed_count++;
            print (strtoupper($letter_code).$code_str_number."\n");
        }
        $number_code = 0;
        for($number_code = 0; $number_code <= 999; $number_code++){
            if($number_code > 99){
                $code_str_number = $number_code;
            }elseif($number_code > 9){
                $code_str_number = "0".$number_code;
            }else{
                $code_str_number = "00".$number_code;
            }
            $total_records_processed_count++;
            print ("ZZZ".$code_str_number."\n");
        }
    }
    $number_code = 0;
    // For Testing Purposes just add this if() to cut the full loop 
    // if($letter_code == 'aab'){
    //  die();
    // }
}

字符串

q35jwt9p

q35jwt9p4#

如果你有一个数字n,最后一位的值是n % 10。余数是n - n % 10。然后你可以通过除以10来右移剩下的数字。
范例:

  • 最后一位是123 % 10 = 3
  • 剩余部分为123 - 123 % 3 = 120
  • 右移1是120 / 10 = 12
  • 对剩余的数字重复上述步骤。

与您的例子的重要区别是数字的表示方式,它没有使用“正常”十进制系统。(它是二进制的),只是你没有使用默认的十进制输出。我在这里的意思是,你使用string作为数据类型的方法是有缺陷的。相反,使用integer来表示从017575999的值,只是使用不同的格式。
对于格式化,让我们将上述算法适用于这种情况。首先,数字系统没有常数基数。最后三位使用基数10。之前的数字使用基数26,数字表示为拉丁字母A-Z. A = 0Z = 25。另外一个小细节是输出是零填充的(或者,更确切地说,A-填充)到六位数。
范例:

  • 从12345开始。
  • 最后一位是123456 % 10 = 6,移位余数是12345
  • 下一个数字是12345 % 10 = 5,移位余数是1234
  • 下一个数字是1234 % 10 = 4,移位余数是123
  • 下一个数字是123 % 26 = 19 = T,移位余数是4
  • 下一个数字是4 % 26 = 4 = E,移位余数是0
  • 下一个数字是0 % 26 = 0 = A,移位余数是0
  • 余数现在为零,因此转换不会溢出。
  • 结果是AET456

相关问题