こんにちは!じゃいごテックのあつしです。
paizaスキルアップ問題集でよく出題されている文字列の操作を調べてみました。
その中でも基本操作である文字列の連結や繰り返し、インデックスでの指定や置き換えについてご紹介します。
文字列の連結と繰り返し
文字列の連結1
+
演算子を使うと、文字列を足し算のように扱うことが出来ます。
family_name = "Yamada" first_name = "Taro" full_name = family_name + first_name p full_name # > "YamadaTaro" p family_name # > "Yamada" p first_name # > "Taro"
文字列の連結2
<<
演算子を使うと、元の文字列に連結することが出来ます。元の文字列が書き換えられてしまいますが、+
演算子より高速です。
family_name = "Yamada" first_name = "Taro" family_name << first_name p family_name # > "YamadaTaro"
文字列の繰り返し
*
演算子を使うと、文字列を繰り返すことが出来ます。
name = "sakura" p name * 2 # > "sakurasakura"
文字列の連結と繰り返しを組み合わせて使う
p "す" << "も" * 8 << "のうち" # > "すもももももももものうち"
() カッコで計算の優先順位を変更
p "な" << "つ" * 4 << "コ" * 2 << "ナッツ" # > "なつつつつココナッツ" p ("な" << "つ") * 4 << "コ" * 2 << "ナッツ" # > "なつなつなつなつココナッツ"
文字列の連結を使ってpaiza練習問題を解いてみる
文字列の連結 (paizaランク D 相当)
※ paiza レベルアップ問題集 文字列処理メニューより
問題:
与えられる文字列の数 N と、 N 個の文字列が与えられるので、それらを順に末尾に連結した文字列を出力してください。
例として、"abc", "def", "ghi" という順で文字列が与えられたとき、連結後の文字列は"abcdefghi" となります。
入力される値
N
S_1
...
S_N
- 1 行目で与えられる文字列の数 N が与えられます。
- 続く N 行で連結する文字列 S_i (1 ≦ i ≦ N) が与えられます。
期待する出力
N 個の文字列を順に後ろに連結した文字列を 1 行で出力してください。
条件
- 1 ≦ N ≦ 100
- 1 ≦ |S_i| ≦ 10000 ( |S_i| は、 S_i の文字数です。1 ≦ i ≦ N)
入力例1
2
pa
iza
出力例1
paiza
入力例2
30
q
w
e
r
t
y
u
i
o
p
l
k
j
h
g
f
d
s
a
z
x
c
v
b
n
m
l
o
l
w
出力例2
qwertyuioplkjhgfdsazxcvbnmlolw
入力例3
9
mo
ji
re
tu
no
re
n
ke
tu
出力例3
mojiretunorenketu
入力例4
13
p
ro
g
ra
m
ming
i
s
soooooooooooooooo
difficult
oh
my
god
出力例4
programmingissoooooooooooooooodifficultohmygod
解答例:
# [解答例1] getsを使った方法 # 最初にinput_strを空文字で初期化 input_str = "" gets.to_i.times do # input_str の末尾に gets で入力された文字を追加していく input_str << gets.chomp end puts input_str # [解答例2] STDIN.readを使った方法 # 改行で分割して1つ目の要素は破棄して、2つ目以降の要素を input_arr に代入する。 _, *input_arr = STDIN.read.split("\n") # 配列の要素を連結して表示 puts input_arr.join
文字列の参照と書き換え
文字列の参照
文字列には前と後からのインデックス(添え字)が振られており、インデックスを指定すると、対応する文字を取得することが出来ます。
前からのインデックスは[0]からのスタート、後ろからのインデックスは[-1]からのスタートとなっており、 ..
を使用すると範囲を表すことが出来ます。
文字列 | Y | a | m | a | d | a | T | a | r | o |
前からのインデックス | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
後からのインデックス | -10 | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 |
name = "YamadaTaro" # 3番目の文字を参照する p name[2] # > "m" # 3番目から6番目までの文字を参照する p name[2..5] # > "mada" # 3番目から4文字を参照する p name[2, 4] # > "mada" # 最初から6番目までの文字を参照する p name[..5] # > "Yamada" # 7番目から最後までの文字を参照する p name[6..] # > "Taro"
文字列の参照を使ってpaiza練習問題を解いてみる
部分文字列 (paizaランク D 相当)
※ paiza レベルアップ問題集 文字列処理メニューより
問題:
文字列 S と整数 i , j が与えられるので、 S の i 文字目から j 文字目までの部分文字列を出力してください。
入力される値
S
i j
期待する出力
S の i 文字目から j 文字目までの部分文字列を 1 行で出力してください。
S_i ... S_j
条件
- 1 ≦ |S| ≦ 10000 ( |S| は、 S の文字数です。)
- 1 ≦ i ≦ j ≦ |S|
入力例1
paiza
1 3
出力例1
pai
入力例2
PAIZA
2 4
出力例2
AIZ
入力例3
ABCDEFGHIJKLMNO!QRSTUVW&XYZ
5 20
出力例3
EFGHIJKLMNO!QRST
入力例4
1234567890
9 9
出力例4
9
解答例:
# [解答例1] getsを使った方法 input_str = gets.chomp i, j = gets.split.map do |str_num| # インデックスは [0] からスタートなので -1 str_num.to_i - 1 end puts input_str[i..j] # [解答例2] STDIN.readを使った方法 input_str, tmp_line = STDIN.read.split("\n") i, j = tmp_line.split.map do |str_num| # インデックスは [0] からスタートなので -1 str_num.to_i - 1 end puts input_str[i..j]
文字の書き換え
インデックスを指定して新たな文字を代入すると文字を上書きすることが出来ます。
name = "YamadaTaro" # 1番目を上書きする name[0] = "H" p name # > "HamadaTaro" # 7番目から8番目を上書きする name[6..7] = "Koji" p name # > "HamadaKojiro" # 与えた文字を含むならその部分を書き換える name["Hamada"] = "Sasaki" p name # > "SasakiKojiro" # 与えた文字列が含まれない場合はエラーがでる name["Yamada"] = "Suzuki" # > IndexError(String not matched) p name["Yamada"] # > nil # "Yamada"という文字は含まれていない p name["Sasaki"] # > "Sasaki" # "Sasaki"という文字が含まれている
文字の書き換えを使ってpaiza練習問題を解いてみる
文字列の書き換え (paizaランク D 相当)
※ paiza レベルアップ問題集 文字列処理メニューより
問題:
文字列 S と整数 i と文字 c が与えられるので、S の i 文字目を c に書き換えたものを出力してください。
入力される値
S
i c
- 1 行目では、文字列 S が与えられます。
- 2 行目では、整数 i と、文字 c が与えられます。
期待する出力
S の i 文字目を c に書き換えたものを 1 行で出力してください。
条件
- 1 ≦ i ≦ |S| ( |S| は、 S の文字数です。)
- 1 ≦ |S| ≦ 100
- c は 1 文字
入力例1
paiza
1 P
出力例1
Paiza
入力例2
PAIZA
5 a
出力例2
PAIZa
入力例3
ABCDEFGHIJKLMNOPQRSTUVW&XYZ
16 !
出力例3
ABCDEFGHIJKLMNO!QRSTUVW&XYZ
入力例4
1234567890
2 +
出力例4
1+34567890
解答例:
# [解答例1] getsを使った方法 input_str = gets.chomp i, c = gets.split # インデックスは [0] からスタートなので -1 i = i.to_i - 1 input_str[i] = c puts input_str # [解答例2] STDIN.readを使った方法 input_str, tmp_line = STDIN.read.split("\n") i, c = tmp_line.split # インデックスは [0] からスタートなので -1 i = i.to_i - 1 input_str[i] = c puts input_str
今回のまとめ
- 文字列のインデックスを指定すると、対応した文字が取り出せる
- 文字列のインデックスを範囲で指定することも出来る
- 文字列のインデックスを指定して新しい文字を代入すると上書きできる
- 前からのインデックスは0から始まり、後ろからのインデックスは-1から始まる
文字列操作メソッドもいくつか覚えれば文字列操作系の問題が楽に解けると思いますので次回以降でご紹介致します。