[Algorithms] – Find words in reviews of hotels

Problem:

Given a set of words and many review of this hotels, you must display the hotels Ids containing in their reviews the words informed.

Inputs:

– Line 1: words
– Line 2: quantity of reviews
– Line 3 .. N: Id Hotel and review;

Rules :

– Special characters should be disregarded;
– If a word appears more than once it should be told all times;
– The result should be respectively ordered by the number of words found and the id of the hotel.

My solution :

```public static class Hotel{
private Integer idHotel;
private Integer score;

public Hotel(Integer idHotel, Integer score){
this.idHotel = idHotel;
this.score = 0;
}

public Integer getScore() {
return score;
}

public Integer getIdHotel() {
return idHotel;
}

@Override
public String toString(){
return this.getIdHotel().toString() + " ";
}

}

public static class Utils{
public static List<String> getArrayOfWordsLine(String words) {
String[] wordsArray = buildWordsArray(words);
return Arrays.asList(wordsArray);
}

private static String[] buildWordsArray(String words) {
words = words.replaceAll("[!,?._'@]", "");
words = words.replaceAll("^ +| +\$|( )+", " ");
words = words.replaceAll("^\\s+", "").replaceAll("\\s+\$", "");
return words.split(" ");
}
}

public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String words = scan.nextLine();
Integer nunReviews = scan.nextInt();
List<Hotel> hotelList = new ArrayList<>();
int counter = 0;
while (counter < nunReviews){
Integer hotelId = scan.nextInt();
scan.next();
String stringReview = scan.nextLine();
List<String> arrayWithWordsReview = Utils.getArrayOfWordsLine(stringReview);
Integer score = calcHotelScore(words,arrayWithWordsReview);
counter ++;
}
}

private static Integer calcHotelScore(String reviews, List<String> wordsArray) {
return wordsArray.stream().filter(s -> reviews.contains(s)).collect(
Collectors.groupingBy(Object::toString,
Collectors.collectingAndThen(
Collectors.mapping(Object::toString, Collectors.toSet()),
Set::size))).values().stream().mapToInt(i -> i.intValue()).sum();

}

private static List<Hotel> takeOrderDescHotelsByQuantityReview(List<Hotel> hotelList) {
List<Hotel> finalList = new ArrayList<>();
hotelList.stream()
.collect(Collectors.groupingBy(h -> h.getIdHotel(),
orderResultsByScoreAndHotelId(finalList);
return finalList;
}

private static void orderResultsByScoreAndHotelId(List<Hotel> finalListHotels) {
Collections.sort(finalListHotels, new Comparator<Hotel>() {
@Override
public int compare(Hotel o1, Hotel o2) {
Integer compare = o2.getScore().compareTo(o1.getScore());
if ( compare == 0){
return o1.getIdHotel().compareTo(o2.getIdHotel());
}
return compare;
}
});
}```