LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 13364|回复: 27

考考你:如果将数字转换为大写数字?

[复制链接]
发表于 2003-6-19 21:32:05 | 显示全部楼层 |阅读模式
比如:
输入12,如何转换成壹拾贰/拾贰?输入1020,转成壹千零贰贰等......???当然输入的数字是任意的!;)
发表于 2003-6-20 17:53:57 | 显示全部楼层

初学perl,写的代码比较拖沓冗杂,与大家交流。

JavaLee兄出的这题,看似容易,真写起来才感到难度不小,俺花了一整天的时间才完成这个脚本,脚本对数字取值限制在999,999,999,999,999,999,99以内(不过可以通过修改脚本来扩大取值范围,俺实在是懒得想怎样写一个自动的:p),虽然我测试了不少数字,估计bug还是会有,大家如果有兴趣,也来测试一下。

lyoo@lsd:~/shellsample$ ./convert.pl
Please input a number:132345670000357
壹佰叁拾贰亿亿叁仟肆佰伍拾陆亿柒仟万零叁佰伍拾柒

  1. #!/usr/bin/perl -w

  2. # Chinese count method
  3. # wrote by Lyoo
  4. # [email]iamlyoo@163.com[/email]
  5. # 2003/07/20


  6. # match @unit = qw / 个 拾 佰 仟 /
  7. @unit = qw / A B C D / ;

  8. # match @unit_max = qw / 万 亿 万亿 亿亿 /
  9. @unit_max = qw / E F G H / ;

  10. $count = 0;

  11. while ( $count < 1 ) {
  12.         print "Please input a number:";
  13.         chomp ($number = <STDIN>);
  14.         if ( $number =~ /^\d+$/ && $number <= 99999999999999999999 ) {
  15.                 $count += 1;
  16.         } else {
  17.                 print "It's not a Number or a GOOD number!\n";
  18.                 print "Note: 0 < number < 999,999,999,999,999,999,99!\n";
  19.                 redo;
  20.         }
  21. }

  22. # add a number to the number_string,
  23. # so that the  while-loop can get the "0" in the  tail of the number_string.
  24. $number_9 = $number."9";

  25. # convert the number to a array.
  26. while ($number_9) {
  27.         my $single = $number_9;
  28.         $single =~ s/(\d).*/$1/;
  29.         $number_9 =~ s/\d(.*)/$1/;
  30.         push (@number_array,$single);
  31. }

  32. # delect the addion number.reverse the array.
  33. pop @number_array;
  34. @number_array = reverse @number_array;
  35. #print "the number_array is @number_array";

  36. # deal with unit.
  37. $i = 0;
  38. foreach (@number_array) {
  39.         $number_unit .= $unit[$i].$_;
  40.        
  41.         $i++;
  42.         $i= $i % 4;
  43. }
  44. #print "the number_unit is $number_unit\n";

  45. # deal with unit_max.
  46. $_ = $number_unit;
  47. s/A//;
  48. s/A/$unit_max[0]/;
  49. s/A/$unit_max[1]/;
  50. s/A/$unit_max[2]/;
  51. s/A/$unit_max[3]/;

  52. # delete the superfluous unit.
  53. s/[A-D]0/0/g;
  54. #print "number_unit_max now is $_\n";

  55. # delete superfluous 0.
  56. s/0+/0/g;
  57. s/([E-H])0/$1/g;
  58. #print "number_unit_max now is $_\n";

  59. s/EF/F/g;
  60. s/FG/G/g;
  61. s/GH/H/g;

  62. $number_unit_max = reverse $_;
  63. #print "the number_unit_max is $number_unit_max\n";

  64. # convert number_unit_max to array.
  65. while ($number_unit_max) {
  66.         my $single = $number_unit_max;
  67.         $single =~ s/(\w).*/$1/;
  68.         $number_unit_max =~ s/\w(.*)/$1/;
  69.         push (@number_unit_max_array,$single);
  70. }
  71. #print "number_unit_max_array is @number_unit_max_array.\n";

  72. foreach (@number_unit_max_array) {
  73.         &print_chinese;
  74. }
  75. print "\n";

  76. sub print_chinese {
  77.         if ($_ eq 0) {
  78.                 print "零";
  79.         } elsif ($_ eq 1) {
  80.                 print "壹";
  81.         } elsif ($_ eq 2) {
  82.                 print "贰";
  83.         } elsif ($_ eq 3) {
  84.                 print "叁";
  85.         } elsif ($_ eq 4) {
  86.                 print "肆";
  87.         } elsif ($_ eq 5) {
  88.                 print "伍";
  89.         } elsif ($_ eq 6) {
  90.                 print "陆";
  91.         } elsif ($_ eq 7) {
  92.                 print "柒";
  93.         } elsif ($_ eq 8) {
  94.                 print "捌";
  95.         } elsif ($_ eq 9) {
  96.                 print "玖";
  97.         } elsif ($_ eq A) {
  98.                 print "个";
  99.         } elsif ($_ eq B) {
  100.                 print "拾";
  101.         } elsif ($_ eq C) {
  102.                 print "佰";
  103.         } elsif ($_ eq D) {
  104.                 print "仟";
  105.         } elsif ($_ eq E) {
  106.                 print "万";
  107.         } elsif ($_ eq F) {
  108.                 print "亿";
  109.         } elsif ($_ eq G) {
  110.                 print "万亿";
  111.         } elsif ($_ eq H) {
  112.                 print "亿亿";
  113.         }
  114. }
