あけましておめでとうございます。2023もジョイタスネットをよろしくお願いします。さて、新年一発目、まずは軽くプログラミング問題を解いていきましょう。PaizaでいうとCランク位の難易度です。
お題
2023という数字には23という並びの数字が含まれている。
この並びの数字として扱うのは今回以下の10種類とする。
01
12
23
34
45
56
67
78
89
90
コマンドラインから任意の桁数の数字が入力されるのでそれに上記10個の数字が1つでも含まれていればOKそうでなければNGと出力される処理を作成せよ。
実行例
2023 [enter key]
OK
123456 [enter key]
OK
20046 [enter key]
NG
902 [enter key]
OK
01 [enter key]
OK
Let’s challenge!
さあ、日頃の成果の見せ所。しっかりと処理を作成してみてもらいたい。
解答例
それでは解答していこう。
配列を使う
入力された文字を一文字ずつ分解して配列として考える方法だ。
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
//入力された文字列を受け取る
String numStr=sc.next();
//その文字数でint配列を作成
int[] numArr=new int[numStr.length()];
for(int i=0;i<numStr.length();i++) {
//文字を一文字ずつとりだしながらintに変換して配列に入れる
numArr[i]=Character.getNumericValue(numStr.charAt(i));
}
for(int i=0;i<numArr.length-1;i++) {
//一つ前の数字に1を足して10で割った余りが次の数と等しくなったらOK
if((numArr[i]+1)%10 == numArr[i+1]) {
System.out.println("OK");
return;
}
}
System.out.println("NG");
}
ポイント
配列を使って解くとこんな感じになる。90といった他の9つとは違った感じの数字も余りの%演算子を使うと解決できる。
正規表現を使う
そもそもこの入力された数字を数値と考えずに文字列として考えてしまうという方法も有力だ。この場合正規表現を使うとよいだろう。正規表現はどうしても学習順位が下がってしまうが(エンジニアを目指すとなったら学習しなければならないことが山程あるので致し方ないところもある)かなり強力なので一度さらっと学習しておくことをお勧めする。
正規表現1
まずは
文字列.matches(パターン)
使ってやってみる。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str=sc.next();
//10個の文字列を準備
String[] arr= {"01","12","23","34","45","56","67","78","89","90"};
//.*(01|12|23|...|90).*という正規表現パターンを作成
String reg=String.format(".*(%s).*",String.join("|",arr));
//文字列とマッチするかで判定
if(str.matches(reg)) {
System.out.println("OK");
}else {
System.out.println("NG");
}
}
ポイント
今回判定するのが10個ほどのパターンなのでそれらをすべて列挙するという力技を用いている。10個の配列を用意するば、それをそのままループで回して
文字列.contains()
で判定するという方法も考えられるがここでは正規表現を使った。
文字列.matches(パターン)
は判定したい文字列全体が、正規表現と一致するかをtrue or falseで判定するものなので今回の場合は
.*(01|12|……|90).*
と前後に.*が必要になるのがポイントだ。
正規表現2
先程はStringクラスのメソッドmatchesを用いたがより高度な正規表現を扱えるMatcherオブジェクトを使う方法が以下
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str=sc.next();
String[] arr= {"01","12","23","34","45","56","67","78","89","90"};
//正規表現パターンオブジェクト作成
Pattern p=Pattern.compile(String.join("|", arr));
//パターンのmacherメソッドによってMatcherオブジェクト生成
Matcher m = p.matcher(str);
//findでパターンとマッチする部分があるかを判定
if(m.find()) {
System.out.println("OK");
//System.out.println(m.group());
}else {
System.out.println("NG");
}
}
Matcherオブジェクトの作り方が複雑だが、その分できることが多くfindではマッチする部分があるかを判定できる。またコードではコメントアウトしてあるgroupを使うと実際にマッチした部分文字列を取得することができる。(2023の場合23)
終わりに
今回は簡単なお題をもとにJavaでの正規表現を紹介した。
「学習することが多すぎて正規表現までは手が回らない」
初学者の多くはそういう状態だと思うが、正規表現は使いこなせると本当に強力だ。2023年は正規表現を勉強してみるというのはいかがだろうか?
コメント