1. 程式人生 > >python數字轉換成中文/數字轉換成漢字python:純字串方法最優

python數字轉換成中文/數字轉換成漢字python:純字串方法最優

這幾天做一個小程式的時候有了這樣的需求:把阿拉伯數字轉換成漢字,比如把‘101’轉換成‘一百零一’,把‘10000’轉換成‘一萬’。

做這樣的程式的時候有以下幾個技術難點:

1.加單位問題:比如需要加入‘十‘’百‘’千‘’萬’

2.去掉多餘的‘零’的問題:因為漢語中超過兩個單位為‘0‘,我們只會說一個‘零’。而且如果末尾位次也是零,則什麼都不讀。比如‘10001’讀作‘一萬零一’,而‘10000’就直接讀作‘一萬’。

3.保留較大單位的問題:在去零的過程中,我們需要保留‘萬’、‘億’這種單位,但是‘百’‘千’等就不需要。

為了解決問題,我設計了兩套程式設計思路(不用現成庫的情況):

1.採用字串替換法:

第一步:把原來的數字str()再list(),用漢字‘零一二三四五六七八九’替換‘0123456789’。

第二步:在需要的位置加入單位。

第三步:刪除多餘的單位和零

2.採用數學計演算法:

第一步:設計函式用原數字整除對應的10的次方數,比如200000就讓它整除100000。得數即為對應單位的數值,比如這個就是十萬位的2。

第二步:用原數字整除後的餘數(%取餘運算),繼續和對應的10的次方數進行整除,然後取餘……迴圈進行

第三步:在每一次整除後,都把得到的整數轉換為中文並和對應位次的單位的中文連線成字串。

第四步:如果取餘後的數比原數字小兩位或者以上,字串連線上一個‘零’,並跳過對應單位,理論上不產生多餘的‘零’和單位。

       有趣的是,方法二是一個非常有精細程式設計思想的做法,而且在實現的過程中可以通過拆分數字(比如把100000拆為10+0000)而進一步簡化程式(只用設計千位以內的程式即可,千以上的算完加個‘萬’就好),對於多餘‘零’的產生控制上可以說也是極其優秀,除了末尾外根本不會多出來沒用的‘零’和‘單位’。

      但是方法一,卻是一個很符合python思想的辦法:雖然會產生不計其數的多餘‘零’和單位,但是在計算的過程中幾乎沒有用到數學,都是if或者del這樣的簡單語句。在最後的多餘單位刪除中,可以採用正則表示式來提高效率。

      兩種方法各有優缺點,對於兩種變成思路,我分別設計了三種程式來完成任務,並對它們進行計時,對比效率:

任務內容:轉換1-9999999所有的數字併產生一個對應列表。

程式一思路:採用數學計演算法,整除對應10的次方數+取餘,把整除得數轉換成字串,加上對應單位數,再次進行。如果餘數和原數字差兩位且不是零,則輸出一個‘零’並連線。

程式二思路:採用字串法並應用正則表示式,先把原數字打成列表

用漢字替換所有數字並在對應位次插入單位。如果對應位次漢字是‘零’,則不插入單位,改為再插入一個‘零’。之後用正則表示式識別‘零’+並替換為‘零’,再刪除末尾‘零’後返回字串。

程式三思路:採用純字串方法。先把原數字打成列表用漢字替換數字並插入單位。將列表倒置,在列表內搜尋‘零’,再驗證找到位置處i後面兩位[i+2]處是否為單位或者‘零’,如果是,則刪除[i+1],之後遞迴。這樣的話零以後的所有多餘單位和零就全部被刪除了。然後進行搜尋,刪除所有‘零’左邊的一位[i-1](就是它原有對應的單位),之後再刪除末尾的‘零’即可。

不廢話,上程式碼:

程式一:

num=['零','一','二','三','四','五','六','七','八','九']

k=['零','十','百','千','萬','十','百']
import time

def rankid():
    rank=[]
    for i in range(9999999):
        a=tstr(i)
        rank.append(a)
    return rank

#取整取餘並連線,返回連線好的字串和餘數
def turn(x,y):
    if y>= 1:
        a=x//pow(10,y)
        b=x%pow(10,y)
        c=num[a]+k[y]
        if y>4 and b<pow(10,4):
            c+=k[4]
        if (len(str(x))-len(str(b))) >= 2 and b != 0:
            c+=k[0]
    else:
        a=x
        b=0
        c=num[a]

    return (c,b,)
#呼叫上一個函式,以保證進行完所有的數並返回
def tstr(x):
    c=turn(x,(len(str(x))-1))
    a=c[0]
    b=c[1]
    while b != 0:
        a+=turn(b,(len(str(b))-1))[0]
        b=turn(b,(len(str(b))-1))[1]

    return a

start=time.time()

ranki=rankid()
end=time.time()-start
print('程式共用時:%0.2f'%end)

共用時:362.93

程式很精巧,可惜太慢。

程式二:

import re,time
#主程式
def ranki():
    rank=[]
    for i in range(9999999):
        i=turn(i)
        rank.append(i)
    return rank
#如果超過萬,則分為兩部分以節約程式碼和執行速度
def turn(x):
    i=str(x)
    if len(i) >4:
        i=tran(i[0:-4])+'萬'+tran(i[-4:])
    else:
        i=tran(i[-4:])
    return i
#轉換數字並插入對應單位,單位為‘零’則再插入一個‘零’以方便正則表示式替換
def tran(x):
    num=['零','一','二','三','四','五','六','七','八','九']
    kin=['零','十','百','千']
    x=list(reversed(x))
    for i in x:
        x[(x.index(i))]=num[int(i)]
    if len(x) >= 2:
        if x[1]==num[0]:
            x.insert(1,kin[0])
        else:
            x.insert(1,kin[1])
        if len(x) >= 4:
            if x[3]==num[0]:
                x.insert(3,kin[0])
            else:
                x.insert(3,kin[2])
            if len(x) >= 6:
                if x[5]==num[0]:
                    x.insert(5,kin[0])
                else:
                    x.insert(5,kin[3])
    x=delz(x)
    return x
#進行多餘‘零’的刪除
#reversed()函式真是可以用在列表和字串。
#加上 if 語句 防止對不必要的資料進行正則表示式檢測
def delz(x):
    x=''.join(x)
    if '零零'in x:
        x=re.sub('零+','零',x)
    if x.startswith('零'):
        x=list(x)
        x.remove('零')
    x=reversed(x)
    x=''.join(x)
    return x
start=time.time()
rank=ranki()
end=time.time()-start
print('程式共用時:%0.2f'%end)
共用時:181.69s

是第一個的兩倍快。

程式三:

num=['零','一','二','三','四','五','六','七','八','九']
kin=['十','百','千','萬','零']
import time

def sadd(x):
    x.reverse()
    if len(x) >= 2:
        x.insert(1,kin[0])
        if len(x) >= 4:
            x.insert(3,kin[1])
            if len(x) >= 6:
                x.insert(5,kin[2])
                if len(x) >= 8:
                    x.insert(7,kin[3])
                    if len(x) >= 10:
                        x.insert(9,kin[0])
                        if len(x) >= 12:
                            x.insert(11,kin[1])

    x=fw(x)
    x=d1(x)
    x=d2(x)
    x=dl(x)
    return x
    
    
def rankis():
    rank=[]
    for i in range(9999999):
        i=list(str(i))
        for j in i:
            i[(i.index(j))]=num[int(j)]
        i=sadd(i)
        rank.append(i)
    return rank


def d1(x):
    if '零' in x:
        a=x.index('零')
        if a==0:
            del x[0]
            d1(x)
        else:
            if x[a+2] in ['十','百','千','萬','零']:
                if x[a+1] != '萬':
                    del x[a+1]
                    d1(x)     
    return x
def d2(x):
    try:
        a=x.index('零')
        if x[a-1] in ['十','百','千','零']:
            del x[a-1]
            d2(x[a+1])
    except:pass
    return x

def fw(x):
    if len(x) >= 9:
        if x[8] == '零':
            del x[8]
    return x
def dl(x):
    try:
        if x[0]=='零':
            del x[0]
            del1(x)
    except:pass
    x.reverse()
    x=''.join(x)
    return x
start=time.time()
rank=rankis()
end=time.time()-start
print('程式共用時:%0.2f'%end)
程式用時:123.68s

雖然還有些多餘程式碼,但是執行速度真是驚人。

總結:個人感覺python是字串至上的語言,很多地方字串都能被靈活運用,程式還遠遠不完美,希望能更快一步。

相關推薦

python數字轉換中文/數字轉換漢字python字串方法

這幾天做一個小程式的時候有了這樣的需求:把阿拉伯數字轉換成漢字,比如把‘101’轉換成‘一百零一’,把‘10000’轉換成‘一萬’。 做這樣的程式的時候有以下幾個技術難點: 1.加單位問題:比如需要加入‘十‘’百‘’千‘’萬’ 2.去掉多餘的‘零’的問題:因

oracle改進之將阿拉伯數字轉換中文數字

