У меня есть задача, которая производит блины, и пользователи могут одновременно их есть. Условие состоит в том, что за 30 секунд можно приготовить всего 12 блинов. Проблема, с которой я столкнулся, заключается в том, что по мере создания блина пользователи едят его, как и ожидалось, но когда он производит последний блин (т. е. 12-й), он завершается, а пользователь не съедает его, в результате чего 1 блин теряется. Мой окончательный результат таков:
Total number of cake produced is 12
Total number of cake eaten is 11
Total number of pancake remained is 1
public class PanCakeTask {
int consumedPancake;
int availablePancake;
int totalPancakeProduced;
List<String> usersList = new ArrayList<>();
void producePancake(HashMap<String,Integer>users){
consumedPancake =0;
availablePancake = 0;
totalPancakeProduced = 0;
if ( totalPancakeProduced <12) {
for (String user: users.keySet()){
consumedPancake +=users.get(user);
}
//only continue with the production of pancakes if the number of pancakes
//produced has not exceeded the quota that was given (i.e 12)
System.out.println("Pancake produced");
//increment the number of pancakes available
availablePancake +=1;
totalPancakeProduced = consumedPancake + availablePancake;
eatPancake(users);
}
}
void eatPancake(HashMap<String,Integer>users){
if (usersList.size()>=1){
System.out.println("The list is "+usersList);
//first pick the user at random
Collections.shuffle(usersList)
int numberEaten = users.get(usersList.get(0));
//get the user that is on index zero after the list has been shuffled
//then check how many pancake that the picked user has eaten
//because each user is expected to eat a maximum of 5 pancake
if (numberEaten >=5){
//This means that this user has exhausted his/her quota so he/she cannot
//be allowed to eat again
//In this case, the eatPancake method is called again to randomly pick another user
//I am thinking of removing the user from the list here so that he/she cannot be picked again
usersList.remove(0);
eatPancake(users);
}else {
//Meaning that the user still has some quota left for him/her to eat
//In this other condition, it will check if there is an available pancake produced
if (availablePancake >=1){
//user will now eat the pancake
//then increment the number of pancake eaten by that user
// and decrement the number of pancakes available
int newCount = numberEaten + 1;
availablePancake -=1;
//finally update the user that just eaten the pancake
users.put(usersList.get(0),newCount);
}
}
}
}
public void performTask(){
//Hashmap is used to store the users because of key-value pairs
HashMap <String,Integer> users = new HashMap<>();
users.put("user1",0);
users.put("user2",0);
users.put("user3",0);
usersList.addAll(users.keySet());
System.out.println(users);
System.out.println(usersList);
//This task can only be executed in 20 seconds
Instant stop = Instant.now().plusSeconds(20);
System.out.println("The starting time is "+Instant.now());
while (stop.isAfter(Instant.now())){
//only continue the process if it has not exceeded 20 seconds
if (totalPancakeProduced <12){
producePancake(users);
}else {
break;
}
}
int available = totalPancakeProduced - consumedPancake;
int numbersLeftToMeetTheDemand = totalPancakeProduced - 15;
System.out.println("The ending time is "+Instant.now());
System.out.println("Total number of cake produced is "+totalPancakeProduced);
System.out.println("Total number of cake eaten is "+consumedPancake);
System.out.println("Total number of pancake remained is "+available);
}
Я удалил некоторые операторы печати для удобства чтения и использовал их в целях отладки. Пожалуйста, посмотрите еще раз @Stultuske
вы спрашиваете о поведении цикла while. Во всем остальном коде нет реальной необходимости.
Я знаю, я вставил код, чтобы он мог объяснить, что я пытаюсь решить, а также проблему, возникшую при попытке ее решения.
Я вызвал метод eatPancake в операторе else один раз перед оператором Break, чтобы последний созданный блин можно было съесть до завершения, но он все еще не работал.
можешь показать еще журнал печати? например, с 11 блинов и до конца?
Журнал заканчивается на 11-м блине. это означает, что съедено всего 11 блинов, а приготовлено 12 блинов. Произошло следующее: как только 12-й блин создан и затем проверено, что условие выполнено, он переходит к оператору Break в другой части и завершается без выполнения метода eatPancake, чтобы можно было съесть последний созданный 12-й блин.
я думаю, ты запутался. Ваш метод eatPancake
вызывается внутри метода producePancake
. Итак, после создания 12-го блина он не возвращается к циклу while, а вызывает метод eatPancake
.
Да, он вызывается внутри метода ProducePancake. Вопрос в том, почему он не вызывает его снова после производства последнего блина. Мне нужна помощь, где его разместить, чтобы его можно было снова вызвать сразу же, как будет изготовлен последний блин.
поэтому и прошу логи, чтобы посмотреть поток. Просто поделитесь ЖУРНАЛАМИ.
Вы обновляете consumedPancake
только внутри метода producePancake
.
Это станет проблемой, когда ваш цикл достигнет последней итерации. Потому что producePancake
рассчитает consumedPancake
на основе карты users
. После этого вызывается eatPancake
, который обновляет карту. Это приведет к неправильному количеству съеденных блинов, поскольку consumedPancake
не обновляется снова после eatPancake
в последней итерации.
Чтобы исправить это, вместо изменения consumedPancake
в методе producePancake
увеличьте его в методе eatPancake
после того, как блин будет съеден.
Так:
void eatPancake(HashMap<String,Integer>users){
if (usersList.size()>=1){
System.out.println("The list is "+usersList);
//first pick the user at random
Collections.shuffle(usersList)
int numberEaten = users.get(usersList.get(0));
//get the user that is on index zero after the list has been shuffled
//then check how many pancake that the picked user has eaten
//because each user is expected to eat a maximum of 5 pancake
if (numberEaten >=5){
//This means that this user has exhausted his/her quota so he/she cannot
//be allowed to eat again
//In this case, the eatPancake method is called again to randomly pick another user
//I am thinking of removing the user from the list here so that he/she cannot be picked again
usersList.remove(0);
eatPancake(users);
}else {
//Meaning that the user still has some quota left for him/her to eat
//In this other condition, it will check if there is an available pancake produced
if (availablePancake >=1){
//user will now eat the pancake
//then increment the number of pancake eaten by that user
// and decrement the number of pancakes available
int newCount = numberEaten + 1;
availablePancake -=1;
//finally update the user that just eaten the pancake
users.put(usersList.get(0),newCount);
//here
consumedPancake++;
}
}
}
}
amd удалить из ProducePancake:
void producePancake(HashMap<String,Integer>users){
//consumedPancake =0;
availablePancake = 0;
totalPancakeProduced = 0;
if ( totalPancakeProduced <12) {
/*
for (String user: users.keySet()){
consumedPancake +=users.get(user);
}
*/
//only continue with the production of pancakes if the number of pancakes
//produced has not exceeded the quota that was given (i.e 12)
System.out.println("Pancake produced");
//increment the number of pancakes available
availablePancake +=1;
totalPancakeProduced = consumedPancake + availablePancake;
eatPancake(users);
}
}
Кроме того, в вашем коде есть некоторые избыточные части, но, похоже, это не является причиной проблемы, поэтому их проигнорировали.
не могли бы вы опубликовать только соответствующий код? минимальный воспроизводимый пример должен подойти