zoukankan      html  css  js  c++  java
  • 拼写纠错

    <?php
    
    /**
        事件a:输入正确单词
        事件b:输入错误单词
        p(a|b):已经输入了错误的单词b,但是想输入的是正确单词a的概率。可以看出在输入一个错误单词b时,就是找到一个p(a|b)概率最大的a,单词a就是所求。
        p(b|a):已经输入了正确的单词a,但是可能输入成错误单词b的概率。一般约难拼写的就越高。
        p(a):输入正确单词的概率,也就是频率。
        
        p(a|b)=p(b|a)*p(a)/p(b);
        答案就是找到一个最大的p(a|b),p(a|b)根据公式,又只和p(b|a)和p(a)有关。
        所以,问题的答案就应该是 
        首先这个词a被写成词b的概率很大,对应p(b|a)很大。一般越是相近的词越有可能被拼错。
        其次这个词a的词频很高,对应p(a)很大。
    **/
    
    function init($file){
        $fp= fopen("http://norvig.com/big.txt","r");
        $a = array();
        while(!feof($fp)){
            $line = fread($fp,1024);
            $words = preg_split('/ /',$line);
            foreach($words as $w){
                preg_match('/[a-zA-Z]*/',$w,$matches);
                if(!array_key_exists(strtolower($matches[0]),$a)){
                    $a[strtolower($matches[0])] = 1;
                }else{
                    $a[strtolower($matches[0])] += 1;
                }
            }
            if(count($a)>10000){
                break;    
            }
            
        }
        fclose($fp);
        file_put_contents($file,json_encode($a));
    }    
    
    function load_words($file='word'){
        if(!is_file($file)){
            init($file);    
        }
        $data = file_get_contents("word","r");
        return json_decode($data,true);
    }
    
    function load_wrong($file='wrong'){
        if(!is_file($file)){
            $fp = fopen($file,'a+');
            fclose($fp);
            return array();        
        }
        $data = file_get_contents("wrong","r");
        return json_decode($data,true);
    }
    
    function log_wrong($fix,$w,$file='wrong'){
        $data = json_decode(file_get_contents($file),true);
        if(!isset($data[$fix])){
            $data[$fix] = array();
            $data[$fix][$w] = 1;
        }else{
            array_key_exists($w,$data[$fix])?$data[$fix][$w]++:$data[$fix][$w]=1;
        }
        file_put_contents($file,json_encode($data));
    }
    
    function distance($str1,$s1,$str2,$s2,$diff=0){    
        if($diff>=4){
            return 99;
        }
        if($s1>=strlen($str1)||$s2>=strlen($str2)){
            return max(strlen($str2)-$s2,strlen($str1)-$s1);
        }
        if($str1[$s1]==$str2[$s2]){
            return distance($str1,$s1+1,$str2,$s2+1,$diff);
        }else{
            return min(min(distance($str1,$s1,$str2,$s2+1,++$diff),distance($str1,$s1+1,$str2,$s2,++$diff)),distance($str1,$s1+1,$str2,$s2+1,++$diff))+1;
        }
    }
    
    function arr_sum($arr){
        $sum = 0;
        foreach($arr as $a){
            foreach($a as $sub_a){
                $sum += $sub_a;
            }
        }
        return $sum;
    }
    
    function auto_complete($w){
        $words = load_words();
        $wrong = load_wrong();
        $count=0;
        if(array_key_exists($w,$words)){
            return $w;
        }else{
            $fixs = array();
            $words_sum = array_sum($words);
            $wrong_sum = arr_sum($wrong);
            foreach($words as $word=>$feq){
                if(abs(strlen($word)-strlen($w))<3){
                    $dist = distance($word,0,$w,0);            
                    if($dist <= 2){
                        $fixs[$word] = sqrt($feq/$words_sum); //防止高词频的单词经常被匹配,比如arry会匹配到are而不是array,所以弱化了词频的影响,用sqrt越是高词频被弱化的越明显。
                        if($wrong[$word][$w]/$wrong_sum!=0){
                            $fixs[$word] *= $wrong[$word][$w]/$wrong_sum; 
                        }
                        $fixs[$word] *= 1/($dist);
                    }
                }
    
            }
            arsort($fixs);
            var_dump($fixs);
            $ret = array_keys($fixs);
            return $ret[0]; //这里也可也设定一个闸值,大于多少的都返回。
        }
    }
    
    $w = "beautifual";
    $fix = auto_complete($w);
    echo '<br>'.$w.'修正结果:'.$fix.'<br>';    
    
    /**
    ***确认单词,假设fix的就是正确的。
    **/
    if(strcmp($fix,$w)!=0){
        log_wrong($fix,$w);
    }    
    
    ?>

    写着玩而已,里面肯定有很多纰漏,只是写个大概的意思。

  • 相关阅读:
    [转][ASP.NET MVC]如何定制Numeric属性/字段验证消息
    [转]how can I change default errormessage for invalid price
    [转]超详细图解:自己架设NuGet服务器
    [转]C#委托Action、Action<T>、Func<T>、Predicate<T>
    自定义Image HtmlHelper
    OAuth 开放授权 Open Authorization
    [转]巧克英语
    Radis
    MongoDB
    [转]asp.net 跨域单点登录
  • 原文地址:https://www.cnblogs.com/23lalala/p/2741612.html
Copyright © 2011-2022 走看看