标签:
在处理数据中,我们经常会遇到正整数中文数据,在存储数据库的时候,我们倾向于存储为阿拉伯数字,因为阿拉伯数字是方便统计和后续计算的。例如对于中文价格数据,存储为阿拉伯数字数据是合理的。
在写这段程序的时候,我搜了一下网上用php写的代码,感觉大部分扩展性和兼容性都不是特别好,所以索性自己写了一个:
1 function toALBSingNumber($Num) { 2 switch ($Num) { 3 case ‘一‘ : 4 return 1; 5 case ‘二‘ : 6 return 2; 7 case ‘三‘ : 8 return 3; 9 case ‘四‘ : 10 return 4; 11 case ‘五‘ : 12 return 5; 13 case ‘六‘ : 14 return 6; 15 case ‘七‘ : 16 return 7; 17 case ‘八‘ : 18 return 8; 19 case ‘九‘ : 20 return 9; 21 default : 22 return 0; 23 } 24 } 25 function toALBLevel($Level) { 26 switch ($Level) { 27 case ‘亿‘ : 28 return 10000; 29 case ‘万‘ : 30 return 10000; 31 case ‘千‘ : 32 return 1000; 33 case ‘百‘ : 34 return 100; 35 case ‘十‘ : 36 return 10; 37 default : 38 return 1; 39 } 40 } 41 function toALBNumber($str) { 42 $money = 0; 43 $preLevel=10000000000000000000000000;//一个缺省的极大值 44 $level = "/(.)?(亿|万|千|百|十)/u";//问号为了兼容个位没有的量级 45 $last="/[一二三四五六七八九]$/u"; 46 preg_match($last, $str,$SingLast);//个位 47 preg_match_all ( $level, $str, $arr );//高位切分 48 for($i=0;$i<count($arr[1]);$i++) { 49 $albLevel=toALBLevel($arr[2][$i]); 50 $albSingNum=toALBSingNumber($arr[1][$i]); 51 if($albLevel>$preLevel) { 52 $money=($money+$albSingNum)*$albLevel; 53 $preLevel=$albLevel; 54 } else { 55 $money=$money+$albSingNum*$albLevel; 56 $preLevel=$albLevel; 57 } 58 59 } 60 if(isset($SingLast[0])) { 61 $money+=toALBSingNumber($SingLast[0]); 62 } 63 return $money; 64 }
toALBNumber是主要函数,调用的toALBLevel和toALBSingNumber是获取相关单位和值的函数。
写这个函数的思路相对简单。我们分析一个数据:一千二百五十二万三千八百四十一。
一二三四五六七八九是基础数字,换算到阿拉伯数字里面会是每一位的数字,但是十百千万这种不是位上的数字,而是指明位。
所以我可以用正则表达式对每一位和每一位上的值全部取出,之后根据对应的位关系,做出乘法和加法操作。
这样就可以完成任务了。
在细节方面,你可以看出:
我所使用的缺省最大位以及需要保留前一位的价值所在。对应于前面举例的数据,我们知道正常情况我们要做的是位和值的乘法。
上面数据切分之后是下面的样子:
一千 | 1*1000 |
二百 | 2*100 |
五十 | 5*10 |
二万 | 2*10000 |
三千 | 3*1000 |
…… |
这样就可以看出在二万这个位置出现了问题。所以我们要保留前一个位和后一个位作比较,一旦前一个位小于后一个位,那么就不能单纯的把前面加和的值与后面数字和位的乘积加和。
正确的操作应该是,把前面的和与后面的数字相加然后乘以后面的数位。
因此,正确的加法应该是:(1*1000+2*100+5*10+2)*10000.
我粗略测试没有问题,基本上没有遇到过超过个位数的数据误差,这也是我要处理的数据能够允许的误差。
基本上,这不算一个复杂的问题,只要想清楚中文数字描述的逻辑,就可以对应到数学里面常用的阿拉伯数字。
如果你有更简单的方法,欢迎指教。
标签:
原文地址:http://www.cnblogs.com/toocooltohavefriends/p/5435100.html