数字转换为汉字
前段时间,因为一个朋友提到了数字转化为汉字,开始我并不以为这有什么难度,但千一段时间想着自己动手写一下相关的算法,发现好像还是没那么容易,后来一下午过去了,试写了各种方式,但好像都不能很好地兼容,特别是0的处理。于是在网上搜索了一些资料,但好像并没能很好地解决这个0的问题,找了些相关代码见下。
来自: http://my.csdn.net/Q718330882(田小涛)(在这并没想说谁是谁非,只想为书写代码而奋斗),因为没有完整的源码所以自己手动加了类名。
class numberToChanise
{
public function num2ch($num) //整体读取转换
{
$num_real = $this->del0($num);//去掉前面的“0”
$numlen = strlen($num_real);
if($numlen >= 9)//如果满九位,读取“亿”位
{
$y=substr($num_real, -9, 1);
//echo $y;
$wsbq = substr($num_real, -8, 4);
$gsbq = substr($num_real, -4);
$a = $this->num_r($this->del0($gsbq));
$b = $this->num_r($this->del0($wsbq))."万";
$c = $this->num_r($this->del0($y))."亿";
}
elseif($numlen <= 8 && $numlen >= 5) //如果大于等于“万”
{
$wsbq = substr($num_real, 0, $numlen-4);
$gsbq = substr($num_real, -4);
$a = $this->num_r($this->del0($gsbq));
$b = $this->num_r($this->del0($wsbq))."万";
$c="";
}
elseif($numlen <= 4) //如果小于等于“千”
{
$gsbq = substr( $num_real, -$numlen);
$a = $this->num_r($this->del0($gsbq));
$b="";
$c="";
}
$ch_num = $c.$b.$a;
return $ch_num ;
}
public function del0($num) //去掉数字段前面的0
{
return "".intval($num);
}
public function n2c($x) //单个数字变汉字
{
$arr_n = array("零","一","二","三","四","五","六","七","八","九","十");
return $arr_n[$x];
}
public function num_r($abcd) //读取数值(4位)
{
$arr= array();
$str = ""; //读取后的汉字数值
$flag = 0; //该位是否为零
$flag_end = 1; //是否以“零”结尾
$size_r = strlen($abcd);
for($i=0; $i<$size_r; $i++)
{
$arr[$i] = $abcd{$i};
}
$arrlen = count($arr);
for($j=0; $j<$arrlen; $j++)
{
$ch = $this->n2c($arr[$arrlen-1-$j]); //从后向前转汉字
if($ch == "零" && $flag == 0)
{ //如果是第一个零
$flag = 1; //该位为零
$str = $ch.$str; //加入汉字数值字符串
continue;
}
elseif($ch == "零")
{ //如果不是第一个零了
continue;
}
$flag = 0; //该位不是零
switch($j)
{
case 0: $str = $ch; $flag_end = 0; break; //第一位(末尾),没有以“零”结尾
case 1: $str = $ch."十".$str; break; //第二位
case 2: $str = $ch."百".$str; break; //第三位
case 3: $str = $ch."千".$str; break; //第四位
}
}
if($flag_end == 1) //如果以“零”结尾
{
mb_internal_encoding("UTF-8");
$str = mb_substr($str, 0, mb_strlen($str)-1); //把“零”去掉
}
return $str;
}
}
$obj = new numberToChanise();
//数字2009080
echo $obj->num2ch('2009080');
//结果如下:
//二百万九千零八十(该结果正确)
//数字200980
echo $obj->num2ch('200980');
//二十万九百八十(不正确)
其实这个算法兼容性很小,中间带0的不能很好处理,很容易出错,这里就不继续列举了(例如:2000009800590,209800590)。当然我还找了其他算法(好像都不太完整兼容),这里就不一一粘贴出来了。 还是自己想办法吧,只能占时将这个问题搁置了,晚上睡觉时也在思考用什么方式处理0出现的问题比较好,过了两天不知道从哪里来的灵感,这种存储和取出的感觉很强烈,后来采用归拿总结的方式就能很好的处理数字转化中文的问题,就是划分最小单元(四位数为一最小单位组),这里贴出的代码没有处理10(十)这种,不过读者可以自己处理。其他的就不多说了,上代码如下。
function number2Chanise($num)
{
//支持到M级别
$unit = array(
"",
"",
"十",
"百",
"千",
"万",
"亿",
"万亿",
"亿亿",
"万亿亿",
);
$code = array(
'0000' => "",
'0001' => "零x",
'0010' => "零x十",
'0011' => "零x十x",
'0101' => "零x百零x",
'0100' => "零x百",
'0110' => "零x百x十",
'0111' => "零x百x十x",
1000 => "x千",
1001 => "x千零x",
1100 => 'x千x百',
1010 => 'x千零x十',
1011 => 'x千零x十x',
1101 => 'x千x百零x',
1110 => 'x千x百x十',
1111 => 'x千x百x十x',
100 => 'x百',
101 => 'x百零x',
110 => 'x百x十',
111 => 'x百x十x',
10 => 'x十',
11 => 'x十x',
1 => 'x',
0 => '零'
);
$arr = array(
0 => "零",
1 => "一",
2 => "二",
3 => "三",
4 => "四",
5 => "五",
6 => "六",
7 => "七",
8 => "八",
9 => "九"
);
$strNum = (string)$num;
$len = strlen($strNum);
$tmp = "";
$count = ceil($len / 4);
$remain = $len % 4;
if($remain)
{
$count -= 1;
}
for($i=1;$i <= $count;$i++)
{
$tmpStr[] = substr($strNum, -4 * $i,4);
}
if($remain)
{
$tmpStr[] = substr($strNum, -4 * $count - $remain,$remain);
}
$tmpStr = array_reverse($tmpStr);
$c = count($tmpStr);
$strk = "";
$t = $c;
//拆分成数组形式
foreach($tmpStr as $k => $strNum)
{
$tmp = "";
$l = 0;
$len = strlen($strNum);
for($i=0;$i<$len;$i++)
{
if($strNum[$i] == 0)
{
$tmp .= 0;
}
else $tmp .= 1;
}
$ts = $code[$tmp];
for($i = 0; $i < $len;$i++)
{
if($strNum[$i] != 0)
{
$ts = substr_replace($ts,$arr[$strNum[$i]],strpos($ts, 'x'),1);
}
else $l++;
}
if($t > 1)
{
if($l < 4)
{
$ts .= $unit[$c - $k + 3];
}
$t--;
}
$strk .= $ts;
}
return $strk;
}
$num = '29000407';
echo number2Chanise($num)
//输出:二千九百万零四百零七
但由于这种状况不知道怎么读。
$num = '2900009407';
//输出:二十九亿九千四百零七
若是读作:二十九亿零九千四百零七,则上面的代码需要修正下。
1).在
$code数组中将0000=>''变为0000=>'零';
2).在返回前加上代码:return str_replace('零零','零',$strk);
若需要交流,请发送邮件到kkkshykkk@126.com
转载请注明原文地址: https://ju.6miu.com/read-676014.html