fc2ブログ

どう書く?org F# 数字混じり文字列ソート

「どう書く?org」http://ja.doukaku.org/に挑戦です。   
さて今回の問題はこちら「数字混じり文字列ソート」http://ja.doukaku.org/295/ 
 
次のようなソードをおこなうソートを作れというものです。
 
辞書順ソート: 1.txt, 10.txt, 100.txt, 2.txt, 20.txt 
 
数字混じり文字列ソート: 1.txt, 2.txt, 10.txt, 20.txt, 100.txt 
 
例2: 
 
辞書順ソート: x12, x13, x1A, x1B, xAB 
 
数字混じり文字列ソート: x1A, x1B, x12, x13, xAB 
 
例3: 
 
辞書順ソート: A10B1, A10B10, A10B2, A1B1, A1B10, A1B2, A2B1, A2B10, A2B2 
 
数字混じり文字列ソート: A1B1, A1B2, A1B10, A2B1, A2B2, A2B10, A10B1, A10B2, A10B10
 
正規表現を利用して、愚直に実装してみました。(コードが堅い!)
速度も望めません。
 
> open System
open System.Text.RegularExpressions
 
let numRemRegex = new Regex("(?<topNum>(^([\\d]+)))(?<topNumRem>(.*))")
let strRemRegex = new Regex("(?<topStr>(^([^\\d]+)))(?<topStrRem>(.*))")
 
let rec compStrIncNum (st_L:string) (st_R:string) =
    let topNum_L = numRemRegex.Match(st_L).Groups.["topNum"]
    let topNum_R = numRemRegex.Match(st_R).Groups.["topNum"]
    let topStr_L = strRemRegex.Match(st_L).Groups.["topStr"]
    let topStr_R = strRemRegex.Match(st_R).Groups.["topStr"]
    if (topNum_L.Success && topNum_R.Success) then
       let intCompVal = compare (Int64.Parse(topNum_L.Value)) (Int64.Parse(topNum_R.Value)) 
       if intCompVal = 0 then
            let TopNumRem_L = numRemRegex.Match(st_L).Groups.["topNumRem"]
            let TopNumRem_R = numRemRegex.Match(st_R).Groups.["topNumRem"]
            compStrIncNum TopNumRem_L.Value TopNumRem_R.Value 
       else
            intCompVal
    elif (topStr_L.Success && topStr_R.Success) then
        let strCompVal = compare topStr_L.Value topStr_R.Value
        if strCompVal = 0 then
            let TopStrRem_L = strRemRegex.Match(st_L).Groups.["topStrRem"]
            let TopStrRem_R = strRemRegex.Match(st_R).Groups.["topStrRem"]
            compStrIncNum TopStrRem_L.Value TopStrRem_R.Value
        else 
            compare st_L st_R
    else
        compare st_L st_R;;
 
val numRemRegex : System.Text.RegularExpressions.Regex =
  (?<topNum>(^([\d]+)))(?<topNumRem>(.*))
val strRemRegex : System.Text.RegularExpressions.Regex =
  (?<topStr>(^([^\d]+)))(?<topStrRem>(.*))
val compStrIncNum : string -> string -> int
 
実行例
 
> List.sortWith compStrIncNum  ["100.txt"; "1.txt"; "20.txt"; "2.txt"; "10.txt"];;
val it : string list = ["1.txt"; "2.txt"; "10.txt"; "20.txt"; "100.txt"]
 
> List.sortWith compStrIncNum ["x13"; "x1B"; "xAB"; "x12"; "x1A"];;
val it : string list = ["x1A"; "x1B"; "x12"; "x13"; "xAB"]
 
> List.sortWith compStrIncNum ["A10B1";"A10B10";"A10B2";"A1B1";"A1B10";"A1B2";"A2B1";"A2B10";"A2B2"];;
val it : string list =
  ["A1B1"; "A1B2"; "A1B10"; "A2B1"; "A2B2"; "A2B10"; "A10B1"; "A10B2";"A10B10"]
 
> List.sortWith compStrIncNum ["う54う"; "い23い"; "い1い"; "あ9あ"; "う100う"; "あ88あ"];;
val it : string list = ["あ9あ"; "あ88あ"; "い1い"; "い23い"; "う54う"; "う100う"]
 
ただこれだとA006BとA6Bが等しいものとしてソートされるので、なにか規則を付け加えた方がよいかもしれません。
スポンサーサイト



テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード