challenge 文字列を指定されたバイト数で分割

与えられた文字列を指定されたバイト数以下に分割する関数
splitBytes を書いてください。エンコーディングは実装側の
自由としますが、日本語対応は必須とします。
また、分割した結果の表現方法は、各言語で都合のよいものを
選択して下さい。(リスト,配列,改行区切りなど)

[使用例]
"あいうえおabcdeかきくけこfghij" -> 30バイト (Shift_JIS)
"あいうえおabcdeかきくけこfghij" -> 40バイト (UTF-8)

★Shift_JISで10バイトで分割
splitBytes("あいうえおabcdeかきくけこfghij", 10, "Shift_JIS")
=> ["あいうえお", "abcdeかき", "くけこfghi", "j"]
    (10バイト, 9バイト, 10バイト, 1バイト)

★UTF-8で10バイトで分割
splitBytes("あいうえおabcdeかきくけこfghij", 10, "UTF-8")
=> ["あいう", "えおabcd", "eかきく", "けこfghi", "j"]
    (9バイト, 10バイト, 10バイト, 1バイト)

---補足-------------------------------------------
当処理は文字列をデータベースの
固定長フィールド(2000バイト)に投入できる最大サイズ
ぎりぎりまでに分割する時の利用を考えています。
--------------------------------------------------

●●●
余力のある方は以下も行ってみて下さい。

(1) 以下データを2000バイトずつに分割し、処理時間を計測する。

日本郵便 - 香川県の郵便番号(CSV形式:10,513Byte)
http://www.post.japanpost.jp/zipcode/dl/kogaki/lzh/37kagawa.lzh

※ひとまず香川県が一番サイズが小さいので選びました。
  自信ありの方はさらに大きいサイズのファイルでもチャレンジして
  みて下さい。(全国一括など)
http://www.post.japanpost.jp/zipcode/dl/kogaki.html

(2) 処理速度向上・コード短縮
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// サンプルコード (Groovy版)
def splitBytes(str, len, encode) {
   result = []
   while (str) {
      int stock = 0;
      for (i in 0..<str.size()){
         if (str[0..i].getBytes(encode).size() <= len) stock = i
         else break
      }
      result << str[0..stock]
      str -= str[0..stock]
   }
   return result
}

println splitBytes("あいうえおabcdeかきくけこfghij", 10, "Shift_JIS")
println splitBytes("あいうえおabcdeかきくけこfghij", 10, "UTF-8")

Posted feedbacks - Scala

 Scalaがまだの様なので。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Fold {
    var    w:Int = 0
    var    e:String = null
    def this(e:String) = { this(); this.e = e }
    def this(w:Int, e:String) = { this(e); this.w = w }
    def fold(s:String):List[String] = s.foldLeft(List(""))((r,c) =>
            (r.head + c) match {
                case l if l.getBytes(e).size > w => c.toString::r
                case l => l::r.tail
            }
        ).reverse
}
object Fold {
    def fold(s:String, w:Int, e:String):List[String] = new Fold(w, e).fold(s)
}

object SplitBytes {
    def foldLines(f:Fold):Unit = readLine match {
            case null =>
            case s => {
                println(f.fold(s).toString)
                foldLines(f)
            }
        }
    def main(args:Array[String]):Unit = args.length match {
            case 2 =>
                try {
                    foldLines(new Fold(args(0).toInt, args(1)))
                } catch {
                    case e:NumberFormatException => println("バイト数の指定が不正です")
                    case e => e.printStackTrace
                }
            case _ => println("usage: SplitBytes BYTES ENCODING")
        }
}

Index

Feed

Other

Link

Pathtraq

loading...