LoginSignup
0
4

More than 3 years have passed since last update.

未経験転職中に出題されたコーディングテスト

Posted at

転職活動中(未経験)にコーディングテストがあり、解答した答えを備忘録として残しました
実力不足で色々試行錯誤して出した答えのため、修正・解説いただけると嬉しいです
この他にも何問かあったので、追って記事にする予定です

問題1.回文部分の文字列を出力

PalindromString(str)でstrには文字列が入ります。
この文字列内で部分的に最長となる回文文字列を取得するメソッドを作るという問題です。
例 str="abracecars"の場合、racecarを返す必要があります。
strの入力は小文字英字のみで、3文字以上の回文文字列がない場合はnoneを返すようにしてください。

自分の回答

1.変数wordに文字列内で連続した文字のすべての組み合わせを取り出す
2.reverseメソッドを用いてword == word.reverseを満たしかつ3文字以上のwordを配列に代入する
3.配列内で最長となるwordを出力する
といった処理を記述したつもりです
以下が全体のコードです

def PalindromString(str)

  # code goes here
  num = 1
  str_size = str.length
  array = []
  # 調べるwordの全組み合わせについて回文になっているか確認する
  while num <= (str_size - 1)
    while 2 <= (str_size - 1)
      word = str.slice(num..str_size - 1)
      str_size = str_size - 1
      # 回文になっている、かつ文字数が2文字以上のものをarrayに代入
      if (word == word.reverse) && (word.length > 2) 
        array << word
      end
    end
    str_size = str.length
    num = num + 1
  end
  # arrayにwordが入っている時に最初に回文になっている最大文字数のものを表示する
  unless array.empty?
    puts array.max_by{|w| w.size}
  else
    puts "none"
  end
end

1.変数wordに文字列内で連続した文字のすべての組み合わせを取り出す

連続した文字のすべての組み合わせを取り出すというのは
例えばstr = "abcdefg"の場合には下記の組み合わせになります
ab, abc, abcd,..,abcdefg
b,bc,bcd,..,bcdefg
c,cd,cde,.,cdefg
d,..,defg
e,ef,efg
f,fg
これらを全部取り出し、それぞれにreverseメソッドを使って回文になるものを探そうとしました
すべての組み合わせを取り出す処理は以下です

def PalindromString(str)
  num = 0
  str_size = str.length
  while num <= (str_size - 1)
    while 2 <= (str_size -1)
      word = str.slice(num..str_size - 1)
      str_size = str_size - 1
    end
    num = num + 1
  end
end

変数について
変数numは文字列を開始する場所の指定に使っています
sliceメソッドで文字列を切り取るときには0からカウントがスタートするため、num = 0から始めています
str_sizeは入力する文字列strの文字数です
wordは入力された文字列から任意の範囲で切り取った単語です

①開始位置の記述

while num <= (str_size - 1)
  num = num + 1
end

while~end内で最初の処理が行われるたびにnumの値が1ずつ増えるので、開始位置がずれていくといった記述です

②終了位置の記述

while 2 <= (str_size - 1)
  word = str.slice(num..str_size - 1)
  str_size = str_size - 1
end

ここではwhile~end内の処理が行われるたびに終了位置が左にずれていくといった記述です

処理の流れ

①で開始位置を決めます
②で開始位置が固定された状態で終了位置が変わりながらすべての組み合わせを取り出します
②の処理が終わると①で開始位置が変わり、固定されます
②の処理で開始位置が固定された状態で終了位置が変わりながらすべての組み合わせを取り出します
str = "abcdefg"の場合
abcdefg,abcdef,abcde,abcd,abc,ab,a
bcdefg,bcdef,bcde,bcd,bc
cdefg,cdef,cde,cd
...
といったように繰り返し、すべての組み合わせを取得します

2.reverseメソッドを用いてword == word.reverseを満たしかつ3文字以上のwordを配列に代入する

while 2 <= (str_size - 1)
  word = str.slice(num..str_size - 1)
  str_size = str_size - 1
  if (word == word.reverse) && (word.length > 2) 
    array << word
  end
end

1で取り出したwordに条件式でword.reverseと一致するものかつwordの長さが2以上のものがあればarrayに代入するという記述です

3.配列内で最長となるwordを出力する

表示は2パターンあります
回文になっているwordが存在し、最長のものを表示するパターン
回文になっているwordが存在せず、noneと表示するパターン
これらを条件式を使って表示させるようにしました

  unless array.empty?
    puts array.max_by{|w| w.size}
  else
    puts "none"
  end

条件式unlessでarrayが空でない場合には文字数が最大のものを出力し、空の場合は"none"が出力されます
max_byメソッドでは条件式を付け加え、その条件で最大となるものを取得することができます
ここではw.sizeで要素の文字数で最大になるものということになります

気づき

簡単なケースではうまく動作しても、複雑化するとうまく動いていない場合が多くありそうだと感じた
動作確認のために問題と一緒に与えられた文字列ではうまく動作したが、うまくいかなそうなケースを自分で考えて処理を行ってみたいと思った
→例えば、最大のものが複数あった場合にはmax_byメソッドで最初に見つけたものしか出力されなかった
(問題には複数表示できるようにといったことは書いてなかったので、このまま提出した)
このうまくいかなそうなケースを想定するにはどうしたら・・・?

0
4
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
4