生成汽车牌照

用户随机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();
附言 1  ·  4年前

有人说叫不用入库,用户选好的,才入库。在前端界面随机生成50个,。。那么我怎么知道这50个。有没有给别的用户选了,又要去查一次数据库

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 5
Epona

你这个循环嵌套有点6😂

4年前 评论
半人间 (楼主) 4年前
Jennie

5 层循环 怕怕 :joy:

4年前 评论
  • 看着5层循环有点头痛,用堆栈写了下,运行在PHP CLI模式下;

    $data = 'abcdefghijklmnopqrstuvwxyz0123456789';
    $res = [];
    for ($i=0;$i<=35;$i++){
    $res[] = substr($data,$i,1);
    }
    $totalNum = 0;
    foreach ($res as $k=>$v){
    $stack = new SplStack();
    $stack->push($v);
    while (!$stack->isEmpty()){
        $isString = $stack->pop();
        if (strlen($isString) == 6){
            $totalNum++;
            $str = $isString.'第'.$totalNum.'个数字'.PHP_EOL;
            file_put_contents('test.log',$str,FILE_APPEND);
            continue;
        }
        foreach ($res as $k=>$j){
            if (empty(strstr((string)$isString,(string)$j))){
                $stack->push($isString.$j);
            };
        }
    
    }
    }
4年前 评论

估计让你不用数据库的意思是让你用redis之类的缓存吧

4年前 评论
半人间 (楼主) 4年前

大兄弟你们这个车牌号是认真的吗?字母 I 和 O 是不予许的。

车牌号序号编码规则

5.8.1 序号编码规则 序号编码规则有三种,分别是:

  • a) 序号中的每一位都使用阿拉伯数字;
  • b) 序号中使用1位英文字母,其他位为阿拉伯数字,26个英文字母中O和I不能使用;
  • c) 序号中使用2位英文字母,其他位为阿拉伯数字,26个英文字母中O和I不能使用。

《中华人民共和国机动车号牌》GA 36-2014 代替 GA 36-2007

实施日期 2014-01-24

作者:sinkcup
链接:https://www.zhihu.com/question/19847950/an...
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4年前 评论
半人间 (楼主) 4年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!