replace 工作 漢字 spa bsp func ace 延展 char   本博客是自己在學習和工作途中的積累與總結。 將阿拉伯數字轉換成中文漢字,方法自定義函數      create or replace function formate(val in num

c# 數字轉換中文數字

//數字轉換為中文 public string GetCountRefundInfoInChanese(string inputNum) { string[] intArr = { "0", "1", "2", "3", "4", "5", "

sql將阿拉伯數字轉換中文數字,MySQL數字轉大寫

CREATE FUNCTION `mathToChar`(`str` INT) RETURNS VARCHAR(100) character set gbk BEGIN DECLARE str1 VARCHAR(1) character set gbk DEFAULT '

【iOS開發系列】將阿拉伯數字轉換中文數字

/** * 將阿拉伯數字轉換為中文數字 */ +(NSString *)translationArabicNum:(NSInteger)arabicNum { NSString *arabicNumStr = [NSString stringWithForma

C#實現阿拉伯數字到大寫中文轉換

原文地址:http://www.jb51.net/article/8061.htm /// <summary> /// 金額轉為大寫金額 /// </summary> public class MoneyConvertChinese { /// &

把阿拉伯數字轉換中文數字

 var chnNumChar = [ "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" ];var chnUnitSection = [ "", "萬", "億", "萬億", "億億" ];var chnUnitChar =

php把阿拉伯數字轉化為中文數字

---恢復內容開始--- function numeral($num){ $china=array('零','一','二','三','四','五','六','七','八','九'); $arr=str_split($num); for($i=0;$i<count($arr);$i++

全國計算機等級考試二級教程--python語言程式設計(2018年版)第一章程式設計基本方法

宣告:本篇文章只是個人知識盲區、知識弱點、重點部分的歸納總結,望各位大佬不喜勿噴。梳理順序是按照書籍的實際順序梳理,轉載請註明出處。 作者:sumjess   一、python簡介: 1、python的誕生      創始人:Guido

將阿拉伯數字轉換中文的php函數

ont enum pre == tin 函數 array light blog function toChinaseNum($num){ $char = array("零","一","二","三","四","五","六","七","八","九"); $dw

完成將 toChineseNum, 可以將數字轉換中文大寫的表示,處理到萬級別,例如 toChineseNum(12345),返回 一萬二千三百四十五

turn nts math while log 處理 [0 floor rip const toChineseNum = (num) => { const unit = [‘‘, ‘十‘, ‘百‘, ‘千‘] const counts = [‘零

數字轉換中文大小寫、金額大小寫

ble clas upper subst sum turn remove 大小 spl 將數字轉換成中文大小寫、金額大小寫 /// <summary> /// 將數字轉換成中文大寫 /// <

萬以內的數字轉換中文大寫的方法

 閒話:一個朋友是做財務的,有一天問我98745的中文大寫是什麼,我也不知道,但是目前好多手機的計算器是可以直接轉換的,所以自己無聊也想寫一段程式碼試試於是就有了今天的水文,但是我個人覺得不算是太水,還是有點點內容的,希望喜歡的朋友可以沒事看看,我也 是一個小白,今年剛大學畢業也才工作

演算法練習03 把數字轉換中文

題目(2018-11-18) 完成將toChineseNum,可以將數字轉換成中文大寫的表示,處理到萬級別,例如toChineseNum(12345),返回一萬二千三百四十五。 實現 將數字按照四位分成一組,存放在輸入中,每一項的處理邏輯其實是相同的,無非是根據最後不同的位置

阿拉伯數字轉換中文大寫數字

function UpGB(InData:real):string; var a1,a2,a3,a4,a5,a6,a7:real; begin   a1 := int(InData/10000);   a2 := int((InData-a1*10000)/1000);  

js 數字金額大小寫轉換中文大寫

function Arabia_to_Chinese(Num) { for(i=Num.length-1;i>=0;i--) { Num = Num.replace(",","")//替換tomoney()中的“,” Num = Num.rep

金額從數字轉換中文漢字大寫的實現

以下簡單封裝的實現方法,詳細見註釋 class money2chinese { private $amount; // 金額 private $num2chinese; // 大寫數字 private $num_company; //

php數字金額轉換中文大寫顯示

整個功能其實不難,只是還算挺實用,所以記一下哈,其他程式語言轉換一下也是能可以的! 思路:把傳過來的金額轉換成整數和小數兩部分,再對其分別進行轉換處理 程式碼附上: function moneyToString($num) { $digits = ['零', '壹', '貳'

字串中的中文數字轉換阿拉伯數字

1、正則表示式的處理工具類 public class RexUtils { public static String and(String... rules) { St

數字轉換中文漢字數字

public class Test2 { private static final String[] UNITS = { "", "十", "百", "千", "萬", "十", "百", "千", "億", "十", "百", "千", }; private sta