生成汽车牌照
用户随机50选1。好的车牌用户选不到。
我目前的做法是这样的。所有车牌入库。别人选了状态就修改为1。下面是入库程序,想跟大家讨论一下,有没有更好的方式。
<?php
use Illuminate\Database\Seeder;
class LicensePlatesTableSeeder extends Seeder
{
public function identicalNumber($numbers = [])
{
$identical = array_count_values($numbers);
$data = [
1 => 0,
2 => 0,
3 => 0,
4 => 0,
5 => 0,
];
foreach ($identical as $item) {
$data[$item]++;
}
return $data;
}
public function orderLength($keys = [])
{
$current = null;
$length = 0;
foreach ($keys as $key) {
if ($current === null || $key - 1 != $current || $key==26) {
$current = $key;
$length = 1;
continue;
}
$length += 1;
}
return $length;
}
public function run()
{
/**
* 生成26个字母和0到9的数字
*/
$data = [];
for ($i = 65; $i < 91; $i++) {
$data[] = strtoupper(chr($i));
}
for ($i = 0; $i <= 9; $i++) {
$data[] = $i;
}
$license = [];
foreach ($data as $key1 => $item1) {
foreach ($data as $key2 => $item2) {
foreach ($data as $key3 => $item3) {
foreach ($data as $key4 => $item4) {
foreach ($data as $key5 => $item5) {
$numbers = [$item1, $item2, $item3, $item4, $item5];
$key = [$key1, $key2, $key3, $key4, $key5];
$identicalNumber = $this->identicalNumber($numbers);
$license[] = [
'number' => implode('', $numbers),
'order_length' => $this->orderLength($key),//最大顺子长度。
'reverse_order_length' => $this->orderLength(array_reverse($key)),//倒序,最大顺子长度。
'identical_2' => $identicalNumber[2],//有2个数字相同的次数。
'identical_3' => $identicalNumber[3],//有3个数字相同的次数。
'identical_4' => $identicalNumber[4],//有4个数字相同的次数。
'identical_5' => $identicalNumber[5],//有5个数字相同的次数。
];
if (count($license) >= 8000) {
\App\LicensePlate::insert($license);
$license = [];
}
}
}
}
}
}
if ($license) {
\App\LicensePlate::insert($license);
}
\App\LicensePlate::where('id', '>', 0)->update([
'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
'updated_at' => \Carbon\Carbon::now()->toDateTimeString(),
]);
}
}
会生成6千万+条数据。用户查询出问题。之前想过,好的车牌放一个表,差的放一个表,但是怕业务会改规则,可能后面3个相同的,或4个相同的,都放出来随机。
用户查询50个随机车牌,去掉一些好的车牌。大家有什么好的优化方式吗?
$id=mt_rand(1,36*36*36*36*36-100000);
$LicensePlates = App\LicensePlate::select('id', 'number')
->whereBetween('id',[$id,$id+100000])//为什么加这个,是因为不加根本查不出来
->whereNull('use_at')//已使用的
->where('order_length', '<=', 2)//不能选顺子长度大于等于3的 比如 123AD ABCD8
->where('reverse_order_length', '<=', 2)//不能选倒序顺子长度大于等于3的 比如 AD321 D4321
->where('identical_2', '<=', 1)//不能选有二个对子,比如 11A22,BBC88
->where('identical_3', 0)//不能选2个相同的 比如 A1A4A AA23A AAA23
->where('identical_4', 0)//不能选4个相同的 比如 AAAA4 77B77 777B7
->where('identical_5', 0)//不能选5个相同的 比如 88888 99999 AAAAA
->inRandomOrder()//随机
->limit(50)
->get();
有人说叫不用入库,用户选好的,才入库。在前端界面随机生成50个,。。那么我怎么知道这50个。有没有给别的用户选了,又要去查一次数据库
你这个循环嵌套有点6😂
5 层循环 怕怕 :joy:
看着5层循环有点头痛,用堆栈写了下,运行在PHP CLI模式下;
估计让你不用数据库的意思是让你用redis之类的缓存吧
大兄弟你们这个车牌号是认真的吗?字母 I 和 O 是不予许的。
车牌号序号编码规则:
5.8.1 序号编码规则 序号编码规则有三种,分别是:
《中华人民共和国机动车号牌》GA 36-2014 代替 GA 36-2007
实施日期 2014-01-24
作者:sinkcup
链接:https://www.zhihu.com/question/19847950/an...
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。