【问题标题】:How do I perform a duplicate check in code?如何在代码中执行重复签入?
【发布时间】:2013-07-25 17:07:22
【问题描述】:

这对某些人来说可能是显而易见的,但我正在尝试检查我的代码中是否有任何重复的值。

为了清楚起见,我正在创建 5 个变量 整数,它们会在创建后随机化一个数字。假设他们被命名为i1i2i3i4i5

我想运行一个循环来相互检查,以确保它们没有任何可能的重复项。如果他们这样做,我将重新随机检查 第二个整数。 (例如 if (i1 == i4) { i4.rand(); })这是为了确保 i1 不需要针对所有先前检查的值进行重新检查,或者在找到不同的数字之前陷入长循环。

如果它是一个完整的 if else 语句,这就是我的想法:if (i1 == i2)if (i1 == i3)if (i1 == i4)if (i1 == i5)if (i2 == i3)if (i2 == i4)if (i2 == i5)if (i3 == i4) , if (i3 == i5), if (i4 == i5)

我知道我可以通过创建大量 if / else 语句来“手动”执行此操作,但有更好的方法吗?如果我将整数限制增加到 20 并且我必须通过 20 次值检查来if / else,这可能不是很可行。我知道有,但我就是想不起来。在 Google 上搜索什么都没有(也许我在搜索错误的关键字),这就是我在 StackOverflow 上询问的原因。

我只想知道我该怎么做,理论上的(理论上你会如何检查重复项?)。答案不一定是可行的函数。

如果您想使用我用于此问题的编程语言创建演示代码,itsExcel VBA。但我认为这些信息可以在理论上适用于许多其他编程语言,因此请随时使用javascript/jQueryC++C# 等写信。记得发表评论!

【问题讨论】:

  • 我认为您的意思是重复的values,而不是变量。无论如何,你是如何创建随机数开始的?
  • 嗯,一个 random() 函数,大多数编程语言都提供 -- Excel VBA 有 Rand()。
  • 同理,先随机,再检查重复。
  • 非常感谢你们让我了解如何解决这样的问题。我还有很多东西要学!

标签: loops


【解决方案1】:

你正在寻找Set;

    Set<Integer> hs = new HashSet<Integer>();
    hs.add(i1);
    if(!hs.add(i2)){
       randomize(i2);
    }

希望这会有所帮助。让我知道,如果您有任何问题。 以上只是一个概念。

要获取代码的逻辑,它将是

   Set<Integer> hs = new HashSet<Integer>();

    for(int count=0; count<Array.length; count++){  // Store the data into the array and loop
        dataToInsert = Array[count]; 

        while(hs.add(dataToInsert)){
           dataToInsert = randomize(dataToInsert);
        }
     }

【讨论】:

  • 要搭载此解决方案,您可能希望使用do { randomize(x) } while (!hs.Add(x)) 而不是现在的if 块。
  • 对,for 循环。所以我必须先将所有变量放入一个数组中......然后运行循环?知道什么是 .add 在 VBA 中的等价物吗?或者这是VBA?我很困惑。
  • 是的,先将元素放入数组中,然后循环遍历数组。上面的代码是用 Java 编写的。这也适用于 C#。
  • 没问题。如果答案对您有所帮助,如果您能通过接受答案来结束问题,我将不胜感激。谢谢
【解决方案2】:

您可以做的是循环遍历List&lt;int&gt;,并且对于索引i 处的每个元素x,循环while list.Take(i-1).Contains(x) 并将x 替换为新的随机数。

但是,如果您只是想以相对便宜的方式检查给定的 List&lt;int&gt; 是否包含唯一编号,则可以执行以下操作:

bool areAllUnique = list.Count() != list.Distinct().Count()`

【讨论】:

    【解决方案3】:

    伪代码:

    1. 创建一个空集S
    2. 生成一个伪随机数r
    3. 如果rS 中,则转到2。否则,转到4。
    4. 将 R 添加到 S。
    5. 如果还有变量需要初始化,转2。

    Java 中的示例实现:

    public static void main(String[] args)
    {
        System.out.println(getUniqueRandoms(5, 10));
    }
    
    public static Set<Integer> getUniqueRandoms(int howMany, int max)
    {
        final Set<Integer> uniqueRandoms = new HashSet<Integer>(howMany);
        while (uniqueRandoms.size() < howMany)
        {
            uniqueRandoms.add((int) (Math.random() * max));
        }
        return uniqueRandoms;
    }
    

    输出:

    [8, 2, 5, 6, 7]
    

    如果您想将它们放在数组中,而不是在 Set 中,只需在您的 Set 上调用 toArray()

    【讨论】:

      【解决方案4】:

      这是一种获取整数的简单方法,假设您要在 1 到 N 的范围内生成整数

      从 1:N 生成一个整数 从 1:N-1 生成一个整数 从 1:N-2 生成一个整数 从 1:N-(k-1) 生成一个整数

      现在将这些解释为您生成的整数的位置(在该数字的总可用整数集中)并构造您的实整数。

      Example, N = 5, k=4
      3
      1
      2
      2
      
      i1 = 3
      i2 = 1
      i3 = 4 (the available integers are 2 4 5)
      i4 = 5
      

      请注意,这需要最少数量的随机数生成。

      【讨论】:

        【解决方案5】:
        HashSet<Integer> set = new HashSet<Integer>();
        for(int i = 0; i < 5; i++)
        {
            int x;
            do
            {
                x = random();
            }
            while(!set.Add(x));
        }
        
            int i1 = set.ElementAt(0),
                i2 = set.ElementAt(1),
                i3 = set.ElementAt(2),
                i4 = set.ElementAt(3),
                i5 = set.ElementAt(4);
        

        【讨论】:

          【解决方案6】:

          我能想到的两种方法。

          1:循环遍历集合中的所有值并将每个值与您添加的值进行比较。

          2:创建一个简单版本的哈希映射:

          var set
          var map_size
          create_set(n):
              set <- array of size n of empty lists
              map_size <- n
          
          add_number(num_to_add):
              if num_to_add not in set[num_to_add % map_size]:
                  add num_to_add to set[num_to_add % map_size]
                  return success
              else:
                  return failure
          
          populate_set():
              loop 5 times:
                  i <- random_number()
                  while(add_number(i) == failure):
                      i <- random_number()
          

          这样,每次添加一个数字时,您最多只检查[max value of integer] / [map size] 值,而不是检查集合中的所有其他数字。平均[number of elements in set] / [map size](我认为,如果我错了,请纠正我)值。

          【讨论】:

            【解决方案7】:

            试试

            ArrayList<Integer> list = new ArrayList<Integer>();
            
            while (list.size() < 5)
            {
                int i = Math.random() * max;
                if (!list.contains(i))
                {
                    list.add(i);
                }
            }
            

            你会得到list 5 个不同的整数。

            【讨论】:

              【解决方案8】:

              需要明确的是,您尝试的是错误的方法。 理论上,检查重复项并在找到重复项时“重新随机化”,可以执行无限长的时间,因为可以连续选择现有整数。

              你应该做的是构造整数集合,这样一开始就不会有重复。丹尼斯贾赫鲁丁的回答就是这样做的。或者,如果您有一组特定的整数可供选择(例如 1-20),并且您只是希望它们按随机顺序,您应该使用shuffling algorithm。无论如何,您应该首先在您的语言中搜索这些现有的实现,因为几乎可以肯定之前已经完成了。

              【讨论】:

              • 我有点意识到,几乎每个人的回答都是基于你刚才写的:“以这样一种方式,一开始就不会有重复”。
              • @RenoYeo 实际上他们中的大多数似乎都有同样的问题:他们正在选择一个随机值并检查它是否已经被选择,这可能会在真正唯一的值出现之前发生任何次数选择。
              • 嗯。我没有真正得到的是丹尼斯的代码——从 1:N 的范围,假设 N 是 5...所以如果生成器生成 4,下一个可用步骤 (1:N-1) 不会结果可能范围仅为 1 - 4,并且可能有机会获得第一步生成的副本?
              • 选择的初始整数不一定是最终结果。我相信他指的算法是this one
              【解决方案9】:

              R 中很简单...

              i <- as.integer(runif(5, 1, 10))
              
              for(l in seq_along(i)){
                while(any(i[l]==i[-l])) # checks each against all the other
                  i[l] <- as.integer(runif(1, 1, 10))
              }
              

              但是在R 中有一个函数sample 从给定的向量中选择随机元素而不重复(即使您可以选择拥有它们)

              > sample(1:10, 5)
              [1] 2 5 1 9 6
              > sample(1:10, 5)
              [1] 3 5 8 2 1
              > sample(1:10, 5)
              [1] 8 3 5 9 4
              > sample(1:10, 5)
              [1]  1  8  9 10  5
              

              【讨论】:

                猜你喜欢
                • 2013-08-10
                • 2017-09-24
                • 2018-10-25
                • 1970-01-01
                • 1970-01-01
                • 2023-03-16
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多