Nano Hash - криптовалюты, майнинг, программирование

Итерация по списку в поисках дубликатов

Итак, у меня есть задача: я должен бросить кости, а затем найти определенную комбинацию, если она выпала. У меня есть переопределенный метод equals, который проверяет комбинацию и работает правильно. Каждый объект из class Dice имеет свой собственный массив строк, который содержит информацию о том, при каком броске выпадает комбинация. Например, комбинация двух выпавших игральных костей (2, 4) была выброшена при 5-м броске из 5, поэтому ее массив имеет: [.., .., .., .., 5] И затем каждый объект из class Dice сохраняется в List<Dice>, который, с другой стороны, помещается в хэш-карту вместе с массивом строк каждой кости. Моя борьба заключается в том, что я не могу понять, как перебирать список игральных костей и проверять, была ли каждая комбинация выброшена более одного раза, и помещать информацию о том, на каком броске она находится, в первую, а затем удаляя дубликат.

Например, предположим, что комбинация (4, 1) была выброшена на первом, а затем на 4-м броске... ее строковый массив должен выглядеть так: [1, .., .., 4, ..], вместо этого печать хэш-карты показывает 2 элемента с комбинацией (4, 1) и их собственными массивами:

[1, .., .., .., ..], [.., .., .., 4, ..].

Надеюсь, вы понимаете мою борьбу.

public class Dice {
  private int firstDice;
  private int secondDice;
  public String[] rollArray;
  public int roll;
  public int duplicate = 1; 

  /**
   * Constructor for the class Dice.
   * @param first first dice
   * @param second second dice
   */
  public Dice(int first, int second) {
    firstDice = first;
    secondDice = second;
  }

  @Override
  public String toString() {
    return "(" + firstDice + ", " + secondDice + ")";
  }

  /**
   * Method equals used for comparing two objects from the class Dice.
   * @param obj object from dice class
   * @return returns true/false if conditions are matched.
   */
  public boolean equals(Dice obj) {
    return (obj.firstDice == firstDice && obj.secondDice == secondDice);
  }
}



import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

/**
 * Created by leo on 6/10/15. Class which contains all methods that realize the rolling of two dices
 * and storing the information about them in a hash map.
 */
public class DiceRoller {

  public List<Dice> diceList = new LinkedList<>();
  public List<String> rollingList = new LinkedList<>();

  /**
   * A method which rolls two dices a number of times with random values.
   *
   * @param numberOfRolls number of rolls
   */
  public void rollDice(int numberOfRolls) {
    Random rand = new Random();
    for (int i = 0; i < numberOfRolls; i++) {
      diceList.add(i, new Dice(rand.nextInt(7 - 1) + 1, rand.nextInt(7 - 1) + 1));
      diceList.get(i).rollArray = new String[numberOfRolls];
      diceList.get(i).roll = i + 1;
      diceList.get(i).rollArray[i] = diceList.get(i).roll + "";
      rollingList.add("" + (i + 1));
      checkDuplicateDice(diceList, diceList.get(i));
    }
  }


  private void checkDuplicateDice(List<Dice> listOfDice, Dice tempDice) {
    /*
     * for (int i = 0; i < listOfDice.size(); i++) { for (int j = i + 1; j < listOfDice.size(); j++)
     * { if (listOfDice.get(i).toString().equals(listOfDice.get(j).toString())) {
     * listOfDice.get(i).duplicate++; } } } for (int i = 0; i < listOfDice.size(); i++) {
     * System.out.println(listOfDice.get(i).toString() + listOfDice.get(i).duplicate); }
     */
    Iterator<Dice> iter = listOfDice.iterator();
    while (iter.hasNext()) {
      Dice elem = iter.next();
      if (elem.toString().equals(tempDice.toString())) {
        elem.duplicate++;
      }
      System.out.println(elem.toString() + elem.duplicate);
    }
  }

  /**
   * A method which checks if the combination entered is rolled.
   *
   * @param first first dice
   * @param second second dice
   */

  public void checkCombination(int first, int second) {
    Dice checker = new Dice(first, second);
    int index = 1;
    boolean flag = false;
    for (Dice diceObject : diceList) {
      diceObject.rollArray = new String[diceList.toArray().length];
      diceObject.rollArray[index - 1] = index + "";
      for (int i = 0; i < diceList.size(); i++) {
        if (diceObject.rollArray[i] == null) {
          diceObject.rollArray[i] = "..";
        }
      }

      if (diceObject.equals(checker)) {
        System.out.println("Combination: (" + first + ", " + second + ") rolled on roll No: "
            + index);
        flag = true;
      }
      index++;
    }
    if (!flag) {
      System.out.println("Combination not rolled.");
    }
  }

  /**
   * A method which stores the data of the dice and each dice'.
   */
  public void hashMapThingy() {
    System.out.print("Roll: ");
    for (int i = 0; i < rollingList.size(); i++) {
      System.out.print((i + 1) + " ");
    }

    System.out.print("\n");
    System.out.println("Comb:");
    HashMap<Dice, String[]> hm = new HashMap<>();
    for (Dice diceObject : diceList) {
      hm.put(diceObject, diceObject.rollArray);
    }

    Set<Map.Entry<Dice, String[]>> set = hm.entrySet();
    for (Map.Entry<Dice, String[]> me : set) {
      System.out.println(me.getKey() + " " + Arrays.toString(printArray(me.getValue())));
    }
  }

  /**
   * Printer method.
   * 
   * @param array array that contains the roll number
   * @return returns the array string
   */
  public String[] printArray(String[] array) {
    return array;
  }
}


