【问题标题】:Random accessing array, how to skip duplicates?随机访问数组,如何跳过重复项?
【发布时间】:2011-12-18 01:49:24
【问题描述】:

我有一个 XML 数组,可以从中提取随机问题。我将如何确保没有重复?我当前的代码如下。

    private void getQuestion() {
    // TODO Auto-generated method stub

    res = getResources();
    qString = res.getStringArray(R.array.questions);

    rQuestion = qString[rgenerator.nextInt(qString.length)];

    tokens = new StringTokenizer(rQuestion, ":");
    wordCount = tokens.countTokens();
    sep = new String[wordCount];
    wArray = 0;
    while (tokens.hasMoreTokens()) {
        sep[wArray] = tokens.nextToken();
        wArray++;
    }

}

任何帮助将不胜感激。

【问题讨论】:

    标签: java android arrays random


    【解决方案1】:

    Fisher-Yates shuffle 是一种或多或少为此目的而设计的算法。

    【讨论】:

    • 我使用 ArrayList 和 Collections.shuffle() 添加了您可能感兴趣的答案。
    【解决方案2】:

    最好将这一系列问题放在一个列表中并使用 Collections.shuffle()。之后,只需遍历列表。更多信息请访问this related answer

    此解决方案将花费一些内存来复制列表,但请记住,字符串本身不会被复制,只有问题的引用会被复制。为获得最佳性能,请使用具有随机访问权限的列表 (ArrayList),或将其用作数组的替代品。如果你不这样做,shuffle 方法将在内部创建一个。

    【讨论】:

      【解决方案3】:

      如果您想要一种从数组中仅获取唯一值的快速方法,this link 有一个非常快速的方法。下面使用了一个 ArrayList,但你不难从字符串数组转换为 ArrayList - 或者直接使用 ArrayLists。

      e.g. new ArrayList(Arrays.asList(myArray));
      

      简而言之,您使用哈希集仅使用此方法获取唯一值

      public static ArrayList GetUniqueValues(Collection values)
      {
          return new ArrayList(new HashSet(values));
      }
      

      那就这样用吧

      ArrayList x = new ArrayList();
      x.add("abc");
      x.add("abc");
      x.add("abc");
      x.add("def");
      x.add("def");
      x.add("ghi");
      
      for (Object y : GetUniqueValues(x))
          Log.d("something", y); //ok lets print the value
      

      产生“abc, def, and ghi”的结果

      为了清楚起见,我同意 Travis 询问您为什么有重复的问题。以上就是回答问题。

      【讨论】:

      • 这个解决方案的主要问题是它会对你的值进行排序。例如,列表将由abc, def, ghi 组成,无论它们添加的顺序是什么。在这种情况下这应该不是问题,但要记住这一点。
      • 我没有重复,但是我发布的方法可以并且确实多次返回相同的答案,因为随机是相同的,所以在数组中相同位置的相同字符串被拉两次
      • 对不起,我帮不上什么忙。我会看看 Leo 的另一个答案,这可能是我处理你的场景的方式。感谢 Jake 为我的回答做出了更多贡献。
      【解决方案4】:

      我想通了。我把它换成

      private void getQuestion() {
          res = getResources();
          qString = res.getStringArray(R.array.questions);
          arrayLength = qString.length;
          qTotal = arrayLength;
      
      }
      
      private void getRandom() {
          rnd = rgenerator.nextInt(arrayLength);
          rQuestion = qString[rnd];
          qString[rnd] = "used";
          seperate();
      
      }
      
      private void seperate() {
          if (rQuestion != "used") {
              tokens = new StringTokenizer(rQuestion, ":");
              wordCount = tokens.countTokens();
              sep = new String[wordCount];
              wArray = 0;
              while (tokens.hasMoreTokens()) {
                  sep[wArray] = tokens.nextToken();
                  wArray++;
              }
              qNumber++;
          } else {
              if (qNumber < qTotal) {
                  getRandom();
              } else {
                  startActivity(new Intent("com.example.END"));
              }
          }
      
      }
      

      它从资源中获取数组,然后从数组中随机抽取一个问题。然后它将那个设置为“已使用”并将其拆分。它还检查拉出的问题是否“已使用”,如果是,则拉出另一个问题。如果所有问题都“已使用”,它还会进入游戏结束活动

      【讨论】:

      • 如果您有足够多的问题,您可能会惊讶地发现您需要等待该算法找到最后一个问题需要多长时间,并且最长等待时间(顺序)甚至是无限的。
      猜你喜欢
      • 2016-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-27
      • 1970-01-01
      • 2014-05-18
      • 2011-05-21
      相关资源
      最近更新 更多