こんにちは。谷口です。
paizaでは、プログラミングスキルチェック問題を公開しています。問題はS・A・B・C・Dと5つのランクにわかれているので、初心者の方でもDランクから無理なくチャレンジできます。
また、paizaラーニングではプログラミング初心者の方向けに「スキルチェック入門編」を全編無料で公開しています。
スキルチェック入門編では、スキルチェックのレベルアップ問題集を題材に、単純な解き方だけでなく、さらにコードを見やすく・シンプルな処理に改善する方法や考え方などもあわせて解説しています。「プログラミングの勉強がしたい」「問題を解けるようになりたい」という方の役に立つ内容になっています。
先日「スキルチェック入門編4:検索履歴(Cランク)」が追加されましたので、今回はその内容をご紹介します。
※スキルチェック入門編4:検索履歴(Cランク)ではJavaで問題を解いていますが、解き方やアルゴリズムに関してはどの言語でも通じます。
スキルチェック入門編4:検索履歴(Cランク)の問題内容
あなたが利用しているブラウザでは、検索ワードの履歴を見ることができません。あなたは検索ワードの履歴を見られないのは不便だと思ったので、検索ワードの履歴を見る機能を自分でつくることにしました。
検索ワードの履歴とは次のようにつくられます。
検索ワード W が以前に入力されたことがある場合:履歴中の W を削除する。履歴の先頭に W を追加する。
検索ワード W が以前に入力されたことがない場合:履歴の先頭に W を追加する。
検索ワード W が N 個与えられるので、N 個の検索ワードが与えられた後の履歴を表示するプログラムを書いてください。
入力される値:入力は以下のフォーマットで与えられます。
N
W_1
W_2
...
W_N1行目には検索ワードの数を表す整数 N が与えられます。
続く N 行では検索ワード W_i が与えられます。
続く N 行のうちの i 行目 (1 ≦ i ≦ N) には、検索ワード W_i が与えられます。検索ワード W_i は小文字のアルファベット a ~ z のみからなる文字列です。
入力は合計 N + 1行であり、 最終行の末尾に改行が 1 つ入ります。入力値最終行の末尾に改行が1つ入ります。
文字列は標準入力から渡されます。
期待する出力:検索ワードを N 個入力した後の検索履歴を出力してください。出力の最後に改行を入れ、余計な文字、空行を含んではいけません。
条件:すべてのテストケースにおいて、以下の条件をみたします。
1 ≦ N ≦ 100
各 W_i (1 ≦ i ≦ N) に対して、W_iの文字数が20を超えない。
入出力例の解説
入力例1では book、candy、apple、book、candy と入力されます。
まずは、順番に検索ワードを受け取っていきます。 book、candy、apple…と、初めて入力されたワードは履歴の先頭に追加します。
次に二度目の book が入力されます。 book は以前に入力されたことがあるので、 履歴中のこのワードを削除し、履歴の先頭に追加します。
こんな感じで、すべての検索ワードが入力されると、 履歴は candy、book、apple となり、これを出力するのが正解となります。
入力例2では apple、book、information、note、pen、pineapple と入力されます。入力例1と同じように検索履歴を出してみましょう。
順番に検索ワードを受け取っていき、 同じワードは検索されていないので、 削除や追加の操作をせずに、そのまま出力するのが正解となります。
実際にコードを書く
まず、入力値を取得する処理を書きます。1行目に 変数 N が入力されます。 N は2行目以降にある検索ワードの数となっています。N の値は、こんな感じで受け取ります。
// N を取得 import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); //検索ワード数を受け取る int N = sc.nextInt(); } }
2行目以降は N 個の検索ワードとなっています。 2行目の値はこんな感じで受け取ります。
// 検索ワード を取得 import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); //検索ワード数を受け取る int N = sc.nextInt(); //次に受け取る検索ワードがある間 while (sc.hasNext()) { //検索ワードを受け取る String W = sc.next(); } } }
hasNext メソッドは受け取れる入力があるかどうかを判定します。 これを while の条件式に入れ、受け取れる入力がある間、next メソッドで入力を受け取ります。
続いて、実際におこなう処理を書きます。 問題文の入力例1を処理するように、コードを書きます。はじめに、ループの外で履歴を格納するための ArrayList をつくり、 ループの中で ArrayList に受け取ったワードを格納します。
// 検索ワードを格納するアレイリストを作成し、格納する import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); //検索ワード数を受け取る int N = sc.nextInt(); //履歴用のArrayListを作成 ArrayList<String> words = new ArrayList<String>(); //次に受け取る検索ワードがある間 while (sc.hasNext()) { //検索ワードを受け取る String W = sc.next(); //検索ワードを履歴リストに追加 words.add(0,W); } } }
次に contains メソッドを使って検索ワードがすでに検索されているかどうかを確認して、その結果によって分岐をさせます。
contains メソッドは、指定したワードが ArrayList に含まれていた場合は true を、 含まれていなかった場合は false を返します。 そして、すでに検索されていた場合は remove メソッドを使って ArrayList から削除するようにします。
// 履歴に検索ワードがすでにあるかを調べ、あった場合削除する import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); //検索ワード数を受け取る int N = sc.nextInt(); //履歴用のArrayListを作成 ArrayList<String> words = new ArrayList<String>(); //次に受け取る検索ワードがある間 while (sc.hasNext()) { //検索ワードを受け取る String W = sc.next(); //検索ワードがリストに入っているかどうか if (words.contains(W)) { //すでに検索されていたとき、そのワードを履歴リストから削除 words.remove(W); } //検索ワードを履歴リストに追加 words.add(0,W); } } }
最後に、結果を出力するコードを書きます。
//結果を出力 import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); //検索ワード数を受け取る int N = sc.nextInt(); //履歴用のArrayListを作成 ArrayList<String> words = new ArrayList<String>(); //次に受け取る検索ワードがある間 while (sc.hasNext()) { //検索ワードを受け取る String W = sc.next(); //検索ワードがリストに入っているかどうか if (words.contains(W)) { //すでに検索されていたとき、そのワードを履歴リストから削除 words.remove(W); } //検索ワードを履歴リストに追加 words.add(0,W); } //出力 for (String word : words) { System.out.println(word); } } }
まとめ
とりあえずこれで答えは出ますので、ひとまず正解の解答コードができました。
スキルチェック入門編4:検索履歴(Cランク)では、このコードをさらに実行時間の早いものに改良する方法も解説しています。
「まずはJavaの使い方を学びたい!」という方は、paizaラーニングの「Java入門編」から初めてみると、無理なく学べるかと思います。
Java入門編について、詳しくはこちら
Java入門編1:プログラミングを学ぶ
Java入門編2:条件によって処理を変えてみよう
Java入門編3: ループ処理を学ぶ
Java入門編4:配列の基礎
Java入門編5: 2次元配列を理解しよう
Java入門編6: メソッドを理解しよう
Java入門編7: クラスを理解しよう
Java入門編8:さらにクラスを理解しよう
Java入門編9: HashMap(連想配列)の基礎
Java入門編10:例外処理を理解しよう
また、「もっと難しい問題をやってみたい」「まずはヒントなしで問題を解いてみたい」という方は、スキルチェック問題に挑戦してみてください。
現在スキルチェック問題に挑戦して結果画面からツイートをすると、抽選でAmazonギフト券が当たるキャンペーンを実施中です。
問題はどれでもOK、正解できなくてもOKですので、プログラミング初心者の方もぜひ挑戦してみてください。
「paizaラーニング」では、未経験者でもブラウザさえあれば、今すぐプログラミングの基礎が動画で学べるレッスンを多数公開しております。
詳しくはこちら
そしてpaizaでは、Webサービス開発企業などで求められるコーディング力や、テストケースを想定する力などが問われるプログラミングスキルチェック問題も提供しています。
スキルチェックに挑戦した人は、その結果によってS・A・B・C・D・Eの6段階のランクを取得できます。必要なスキルランクを取得すれば、書類選考なしで企業の求人に応募することも可能です。「自分のプログラミングスキルを客観的に知りたい」「スキルを使って転職したい」という方は、ぜひチャレンジしてみてください。
詳しくはこちら