2011-11-30 167 views
8

看起来好像在char -> string -> string类型的标准库中没有功能,它在string的前面(或末尾)插入了char。有一些解决方法,例如通过使用String.makeString.blit。有没有一个优雅的方式来做到这一点?如何在OCaml中将字符追加到字符串中?

+1

使用'缓冲区'可能更适合种植字符串。 –

回答

6

String.makeString.blit是这样做的好方法,但它们似乎是必要的。我个人更喜欢让使用Char.escaped和字符串拼接缀功能:

let (^$) c s = s^Char.escaped c (* append *) 
let ($^) c s = Char.escaped c^s (* prepend *) 
+7

我会说'Char.escaped'是为了生成OCaml代码作为输出或编写人类可读消息的专门用途。对于普通情况,'String.make 1 c'可能就是你想要的。它看起来有点笨拙。电池有'BatString.of_char'。 –

+0

感谢您对“Char.escaped”的澄清。我保持不变,以便其他人知道。 – pad

+1

当@ JeffreyScofield的回答和评论中的所有内容都已明确时,为什么要低估? – pad

16

从@pad的代码是什么,我会用,因为我喜欢把字符串作为不可改变如果可能的话。但我不会使用Char.escaped;它专门用于你想要OCaml字符的词汇表示。因此,这里是你做出的改变,你会得到什么:

let prefix_char s c = String.make 1 c^s 

let suffix_char s c = s^String.make 1 c 
8

我做了不同的方法效率的比较:

  1. 我写了一个简单的测试:

    let append_escaped s c = s^Char.escaped c 
    let append_make s c = s^String.make 1 c 
    let append_sprintf s c = Printf.sprintf "%s%c" s c 
    
    let _ = 
        let s = "some text" in 
        let c = 'a' in 
        for i = 1 to 100000000 do 
        let _ = append_(*escaped|make|sprintf*) s c in() 
        done 
    
  2. 我原生编译(Intel Core 2 Duo)。

  3. 我对每个选项进行了三次测试,用time进行计时,并计算平均值真实已过时间。

下面是结果:

  1. s^String.make 1 c:7.75s(100%

  2. s^Char.escaped c:8.30s(107%

  3. Printf.sprintf "%s%c" s c :68.57s(885%

+2

再次注意:'Char.escaped'与'String.make'不同。根据OCaml的词汇规则,它为角色创造了一个“逃脱”的价值。为了看到这个,尝试用这种方法添加一个换行符(''\ n'')。这也是为什么它慢一点。对于大多数通用目的,你想使用'String.make 1 c'。自然'Printf.sprintf'慢得多,但非常灵活。 –

+0

@JeffreyScofield我只是想补充一点,所以人们不需要自己尝试:'char.escaped'\ n''='“\\ n”'。 –

+0

谢谢,也许我应该自己说这个吧!这些评论限制在很短的时间内。无论如何:'炭。'\ n''给你一个由''''和''''组成的双字符串。 'String.make 1'\ n''给你一个由''\ n''组成的单字符串,这更可能是你想要的。 –