我需要在 PHP 中创建一系列唯一的字母数字代码,从“AAA000”开始,递增到“ZZZ999”。代码应遵循以下模式:
此模式应给出总共 17,576,000 个唯一代码。我最初不确定如何处理增量,尤其是从“AAZ999”滚动到“ABA000”时。不过,我已经用 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”。
问题:
虽然此代码有效,但我很想知道是否有更有效或更优雅的方法来实现相同的结果,特别是在处理代码从“ZZY999”滚动到“ZZZ000”时的特殊情况。
请找到以下解决方案,这会对您有所帮助。
<?php
for($i = 'aaa'; $i < 'zzz'; $i++){
print "$i ";
}
?>
如果它不适合您或者您需要特定输出,请告诉我。
First of 循环遍历字母,因为它们是代码的开头。
然后在字母循环中,您可以遍历数字并将两者合并以创建字符串。
这是此功能的可行解决方案。
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();
// }
}
自从 PHP8.3 发布
str_increment()
(和 str_decrement()
)以来,此任务的所有潜在麻烦都被消除了。
代码:(演示)
$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
相关阅读:
如果您有一个数字
n
,则最后一位数字的值为 n % 10
。剩下的就是n - n % 10
。然后,您可以通过除以 10
来右移剩余数字。
示例:
123 % 10 = 3
。123 - 123 % 3 = 120
。120 / 10 = 12
。您的情况的重要区别在于数字的表示方式,它不特别使用“正常”十进制系统。然而,这仍然是 PHP 中的正常
integer
(二进制),只是您不使用默认的十进制输出。我在这里的意思是,您使用 string
作为数据类型的方法是有缺陷的。相反,使用 integer
来表示从 0
到 17575999
的值,只需使用不同的格式即可。
对于格式化,让我们将上述算法适应这种情况。首先,数字系统没有固定的基数。最后三位数字使用基数
10
。前面的数字使用基数 26
,这些数字表示为大写拉丁字母 A-Z
。 A = 0
和Z = 25
。另一个小细节是输出被零填充(或者更确切地说,A
填充)到六位数字。
示例:
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
。