文字列の均等分割
この問題は、除算だけでははく算術演算とか、文字列の長さをstrlenの類いで測るとかをしなくても、多分書けるのではないかと思います。
Posted feedbacks - Ruby
例えば5分割の場合、以下のように配列を作成後、文字が入っている所に入力文字を当てはめていくようにしました。 "ゆはのげゝら四にれたも" "めかなきあす月もばくて" "よなかわかほ十な木らゆ" "りきをびしどよりのがく" "も世なつくにひぬしり" shiroさんと同様のロジックですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | def strDiv(n,s)
r = [[]]
s1 = s.split(//)
while s1!=[]
1.upto(n) {|i|
(r[i-1] ||= []) << s1.shift
}
end
s1 = s.split(//)
r.each {|i|
i.each {|j|
print s1.shift if j
}
puts
}
end
strDiv(5,"ゆめよりもはかなき世のなかをなげきわびつゝあかしくらすほどに四月十よひにもなりぬれば木のしたくらがりもてゆく")
|
最初に,行数分の文字ずつ(例えば,4分割なら4文字ずつ)与えられた文字列を走査し,[14, 14, 13, 13] のような各行の文字数からなる配列を作ります.次に,配列を走査しつ つ,この文字数ずつ文字列をとって配列の中身を置き換え,出力とします.
% ./divid.rb divid 4: ["ゆめよりもはかなき世のなかを", "なげきわびつゝあかしくらすほ", "どに四月十よひにもなりぬれ", "ば木のしたくらがりもてゆく"] divid 5: ["ゆめよりもはかなき世の", "なかをなげきわびつゝあ", "かしくらすほどに四月十", "よひにもなりぬれば木の", "したくらがりもてゆく"] divid 6: ["ゆめよりもはかなき", "世のなかをなげきわ", "びつゝあかしくらす", "ほどに四月十よひに", "もなりぬれば木のし", "たくらがりもてゆく"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | require 'pp'
$KCODE='EUC'
class String
def divid(lines)
out, x, y = [0] * lines, split(''), nil
y.times {|i| out[i] += 1 } while (y = x.slice!(0, lines).size) > 0
rest = self
out.map! do |len|
_, ret, rest = *rest.match(/(.{#{len}})(.*)/)
ret
end
end
end
sample = "ゆめよりもはかなき世のなかをなげきわびつゝあかしくらすほどに四月十よひにもなりぬれば木のしたくらがりもてゆく"
(4..6).to_a.each do |i|
puts "divid #{i}:"
pp sample.divid(i)
puts
end
|
- http://ja.doukaku.org/comment/4258/
- http://ja.doukaku.org/comment/4266/
を参考に ruby1.9 Enumerator とメソッドチェインで書いてみました。
$ ruby1.9 --version ruby 1.9.0 (2007-11-02 patchlevel 0) [i686-linux]
1 2 3 4 5 6 | def divid(n, str)
(1..n).cycle.zip(str = str.split(//u)).sort.inject(["", 1]) {|(r,i),(j,_)|
r << ((i == j) ? "" : "\n") << str.shift
[r, j]
}.first
end
|
器を作って埋めていく方式。
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 | require 'pp'
sample = 'ゆめよりもはかなき世のなかをなげきわびつゝあかしくらすほどに四月十よひにもなりぬれば木のしたくらがりもてゆく'
def divid(num,str)
str_ = str.split(//)
buf, _n = str_.inject([[],0]) do |acc,ch|
tmp, n = acc
tmp[n] ||= []
tmp[n] << ch
[tmp, if (n_ = n + 1) < num then n_ else 0 end]
end
str_.inject([0,0]) do |idx,ch|
n, m = idx
if buf[n][m].nil?
n += 1
m = 0
end
buf[n][m] = ch
[n, m + 1]
end
buf.map {|ary| ary.join}
end
(4..6).each do |n|
pp divid(n, sample)
end
|
他の人のコードを見ずに書いてみました。 見返してみると、kenaxt さんのコード(#4250)とほとんど同じですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | def divid(num, str)
a = Array.new(num){ [] }
chrs = str.split('')
tmp = chrs.clone
until tmp.empty?
a.each_index do |i|
break if tmp.empty?
a[i] << tmp.shift
end
end
a.each do |b|
b.each_index do |i|
b[i] = chrs.shift
end
end
a.map{ |b| b.join('') }.join("\n")
end
sample = "ゆめよりもはかなき世のなかをなげきわびつゝあかしくらすほどに四月十よひにもなりぬれば木のしたくらがりもてゆく"
puts divid(5, sample)
|




nobsun
#4090()
Rating-1/3=-0.33
1 reply [ reply ]