#はじめに
この記事は、プログラミング初心者が書いています。
間違っていること、もっとこうした方がいいよ!!等ございましたら、
コメントお願いします。
また、この問題はpaizaの練習問題になります。
ランクの上下には全く関係のないものですので、ご安心ください。
#非オブジェクト指向で書いたやつ
Javaで解いてみた!! Paiza練習問題「長テーブルのうなぎ屋」
こちらは手続き型(あってる?)で解いています。
この記事を投稿した際に、オブジェクト指向で書いたコードがあったため、
自分なりに消化させていただきました。
問題の具体的な内容などもこちらでご確認ください。
#オブジェクト指向で考える
非オブジェクト指向で書いたコード
import java.util.*;
public class unagiya {
public static void main(String[] args) {
/*
* 店の総席数、来店するグループ数をString型で取得しlineに格納
* lineに格納したデータをsplitで分けてString配列のlineArrayに格納
*/
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine();
String[] lineArray = line.split(" ");
/*
* lineArrayに格納したデータをキャストして各変数に格納
*
* seatNum:座席の数
* totalGuest:来店するグループの数
*/
int seatNum = castString(lineArray[0]);
int totalGuest = castString(lineArray[1]);
/*
* seats:座席数をhashMapで作成
* Integerが席番号
* Booleanが人の有無(trueなら座れる,)
*/
Map<Integer,Boolean> seats = new HashMap<>();
for(int i = 1; i <= seatNum; i++){
seats.put(i,true);
}
/*
*isSitCustomer:客が選んだ席に人がいるかいないか確認
*いなければtrueを投げる
*
* choiceSeat:来た客が選ぶ基点となる席番号
*menberNum:来た客の数
*/
int choiceSeat = 0;
int memberNum = 0;
for(int i = 0; i < totalGuest; i++){
//コンソールの入力値を受け取り、
//memberNumとchoiceSeatに代入
line = scanner.nextLine();
lineArray = line.split(" ");
memberNum = castString(lineArray[0]);
choiceSeat = castString(lineArray[1]);
//isSitGuestがtrueなら、客の選んだ席、人数の座席情報をfalseに書き換える
if(isSitGuest(seats,choiceSeat,memberNum)){
for(int j = 0,index = 1 ; j < memberNum; j++){
if(seats.size() < choiceSeat + j){
seats.put(index, false);
index++;
} else {
seats.put(choiceSeat + j,false);
}
}
}
}
//座席情報のfalseの数を調べてリザルトに代入
int result = 0;
for(int i = 1; i <= seats.size(); i++){
if(seats.get(i).equals(false)){
result++;
}
}
System.out.println(result);
}
//String型の数値をint型にキャスト
public static int castString(String strNum){
int num = Integer.parseInt(strNum);
return num;
}
/*
* Map座席の情報、客が選んだ席、客の人数を受け取り、
* 客が選んだ席から、客の人数分、falseがあるかチェック
*
* 条件
* 客の人数が席より多ければfalseを返す
* 座席情報に一つでもfalseがあればfalseを返す
*/
public static boolean isSitGuest(Map seats, int choiceSeat, int menberNum){
if(menberNum > seats.size()){
return false;
}
boolean flag = true;
for(int i = 0,index = 1; i < menberNum; i++){
//index:座席情報の一番最初の1を指定
//客の数が座席番号を超えたら1から数える時に使用
if(seats.size() < choiceSeat + i){
if(seats.get(index).equals(false)){
flag = false;
index++;
} else {
index++;
}
} else if(seats.get(choiceSeat + i).equals(false)){
flag = false;
}
}
if(flag){
return true;
} else {
return false;
}
}
}
#だ、誰が書いたんだこのコード・・・
2週間ほど経って読み返してみたのですが、まあ見難い。
Mapで座席を作って色々やってますね・・・。
(途中で読むのをやめた)
この時の自分は「まあまあいいコード書けたぜw」なんて調子乗ってました。
しかし、流星のように現れたshiracamusさんの一言
「せっかくなのでオブジェクト指向しましょ」
その言葉と一緒に残していったコードがこちら
(shiracamusさんからコード掲載の許可をいただいております)
#@shiracamusさんのコード
import java.util.*;
enum Seat { AVAILABLE, TAKEN };
class LongTable {
private Seat seat[];
LongTable(int seatNum) {
seat = new Seat[seatNum];
for (int i = 0; i < seatNum; i++) {
seat[i] = Seat.AVAILABLE;
}
}
boolean sit(int position, int num) {
for (int i = position; i < position + num; i++) {
if (seat[i % seat.length] != Seat.AVAILABLE) {
return false;
}
}
for (int i = position; i < position + num; i++) {
seat[i % seat.length] = Seat.TAKEN;
}
return true;
}
}
public class Unagiya {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[] input = scanner.nextLine().split(" ");
int seatNum = Integer.parseInt(input[0]);
int groupNum = Integer.parseInt(input[1]);
LongTable table = new LongTable(seatNum);
int sitCount = 0;
for (int i = 0; i < groupNum; i++){
input = scanner.nextLine().split(" ");
int memberNum = Integer.parseInt(input[0]);
int seatNumber = Integer.parseInt(input[1]);
if (table.sit(seatNumber, memberNum)) {
sitCount += memberNum;
}
}
System.out.println(sitCount);
}
}
#オブジェクト指向ってなんだっけ???
このコードを見た瞬間、体に電撃が流れました。
おそらく僕のコードをベースに書き直したのでしょう。
ならば僕はもっと時間を掛けて、
僕なりの「オブジェクト指向」で書いてみようと思います。
#うなぎ屋の登場オブジェクト
僕はまず登場人物から考え始めます。
まずは
・長テーブル
enum Seat {AVAILABLE,UNAVAILABLE}
TAKENから
対象的なUNAVAILABLEに変更しました。
そしてテーブル。
テーブルはテーブルなので、メソッド(動作)はありません。そこにただ存在するだけです。
class LongTable {
Seat[] seats;
/**
* テーブルを作成するコンストラクタ
* 初期値はAVAILABLE
* @param tableNum
*/
LongTable(Integer tableNum) {
this.seats = new Seat[tableNum];
for (int i = 0; i < tableNum; i++) {
seats[i] = Seat.AVAILABLE;
}
}
}
次に江戸っ子のお客さん。今回は少し気が早いとのことです。
席に人がいなかったら(isSit)座る(sitting)
席に人がいたら(isSit)帰る
class Guest {
/**
* 客が選んだ席に人がいなかったらtrueを投げるメソッド
* @param guestNum
* @param choiceNum
* @param table
* @return
*/
public static Boolean isSit(Integer guestNum, Integer choiceNum, LongTable table) {
Boolean seatConfirmation = true;
for (int i = choiceNum; i < choiceNum + guestNum; i++) {
if (table.seats[i % table.seats.length] == Seat.UNAVAILABLE) {
seatConfirmation = false;
}
}
return seatConfirmation;
}
/**
* 客が座り、その席をUNAVAILABLEにするメソッド
* @param guestNum
* @param choiceNum
* @param table
*/
public static void sitting(Integer guestNum, Integer choiceNum, LongTable table) {
for (int i = choiceNum; i < choiceNum + guestNum; i++) {
table.seats[i % table.seats.length] = Seat.UNAVAILABLE;
}
}
}
では、席に座っている人の数を数えるのは・・・
多分お店のスタッフさんになりますね。
class Staff {
/**
* 座っている人の数を数えるメソッド
* @param table
* @return count(SeatのUNAVAILABLEの数を数える)
*/
public static Integer sitCount(LongTable table) {
Integer count = 0;
for (int i = 0; i < table.seats.length; i++) {
if (table.seats[i] == Seat.UNAVAILABLE) {
count++;
}
}
return count;
}
}
これで登場人物は揃いました。
あとはストーリーが進んでいくのを見守るだけです。
#Mainメソッドの記述
ストーリーはmainメソッドに記述していきます。
public class Unagiya {
public static void main(String[] args) throws Exception{
//input:コンソールからの入力値を1行取得
//inpuArray:1行の数値を分けて配列に格納
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] inputArray = input.split(" ");
//tableNum:うなぎ屋の座席の数
//toDayGuest:本日ゲストが全部で何グループ来るか
Integer tableNum = toCastString(inputArray[0]);
Integer toDayGuest = toCastString(inputArray[1]);
LongTable table = new LongTable(tableNum);
//guestNum:1グループの人数
//choiceNum:ゲストが選んだ席
Integer guestNum = 0;
Integer choiceNum = 0;
for (int i = 0; i < toDayGuest; i++) {
input = scanner.nextLine();
inputArray = input.split(" ");
guestNum = toCastString(inputArray[0]);
choiceNum = toCastString(inputArray[1]);
if (Guest.isSit(guestNum, choiceNum, table)) {
Guest.sitting(guestNum, choiceNum, table);
}
}
Integer count = Staff.sitCount(table);
System.out.println(count);
}
/**
* String型のアラビア数字をInteger型に変換するメソッド
* @param strNum
* @return num
*/
public static Integer toCastString(String strNum) {
Integer num = Integer.parseInt(strNum);
return num;
}
}
問題なく通りました。
#参考
https://www.slideshare.net/masuda220/ss-14263541
こちらのスライドは非常に参考になるのですが、
縛りが非常に厳しいため、少し緩めにやっていますww
#意見、感想、改善点、僕の悪口、募集中です
僭越ながら2回目の記事投稿になりました。
Qiitaの暗黙の了解などおそらくガン無視して書いてます。
上記の件含め、読んでくださった方は、何か記録を残していただけるとありがたいです。
最後まで読んでくれた方、ありがとうございました。