使用MySQL改进算法


Improving algorithm using MySQL

下面的代码主要是用PHP编写的,但我希望加快这个过程,在PHP中解析字符串很慢。

假设我从数据库中获得一个字符串,并将其转换为数组。

$data['options_list'] = array(
            "Colours" => array('red','blue','green','purple'),
            "Length" => array('3','4','5','6'),
            "Voltage" => array('6v','12v','15v'),
        );

每个子数组都是一个下拉选择列表,最终用户可以从每个选择列表中选择1个。

当用户点击提交时,我希望将提交的值与管理员预定义的"价格表"进行匹配。可能"红色"answers"6v"的价格是5美元,但"红色"answers"5"(长度)和"6v"的价格是6美元。

问题是,如何做到这一点?

目前我采取的方法是:

提交表单(3个选择列表)后,我从数据库中获得管理员设置的相关价格规则。我以结果为例。

$data['price_table'] = 
            array(
                'red;4'=>'2',
                'red;5'=>'3',
                'red;6'=>'4',
                'blue;3'=>'5',
                'blue;4'=>'6',
                'blue;5'=>'7',
                'blue;6'=>'8',
                'green;3'=>'9',
                'green;4'=>'10',
                'green;5'=>'11',
                'green;6'=>'12',
                'purple;3'=>'13',
                'purple;4'=>'14',
                'purple;5'=>'15',
                'purple;6'=>'16',
                'red;3'=>'1',
                'red;3;12v'=>'17',
                'blue;6;15v'=>'18',
        );

注意:上面例子的顺序可以是任意顺序,算法应该可以工作

然后,我将上述每个元素分解成一个数组,并获得与最佳分数匹配的结果。
$option_choices = $this->input->post('select');
$score = 0;
        foreach($data['price_table'] as $key=>$value)
        {
            $temp = 0;
            $keys = explode(';',$key);
            foreach($keys as $k)
            {
                if(in_array($k, $option_choices))
                {
                    $temp++;
                }else{
                    $temp--;
                }               
            }
            if($temp > $score)
            {
                $score = $temp;
                $result = $value;
            }           
        }
        echo "Result : ".$result;

预期结果示例:

可选选项:"red","5"
结果:3

可选选项:"3","red"结果:1

可选选项:"red", "3", "12v"结果:17


当前方法按预期工作。但是,使用PHP处理这些问题很慢。我考虑过使用JSON,但这意味着我将向用户提供我的整个价格表,这并不是我真正想要的。我也考虑过使用另一种语言(例如python),但考虑到成本,它不是特别实用。那就剩下MySQL了。

如果有人可以建议一个便宜和成本效益的方式来做到这一点,请提供和例子。如果你能提供一个更快的PHP解决方案就更好了。

谢谢!

它看起来像你做的工作,使结果读得更快,但你仍然解析和测试每个数组部分针对完整的列表?将搜索移到MySQL并在那里添加额外的列可能会运行得更快。

既然你可以控制数组(或测试字符串),也许可以尝试固定长度的字符串:

$results = explode("'n", "
1         Red       v1
22        Blue      v2
333       Green     v3");
$i = 0;
while($i < count($results)) {
    $a = substr($results[$i], 0, 10);
    $b = substr($results[$i], 10, 20);
    $c = substr($results[$i], strpos(' ', strrev($results[$i]))-1);
    if(stripos($userInput, $a . $b . $c) !== false) {
            // parse more...

据说JavaScript在这方面很擅长:
http://addyosmani.com/blog/faster-javascript-memoization/