复制代码
 楼主| 发表于 2003-6-20 18:48:27 | 显示全部楼层
精彩!!~
不过,我认为用shell一样可以作得到的!可惜,我还没写出来呢!
LY兄的perl水平的进步真快呀~佩服
发表于 2003-6-20 22:05:10 | 显示全部楼层

bash版本

  1. #!/bin/bash
  2. #penny_ccf@hotmail.com
  3. #it's ugly, but it works :)
  4. cconvert(){
  5. declare -a cnum;
  6. declare -a cmag;
  7. cnum[1]="壹"
  8. cnum[2]="贰"
  9. cnum[3]="叁"
  10. cnum[4]="肆"
  11. cnum[5]="伍"
  12. cnum[6]="陆"
  13. cnum[7]="柒"
  14. cnum[8]="拔"
  15. cnum[9]="玖"
  16. cnum[0]="零"
  17. cmag[0]=""
  18. cmag[1]="拾"
  19. cmag[2]="佰"
  20. cmag[3]="仟"
  21. cmag[4]="万"
  22. cmag[5]="拾"
  23. cmag[6]="百"
  24. cmag[7]="千"
  25. tempalpha="$1";
  26. ctempmag=$2;
  27. if [ $tempalpha == "00000000" ] ; then
  28. CSTR="";
  29. return 0;
  30. fi
  31. let templength="${#tempalpha}";
  32. CSTR="";
  33. for ((m=0;m<templength;m++))
  34. do
  35. tempi=${tempalpha:m:1};
  36. let tempj="$templength-$m-1";
  37. if ((( tempi == 0 )) && (( tempj ==4 ))); then
  38. CSTR=$CSTR"万";
  39. elif (( tempi == 0 )); then
  40. CSTR=$CSTR${cnum[0]};
  41. else
  42. CSTR=$CSTR${cnum[$tempi]}${cmag[$tempj]};
  43. fi
  44. done
  45. CSTR=$(echo $CSTR | sed -e 's/零零*/零/g' -e 's/零$//g' -e 's/零零零万//g');
  46. CMAG="";
  47. for ((m=0;m<ctempmag;m++))
  48. do
  49. CMAG=$CMAG"亿";
  50. done
  51. CSTR=$CSTR$CMAG;
  52. }
  53. alpha=$1;
  54. length=${#alpha};
  55. let k="$length/8";
  56. let modl="$length%8";
  57. MYSTR="";
  58. tempstr=${alpha:0:$modl};
  59. if ((modl>0)); then cconvert $tempstr $k; fi
  60. MYSTR=$MYSTR$CSTR;
  61. for ((i=0;i<k;i++))
  62. do
  63.   let pos="$i*8+modl";
  64.   tempstr=${alpha:$pos:8};
  65.   let tempmag="$k-$i-1";
  66.   cconvert $tempstr $tempmag;
  67.   MYSTR=$MYSTR$CSTR;
  68. done  
  69. echo $MYSTR | sed -e 's/亿零万/亿零/g'  -e 's/零万/万/g' -e 's/零亿/亿/g' -e 's/零零*/零/g' -e 's/零$//g';
复制代码

$ ./convert.sh  1000222299999999999000000000099990000000002222200000
壹仟亿亿亿亿亿亿贰千贰百贰拾贰万玖仟玖佰玖拾玖亿亿亿亿亿玖千玖百玖拾玖万玖仟玖佰玖拾亿亿亿亿零亿亿亿零玖百玖拾玖万玖仟亿亿零贰拾贰亿贰千贰百贰拾万


转换任意长度
用到了bash的function和array,目前看起来还能用,不过写的很不好看

感谢LYOO兄的建议,改了两处bug,请继续测试
发表于 2003-6-20 22:30:08 | 显示全部楼层
妙,penny的脚本短小精悍!

不过超过一千万后的读数还是有问题:

lyoo@lsd:~$ ./pennyconvert.sh 10000000
壹壹千万
lyoo@lsd:~$ ./pennyconvert.sh 100000000
壹亿零万
lyoo@lsd:~$ ./pennyconvert.sh 1000000000
壹拾亿零万
lyoo@lsd:~$ ./pennyconvert.sh 10000000001
壹佰亿零万零壹
发表于 2003-6-20 22:36:58 | 显示全部楼层
呵呵,我在22:24分编辑了这个帖子
你在22:30发贴

你再copy一次?第一个壹壹千万还是有问题,后面几个倒是没问题了

这程序实在是写的难看,最后一堆sed修修补补,看来还是有漏掉的。。^_^

edit1: lyoo兄提出的bug都改掉了,又发现新bug。。调试中...
发表于 2003-6-20 23:13:52 | 显示全部楼层
呵呵,penny效率神速呀
这程序实在是写的难看,最后一堆sed修修补补,看来还是有漏掉的。。^_^

我也是一样,狂用s///g ;)
我的脚本有个毛病就是,超过万亿后,万亿和亿之间单位有重复,调试中...
看看这个1111111111100000,咱们俩的脚本都有毛病:
lyoo@lsd:~$ ./lyoo_convert.pl
Please input a number:1111111111100000
壹仟壹佰壹拾壹万亿壹仟壹佰壹拾壹亿壹仟壹佰壹拾万
lyoo@lsd:~$ ./penny_convert.sh 1111111111100000
贰壹千壹百壹拾壹万壹仟壹佰壹拾壹亿壹千壹百壹拾万
发表于 2003-6-20 23:20:04 | 显示全部楼层
哈哈,又升级了,嗯,试试这个10000000000000000001 。
发表于 2003-6-20 23:23:33 | 显示全部楼层
^_^,一分钟以前又升级了一次

$./convert.sh 10000000000000000001
壹仟亿亿零壹

./convert.sh 1111111111100000
壹千壹百壹拾壹万壹仟壹佰壹拾壹亿壹千壹百壹拾万

至少这两个都没问题了
发表于 2003-6-20 23:51:59 | 显示全部楼层
怪,我重新从上面拷贝了你的代码,可执行起来好象没什么改变。
...我还是先读读你的代码,希望能借点好东西,补补我的脚本:p
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表