diff --git a/kshiraishi/src/B084.java b/kshiraishi/src/B084.java new file mode 100644 index 0000000000000000000000000000000000000000..96bc2a86d2fc0712239c53f4f58817205b4c321d --- /dev/null +++ b/kshiraishi/src/B084.java @@ -0,0 +1,50 @@ +package B084; + +import java.util.List; +import java.util.Set; + +/** + * @see GourumetData データ保持 + * @see GourumetOperation 処理部分のメソッドをまとめたクラス + * + * @param myRating3 自分が評価3以上をつけた店のインデックスを格納したリスト + * @param otherRating3 自分以外が評価3以上をつけた店のインデックスを格納したリスト + * @param similarUsersReviewList 好みが似てる人の他人の評価3以上のリスト + * @param recommend 自分が行ったことない(評価0)店で好みが似てる人が評価3をつけた店のインデックス + * + */ +public class B084 { + + public static void main(String[] args) { + GourumetData gourumetData = new GourumetData(); + GourumetOperation operation = new GourumetOperation(); + + //自分と他のユーザが評価3以上とした店のインデックスをそれぞれリストに保存 + List myRating3 = operation.myRatingsOf3(gourumetData); + List> otherRating3 = operation.otherRatingsOf3(gourumetData); + + //自分の評価3以上の店と同じ店を評価3以上が基準値以上見つかった場合、 + //好みが似ているユーザとしてそのユーザの評価リストを保存。 + List> similarUsersReviewList = operation.similarUsers(gourumetData, myRating3, otherRating3); + //自分が評価0で好みのユーザが評価3をつけた店を出力 + Set recommend = operation.recommendRestaurant(gourumetData, similarUsersReviewList); + + // recommendセットが空かどうかをチェック + if (recommend.isEmpty()) { + System.out.println("no"); + } else { + int count = 0; + for (int restaurantIndex : recommend) { + System.out.print(restaurantIndex + 1); // まず値を出力 + if (count < recommend.size() - 1) { // 最後の要素でなければ空白を追加 + System.out.print(" "); + } + count++; + } + System.out.println(); // 最後で改行 + } + + + } + +} diff --git a/kshiraishi/src/GourumetData.java b/kshiraishi/src/GourumetData.java new file mode 100644 index 0000000000000000000000000000000000000000..faa9bd014472a4c010d0ca65f2892f263fa6dee6 --- /dev/null +++ b/kshiraishi/src/GourumetData.java @@ -0,0 +1,72 @@ +package B084; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +/** + * データ保持オブジェクト + * + * @param reviewedRestaurantNum レビューした店の数 + * @param otherUserCount 自分以外のユーザ数 + * @param minMatchCriteria 自分と好みが似ていると言える基準の数 + * @param myReviewedList 自分の評価リスト + * @param otherReviewedList 自分以外の評価リスト + * + */ +public class GourumetData { + private final int reviewedRestaurantNum; + private final int otherUserCount; + private final int minMatchCriteria; + private final List myReviewedList = new ArrayList(); + private final List> otherReviewedList = new ArrayList>(); + + + /**コンストラクタ*/ + public GourumetData() { + Scanner sc = new Scanner(System.in); + + this.reviewedRestaurantNum = Integer.parseInt(sc.next()); + this.otherUserCount = Integer.parseInt(sc.next()); + this.minMatchCriteria = Integer.parseInt(sc.next()); + + for(int i=0; i tempList = new ArrayList(); + for(int reviewNum=0; reviewNum getMyReviewedList() { + return myReviewedList; + } + + + public List> getOtherReviewedList() { + return otherReviewedList; + } + + +} diff --git a/kshiraishi/src/GourumetDataTest.java b/kshiraishi/src/GourumetDataTest.java new file mode 100644 index 0000000000000000000000000000000000000000..bed3a42aa874fa1210555ba5a8c086f8c7f57b1c --- /dev/null +++ b/kshiraishi/src/GourumetDataTest.java @@ -0,0 +1,46 @@ +package B084; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Arrays; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class GourumetDataTest { + private InputStream originalSystemIn; + + @Before + public void setUp() { + originalSystemIn = System.in; + } + + @Test + public void コンストラクタGourumetDataのテスト() { + String input = "4 3 2\n3 0 3 0\n3 3 3 1\n1 3 1 3\n3 0 3 3"; + InputStream testInput = new ByteArrayInputStream(input.getBytes()); + + System.setIn(testInput); + + GourumetData gourumeData = new GourumetData(); + + assertThat(gourumeData.getReviewedRestaurantNum(), is(4)); + assertThat(gourumeData.getOtherUserCount(), is(3)); + assertThat(gourumeData.getMinMatchCriteria(), is(2)); + assertThat(gourumeData.getMyReviewedList(), is(Arrays.asList(3, 0, 3, 0))); + assertThat(gourumeData.getOtherReviewedList(), is(Arrays.asList( + Arrays.asList(3, 3, 3, 1), + Arrays.asList(1, 3, 1, 3), + Arrays.asList(3, 0, 3, 3)))); + } + + @After + public void tearDown() { + System.setIn(originalSystemIn); + } + + + +} diff --git a/kshiraishi/src/GourumetOperation.java b/kshiraishi/src/GourumetOperation.java new file mode 100644 index 0000000000000000000000000000000000000000..162603fd0fe3e98a6fd57632db96d1aff98b7871 --- /dev/null +++ b/kshiraishi/src/GourumetOperation.java @@ -0,0 +1,94 @@ +package B084; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; +/** + * 処理部分のメソッドを定義したクラス + * + * + */ +public class GourumetOperation { + + /**自分の評価3以上のインデックス(店)のリストを返す*/ + public List myRatingsOf3(GourumetData gourumetData) { + List myRating3 = new ArrayList<>(); + + for(int i=0; i= 3) { + myRating3.add(i); //評価3以上ならインデックス(店)をリストに追加 + } + } + + return myRating3; + } + + /**他ユーザの評価3以上のインデックス(店)のリストを返す*/ + public List> otherRatingsOf3(GourumetData gourumetData) { + List> otherRating3 = new ArrayList<>(); + + for (int i = 0; i < gourumetData.getOtherReviewedList().size(); i++) { + otherRating3.add(new ArrayList<>()); // 各ユーザーごとの評価3リストを初期化 + } + + for(int i=0; i= 3) { + otherRating3.get(i).add(j); //評価3以上ならインデックス(店)をリストに追加 + } + } + } + + return otherRating3; + } + + /**自分の評価3以上の店と同じ店を評価3以上が基準値以上見つかった場合、 + 好みが似ているユーザとしてそのユーザの評価リストを保存。*/ + public List> similarUsers(GourumetData gourumetData, List myRating3, List> otherRating3){ + + List> similarUsers = new ArrayList<>(); + + Set myRating3Set = new TreeSet<>(myRating3); // 自分の3評価インデックスをSetに変換 + + for(List otherUserRatingList : otherRating3) { + Set otherUserRatingSet = new TreeSet<>(otherUserRatingList); + + // 共通部分の要素数を数える + Set intersection = new TreeSet<>(myRating3Set); // myRating3Setのコピーを作成 + intersection.retainAll(otherUserRatingSet); // intersectionにはmyRating3SetとotherUserRatingSetの共通要素のみが残る + + int matchCount = intersection.size(); // 共通要素の数がマッチカウント + + if(matchCount >= gourumetData.getMinMatchCriteria()) { + similarUsers.add(otherUserRatingList); + } + } + + return similarUsers; + } + + /**自分の行ったことない店(評価0)で好みが似てる他のユーザが評価3をつけた店をListで返す*/ + public Set recommendRestaurant(GourumetData gourumetData, List>similarUsersReviewList){ + Set recommendSet = new TreeSet<>(); + + for(List list : similarUsersReviewList) { + for(int i=0; i= 1; //レビューが1以上あれば行ったことがある店 + } +} + + + diff --git a/kshiraishi/src/GourumetOperationTest.java b/kshiraishi/src/GourumetOperationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..81db2a588a09ac372af651f33752d04d25ba02fe --- /dev/null +++ b/kshiraishi/src/GourumetOperationTest.java @@ -0,0 +1,86 @@ +package B084; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import org.junit.Test; + +public class GourumetOperationTest { + + @Test + public void myRatingsOf3のテスト入力例1の時評価3以上のインデックスを返せる() { + GourumetOperation sut = new GourumetOperation(); + GourumetData stub = mock(GourumetData.class); + List review = Arrays.asList(3,0,3,0); + + when(stub.getMyReviewedList()).thenReturn(review); + + List expected = Arrays.asList(0,2); + + List actual = sut.myRatingsOf3(stub); + assertThat(actual,is(expected)); + } + + @Test + public void otherRatingsOf3のテスト入力例1の時評価3以上のインデックスを返せる() { + GourumetOperation sut = new GourumetOperation(); + GourumetData stub = mock(GourumetData.class); + List> review = Arrays.asList( + Arrays.asList(3,3,3,1), + Arrays.asList(1,3,1,3), + Arrays.asList(3,0,3,3) + ); + + when(stub.getOtherReviewedList()).thenReturn(review); + + List> expected = Arrays.asList( + Arrays.asList(0,1,2), + Arrays.asList(1,3), + Arrays.asList(0,2,3) + ); + + List actual = sut.otherRatingsOf3(stub); + assertThat(actual,is(expected)); + } + + @Test + public void similarUsersで自分と他人の評価3以上が2個以上あった場合その他人のリストを返す () { + GourumetData stub = mock(GourumetData.class); + when(stub.getMinMatchCriteria()).thenReturn(2); + List myRating3List = Arrays.asList(0,2); + List> otherRating3List = Arrays.asList( + Arrays.asList(0,1,2), + Arrays.asList(1,3), + Arrays.asList(0,2,3) + ); + + List> expected = Arrays.asList( + Arrays.asList(0,1,2), + Arrays.asList(0,2,3) + ); + + GourumetOperation sut = new GourumetOperation(); + assertThat(sut.similarUsers(stub, myRating3List, otherRating3List), is(expected)); + } + + @Test + public void 自分が評価0で好みが似てる人が評価3以上のインデックスを取得できる () { + GourumetData stub = mock(GourumetData.class); + when(stub.getMyReviewedList()).thenReturn(Arrays.asList(3,0,3,0)); + List>similarUsersReviewList = Arrays.asList( + Arrays.asList(0,1,2), + Arrays.asList(0,2,3) + ); + Set expected = new LinkedHashSet<>(Arrays.asList(1,3)); + + GourumetOperation sut = new GourumetOperation(); + assertThat(sut.recommendRestaurant(stub, similarUsersReviewList), is(expected)); + + } + +} +