public class Test {
  /**
   * Main function.
   * 
   * @param args arguments
   */
  public static void main(String[] args) {
    int number = 5;
    DiceRoller diceRoller = new DiceRoller();
    diceRoller.rollDice(number);
//    Dice.fillDiceList();

//    Dice.printListDices();
    diceRoller.checkCombination(3, 2);
    diceRoller.checkCombination(1, 3);
    diceRoller.checkCombination(6, 3);
    diceRoller.hashMapThingy();
  }
}

И текущий вывод консоли:

(5, 1)2
(5, 1)2
(1, 1)2
(5, 1)3
(1, 1)2
(5, 1)2
(5, 1)3
(1, 1)2
(5, 1)2
(1, 5)2
(5, 1)3
(1, 1)2
(5, 1)2
(1, 5)2
(4, 4)2
Combination not rolled.
Combination not rolled.
Combination not rolled.
Roll: 1 2 3 4 5 
Comb:
(1, 1) [.., 2, .., .., ..]
(1, 5) [.., .., .., 4, ..]
(5, 1) [1, .., .., .., ..]
(5, 1) [.., .., 3, .., ..]
(4, 4) [.., .., .., .., 5]

  • Какой вопрос? 12.06.2015
  • (1) Когда вы переопределяете equals, всегда переопределяйте и hashCode. (2) почему бы вам не использовать Set вместо List, если вам не нужны дубликаты? 12.06.2015
  • зачем создавать массив строк для каждой комбинации? это кажется слишком сложным. Я бы просто сохранил кости в наборе, как говорит RealSkeptic, а затем просто проверил, содержит ли этот набор конкретную игральную кость (используя ваши собственные методы hashCode и equals) 12.06.2015
  • @vefthym Хорошо ... Я сделал это, но это не главное. Суть в том, чтобы сказать, на каком именно броске выпадает комбинация. Это домашнее задание, поэтому я должен использовать HashMap для отображения результатов в виде таблицы. Мои методы поиска конкретной комбинации работают, но с этого момента я изо всех сил пытаюсь: (1) отредактировать информацию о кости с информацией о ее дубликате; (2) удалить дубликат. С моими объектами из класса Dice, которые имеют свой собственный массив, два кубика никогда не могут быть одинаковыми, поэтому все оказывается в наборе. 12.06.2015

Ответы:


1

Проблема с вашим методом checkDuplicateDice

  private void checkDuplicateDice(List<Dice> listOfDice, Dice tempDice) {
  boolean duplicate = false;
  for (Dice elem : listOfDice) {
      if (elem.roll != tempDice.roll && elem.toString().equals(tempDice.toString())) {
            elem.duplicate++;
            elem.rollArray[tempDice.roll-1] = tempDice.roll + "";
            duplicate = true;
        }
  }
  if(duplicate)
      listOfDice.remove(tempDice.roll -1);

}

Как и выше, вам нужно обновить свой rollArray и отправить его обратно, чтобы rollArray был обновлен.

Делать это таким образом - не лучший способ, но изменение, как указано выше, даст желаемый ответ.

12.06.2015
  • Не знаю, но это не помогло. 12.06.2015
  • Это связано с тем, что в методе checkCombination массив повторно инициализируется. Попробуйте использовать hashMapThingy перед методом checkCombination 12.06.2015
  • Ok. Это работает да! Спасибо. Теперь .. Чтобы выяснить, как удалить кости, не вызывая никаких неприятных исключений. 12.06.2015
  • Обновлен метод удаления записи. Но в вашем случае, поскольку вы добавляете кости в индекс, я бы рекомендовал не удалять его здесь. 12.06.2015

  • 2

    Мне было интересно, смогу ли я следовать логике Суджита Чайтаньи, и я подумал, почему метод не возвращает объект из класса Dice вместо void, а затем использует этот объект для его безопасного удаления без исключений. Я немного изменил его, и получилось довольно хорошо. .

    private Dice checkDuplicateDice(List<Dice> listOfDice, Dice tempDice) {
    
    boolean duplicate = false;
    for (Dice elem : listOfDice) {
      if (elem.roll != tempDice.roll && elem.toString().equals(tempDice.toString())) {
        elem.rollArray[tempDice.roll - 1] = tempDice.roll + "";
        duplicate = true;
      }
    }
    if (duplicate) {
      return tempDice;
    }
    return null;
    

    }

    В методе rollDice я вставил новый цикл for после первого:

    for (int j = 0; j < diceList.size(); j++) {
      if (checkDuplicateDice(diceList, diceList.get(j)) != null) {
        diceList.remove(j);
      }
    }
    

    Я также изменил метод checkCombination, чтобы он не переопределял массив. Я добавил новую глобальную переменную listSize, которая принимает diceList.size() сразу после того, как все кости были брошены, чтобы она не менялась после удаления костей. Я использую listSize в цикле, чтобы правильно отметить те элементы массива строк, которые не содержат значения (являются null)

    public void checkCombination(int first, int second) {
    Dice checker = new Dice(first, second);
    int index = 1;
    boolean flag = false;
    for (Dice diceObject : diceList) {
    
      for (int i = 0; i < listSize; i++) {
        if (diceObject.rollArray[i] == null) {
          diceObject.rollArray[i] = "..";
        }
      }
    
      if (diceObject.equals(checker)) {
        System.out.println("Combination: (" + first + ", " + second + ") rolled on roll No: "
            + index);
        flag = true;
      }
      index++;
    }
    if (!flag) {
      System.out.println("Combination not rolled.");
    }
    

    }

    Тогда вывод был следующим:

    Roll: 1 2 3 4 5 
    Comb:
    (2, 1) [.., .., 3, .., ..]
    (3, 6) [.., 2, .., 4, 5]
    (6, 5) [1, .., .., .., ..]
    
    12.06.2015
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..