# Ruby 发起一个算法讨论， 有关两个字符串之间逐字符混插

zw963 · 2012年03月16日 · 最后由 jhjguxin 回复于 2012年03月23日 · 5352 次阅读

## 发起一个算法讨论

``````aS HvOeRrTy  SlToRnIgN GlSoHnOgR Ts tSrTiRnIgN

``````

``````a_long_string = "a very long long string"
short_string = "SHORT STRING"

def insert_str(str1, str2)
tmp_str = ""
enum1 = str1.chars
index = 0
loop do
z = enum1.next << str2[index]
index = (index + 1) % str2.length
tmp_str << z
end
tmp_str
end

insert_str a_long_string, short_string

``````

``````
def insert_str long, short
short_len = short.length
string_array = long.chars.enum_for(:inject, []).with_index do |(r, char), i|
r << char
r << short[i % short_len]
end
string_array.join
end

``````

``````def insert_str l,s; l.split("").zip((s * (l.size / s.size) << s[0...(l.size % s.size)]).split("")).join;end

``````
``````def merge_string(long, short)
result = []
long_size = long.size
i = 0
short.each_char do |char|
result << long[i]
result << char
i += 1
end
result.join('') << long[i..long_size]
end

``````

``````def insert_str long, short
short_arr = short.split("")
result = ""
long.split("").each{|str| result << str + short_arr.first and short_arr.rotate!}
return result
end

``````
``````a_long_string = "a very long long string"
short_string = "SHORT STRING"

def insert_str(str1, str2)
ls, ss = [str1, str2].map(&:chars)
ls.zip(ss.cycle).join
end

``````
``````def insert_str(long, short)
div, mod = long.size.divmod(short.size)
c = short * div + short[0..(mod - 1)]
long.chars.zip(c.chars).join
end

``````

#2 楼 @pongyo , 谢谢. 脑子卡壳了. 平常总是用数组, 换作字符串了, 没反应过来. 哈哈.

#3 楼 @daqing 你的代码不满足我的要求.

``````"aS HvOeRrTy  SlToRnIgN Glong string"

``````

#4 楼 @huyong36 Cool~~

#5 楼 @hysios 太酷了~~ 我倒是想到了用 cycle, 但是没想到可以这样用 each_with_object

#6 楼 @hooopo , 无语了. 竟然用这种办法.....

``````def insert_str(s1,s2)
s1.chars.zip((s2*(s1.length/s2.length+1)).chars).join
end

``````

``````def insert_str2(s1,s2)
s1.chars.inject('') {|ss,s| ss << s + s2[(ss.length/2)%s2.length]}
end

``````

@hysios 的代码很棒阿，使用 api 特别恰当，学习一下

``````def insert(long,short)
enum_l = long.each_char
enum_s = short.each_char.cycle
temp = ""
loop do
temp << enum_l.next << enum_s.next
end
long.replace(temp)
end

``````

#5 楼 @hysios 五楼修改后的代码, 堪称把 Ruby 简约而不失魔幻的风格堪称发挥到了极致. 代码量很少, 而且看起来相当直观. 绝对是自文档代码的典范.

@hysios 相当漂亮！

#5 楼 @hysios cycle 不错。

#15 楼 @zw963 zip + cycle 才是经典

``````def insert_str(str1, str2)
str1.chars.zip(str2.chars.cycle).join
end

``````

@hooopo 实际上我之前看错了需求 原始语句是这样的

``````def insert_str(str1, str2)
short, long = [str1, str2].sort.map(&:chars)
...
end

``````

zip + cycle 才是经典

#24 楼 @zw963 忍不住再回复一下，看来象 string 和 list 这样的基础 api 还要深挖，这个例子绝对适合拿出来 show 一下 ruby style

zip + cycle 真是经典，过瘾看着。

def insert_str(str1, str2) i = -1 str1.split(//).join("\0").gsub("\0") do i = (i + 1) % str2.length str2[i] end end

``````def insert_str(str1, str2)
i = -1
str1.split(//).join("\0").gsub("\0") do
p \$&
i = (i + 1) % str2.length
str2[i]
end
end

``````
``````
def insert_cycle_char long, short
long.split('').zip(short.split('').cycle).flatten.join
end

insert_cycle_char "a very long long string" , "SHORT STRING"

``````

#28 楼 @geekontheway 这个比 @hysios 的差一些：chars 比 split 的语义更清晰，而且很可能性能更好，flatten 在 join 之前用是多余的

#29 楼 @fsword 果然如此，受教了

``````def insert_str2(str1,str2)
result = ''
str1.length.times {|n|result << str1[n] << str2[n % str2.length] }
result
end

``````

#32 楼 @hegwin 虽然实现细节和我差不多, 不过你这个想法, 太奇妙了

``````def insert_str(long, short, index = 0)
long[index] ? long[index] << short[index % short.length] << insert_str(long, short, index + 1)
: ""
end

``````

fiber 版的:

``````def insert_str(long, short)
require 'fiber'

longer = Fiber.new do |shorter, result|
long.each_char do |char|
result << char
shorter.transfer(longer, result)
end
result
end

shorter = Fiber.new do |longer, result|
short.each_char.cycle do |char|
result << char
longer.transfer(shorter, result)
end
end

longer.transfer(shorter, "")
end

``````

``````a_long_string = "a very long long string"
short_string = "SHORT STRING"

result=""
i = 0

a_long_string.each_char do |a|
i=0 if i == short_string.length
result << a << short_string[i]
i += 1
end
result

``````