简体   繁体   English

遍历列表搜索重复项

[英]Iterating through a list searching for duplicates

So I have this task that I must do a dice roller and then search for a certain combination if it was rolled. 因此,我有一个任务,我必须做一个骰子滚子,然后搜索某个组合(如果滚动了)。 I have an overriden equals method, that checks for the combination and it is working properly. 我有一个重写的equals方法,该方法检查组合是否正常。 Every object from the class Dice has its own string array which contains information about on which roll is the combination rolled. class Dice每个对象都有自己的字符串数组,其中包含有关组合滚动到哪个滚动的信息。 For example combination of two rolled dice (2, 4) was rolled on 5th roll out of 5 so its array has: [.., .., .., .., 5] And then each object from the class Dice is stored in a List<Dice> which on the other hand is put into a hashmap alongside each dice' string array. 例如,将两个滚动骰子(2, 4)组合从5中滚出了第5个,因此其数组具有: [.., .., .., .., 5] ,然后存储class Dice每个对象在List<Dice> ,另一方面,它与每个骰子的字符串数组一起放入哈希图中。 My struggles are that I can't understand how to iterate over the list of dice and check if each combination was rolled more than once and put the information about on which roll it's on into the first and then removing the duplicate. 我的挣扎在于,我不知道如何遍历骰子列表,并检查每个组合是否滚动了一次以上,然后将有关滚动的信息放入第一个,然后删除重复项。

For example let's say the combination (4, 1) has been rolled on the first and then on the 4th roll... its string array should look like: [1, .., .., 4, ..] , instead, the printing of the hashmap shows 2 elements with (4, 1) combination and their own arrays: 例如,假设组合(4, 1)在第一卷上滚动,然后在第四卷上滚动...其字符串数组应类似于: [1, .., .., 4, ..] ,哈希图的打印显示2个元素具有(4, 1)组合和它们自己的数组:

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

I hope you understand my struggles. 我希望你理解我的挣扎。

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();
  }
}

And current console output: 和当前控制台输出:

(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]

The problem is with your checkDuplicateDice method 问题出在您的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);

} }

Like above you need to update your rollArray and send it back so that rollArray will be updated. 像上面一样,您需要更新rollArray并将其发送回去,以便更新rollArray。

Doing it this way is not the best way but changing as above will get the answer you want 这样做不是最好的方法,但是按上述方法进行更改将得到您想要的答案

I wondered if I could follow Sujit Chaitanya's logic and I thought why not the method return an object from the class Dice, instead of void then use that object to remove it safely without exceptions.. I modified it a bit and it turned out pretty good. 我想知道我是否可以遵循Sujit Chaitanya的逻辑,我想为什么该方法不从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;

} }

In the rollDice method I inserted a new for loop after the first one: rollDice方法中,我在第一个之后插入了一个新的for循环:

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

I also modified the checkCombination method to not override the array. 我还修改了checkCombination方法以不覆盖数组。 I added a new global variable listSize which takes the diceList.size() right after all the dices have been rolled so that it won't change after a dice is removed. 我添加了一个新的全局变量listSize ,它在所有骰子都滚动后diceList.size()以便在删除骰子后它不会改变。 I use the listSize in the loop in order to correctly mark those elements of the string array that don't contain a value (are null ) 我在循环中使用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.");
}

} }

Then the output was as follows: 然后输出如下:

Roll: 1 2 3 4 5 
Comb:
(2, 1) [.., .., 3, .., ..]
(3, 6) [.., 2, .., 4, 5]
(6, 5) [1, .., .., .., ..]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM