Javascript 如何找到数组的一组唯一对?

Javascript 如何找到数组的一组唯一对?,javascript,algorithm,coding-efficiency,set-theory,Javascript,Algorithm,Coding Efficiency,Set Theory,假设我有以下数组: array = [0, 1, 2, ... , n] 如何找到一个集合,使集合中的对都是唯一且不重复的元素 这意味着: •(x,y)=(y,x)因此,如果(x,y)在集合中,则(y,x)不会在集合中,反之亦然 •如果一个元件已被使用,则不能再次使用 例如:如果(1,2)在集合中,则集合中不可能有具有1或2的对 背景: 我正在创建一个记忆游戏,将硬币放置在由2n个元素组成的棋盘上。我希望游戏的每次迭代都将元素放置在棋盘上的随机空间中 例如: 坦白地说,我不知道如果不使用O(n

假设我有以下数组:

array = [0, 1, 2, ... , n]
如何找到一个集合,使集合中的对都是唯一且不重复的元素

这意味着:

•(x,y)=(y,x)因此,如果(x,y)在集合中,则(y,x)不会在集合中,反之亦然

•如果一个元件已被使用,则不能再次使用

例如:如果(1,2)在集合中,则集合中不可能有具有1或2的对

背景: 我正在创建一个记忆游戏,将硬币放置在由2n个元素组成的棋盘上。我希望游戏的每次迭代都将元素放置在棋盘上的随机空间中

例如:

坦白地说,我不知道如果不使用O(n^2)蛮力方法,如何解决这个问题。我想可能还有另一种算法更有效。

创建两个输入数组(或一个包含重复元素的数组)。从数组中随机逐出元素,并将它们随机放置在3个输出数组中。您不需要对它们进行洗牌,因为您可以随机拾取元素,也可以随机放置

在您的代码中,如果在输出数组中,您可以检查元素是否已存在于给定索引中,以避免重写。

您可以使用在O(n)时间内高效地用每个硬币值中的两个洗牌数组。该算法基本上采用一个排序列表,并不断交换列表中的两个随机元素,直到列表在数学上被洗牌/随机

在JavaScript中:

// Generate seed array.
// Numbers are used here for simplicity, but the array can contain any type like String.
a = [];
for (i=0; i<4; i++) { a.push(i, i); }
console.log(a);  // [0, 0, 1, 1, 2, 2, 3, 3]

// This is the "modern version" pseudo-code ported to JavaScript:
// To shuffle an array a of n elements (indices 0..n-1):
n = a.length;
// for i from n−1 downto 1 do
for (i=n-1; i>0; i--)  {  
  // j ← random integer such that 0 ≤ j ≤ i
  j = Math.floor(Math.random() * (i + 1));

  // exchange a[j] and a[i] 
  tmp = a[j];
  a[j] = a[i];
  a[i] = tmp;
}
console.log(a);  // [2, 1, 3, 3, 0, 1, 0, 2]
//生成种子数组。
//这里使用数字是为了简单,但是数组可以包含任何类型,比如字符串。
a=[];
对于(i=0;i0;i--){
//j← 随机整数,使得0≤ J≤ 我
j=数学地板(数学随机()*(i+1));
//交换a[j]和a[i]
tmp=a[j];
a[j]=a[i];
a[i]=tmp;
}
console.log(a);//[2, 1, 3, 3, 0, 1, 0, 2]

旁注:即使你的算法中的O(n^2)听起来很糟糕,但对你的硬币游戏中的物品进行洗牌可能没有多大区别。在开始时,您只需洗牌一次少量项目。因此,您可能无法判断复杂性是O(n)还是O(n^2)。复杂性只在n变得非常大时才变得重要,或者需要不断重复计算(比如每秒数百万次)。我建议首先优化代码的可读性。然后只在明显需要的时候进行优化。

分享你的代码,以显示有人尝试过,@SagarAgrawal我的想法是,我不知道从哪里开始,我不是在寻找一个完整的算法,而是一个从哪里开始的想法,或者如果你正在创建内存游戏,你可以简单地创建两个输入数组。从数组中随机逐出元素,并将它们随机放置在3个输出数组中。创建[A、A、B、B、C、C、D、D、E、E、F、F]并进行洗牌?@TryKhov:没问题:)注意,您可以就地洗牌,所以只有一个数组。在JavaScript中声明变量很重要。您好@Leftium,谢谢您的建议。从前面的建议中,我奇怪地想到了类似的事情。我所做的是遍历列表,并在列表中用随机元素切换元素,这基本上就是您刚才介绍的!它工作正常,而且是我想要的。@TryKhov:酷!请注意,该算法的一个简单版本过于复杂,因此某些组合比其他组合更常见:不是真正的随机组合。这就是为什么费舍尔·耶茨设计成这样。
// Generate seed array.
// Numbers are used here for simplicity, but the array can contain any type like String.
a = [];
for (i=0; i<4; i++) { a.push(i, i); }
console.log(a);  // [0, 0, 1, 1, 2, 2, 3, 3]

// This is the "modern version" pseudo-code ported to JavaScript:
// To shuffle an array a of n elements (indices 0..n-1):
n = a.length;
// for i from n−1 downto 1 do
for (i=n-1; i>0; i--)  {  
  // j ← random integer such that 0 ≤ j ≤ i
  j = Math.floor(Math.random() * (i + 1));

  // exchange a[j] and a[i] 
  tmp = a[j];
  a[j] = a[i];
  a[i] = tmp;
}
console.log(a);  // [2, 1, 3, 3, 0, 1, 0, 2]