2016-09-20 56 views
0

我們有數組:兩個嵌套的for /環路而不需要重複對

var arr = [0,1,2]; 

和循環:

for (var i=0; i<arr.length; i++) { 
    for (var j=0; j<arr.length; j++) { 
     if (arr[i] == arr[j]) continue; 
     console.log(arr[i], arr[j]); 
    } 
} 

輸出:

0,1 //a--| 
0,2 //b--|--| 
1,0 //a--| | 
1,2 //c-----|--| 
2,0 //b-----| | 
2,1 //c--------| 

,我們可以看到有被複制對(在評論的a,b和c發生兩次)

我們可以擺脫重複對的唯一方法是將已匹配的對存儲在某種內存中?

var mem = {}; 

for (var i=0; i<arr.length; i++) { 
    for (var j=0; j<arr.length; j++) { 
     var left = i; 
     var right = j; 
     if (left > right) { 
      var temp = right; 
      right = left; 
      left = temp; 
     } 

     if (arr[i] == arr[j] || mem[arr[left]+","+arr[right]]) continue; 

     console.log(arr[i], arr[j]); 
     mem[arr[left]+","+arr[right]] = true; 
    } 
} 

輸出:

0,1 
0,2 
1,2 

但這需要額外的內存(更大的陣列,它需要大量的吧..)

是不存在任何存儲附加任何其他方式?

+1

簡短的答案是...沒有 – charlietfl

+0

難道這些循環將是數百萬大,因爲如果不是,我沒有看到過早優化的理由。當這確實會導致可衡量的問題時,可能會有一個可能更有效的過濾器,我不是他們的專家。即使如此,我懷疑它的內存使用率相同,但在代碼中不太明顯。 – Goose

回答

5

如果輸入數組是獨一無二的你爲什麼不只是啓動Ĵ從i + 1

for (var i=0; i<arr.length; i++) { 
    for (var j= i + 1 ; j<arr.length; j++) { 
     console.log(arr[i], arr[j]); 
    } 
} 
+0

太簡單了。我會在兩分鐘內接受答案。 – ElSajko

+1

哇,這實際上比我做的更有效率,儘管它使用了相同的原理。太好了! – Feathercrown

+0

@ Feathercrown:也更適合鏈接列表。 – ElSajko

1

一個可能的算法如下:

  1. 排序的數組。

  2. 從數組中刪除重複的值(後面留下1),對於每個值爲x的副本,輸出(x,x)

  3. 對於每一對指數ij這樣i < j,輸出相應的對(i,j)

雖然這可能不會產生排序輸出,但它確實處理重複值和未排序的輸入數組。

1
for (var i=0; i<arr.length; i++) { 
    for (var j=0; j<arr.length; j++) { 
     if (arr[i] == arr[j] || j<i) continue; 
     console.log(arr[i], arr[j]); 
    } 
} 

這應該有效。

說明: 如果j比我少,那麼你可以切換i和j獲得另一個輸出使用相同的兩個值。但是如果你讓數組中的j在前面,那麼不會輸出重複數據。

如何它 「看起來」:

O =數組值

X = ARR [I]

| = ARR [j]的

- = ARR [i]和ARR [j]的在這個點都

-oooo //繼續

X | OOO

xo | oo

xoo | o xooo |

然後,沒有改變:

| xooo //輸出!與行(/步)2相同!

鄰OOO //繼續

牛| OO

有了變化: | xooo // j是在我,所以不輸出。避免線路重複(/步)2.

鄰OOO //繼續

牛| OO

+0

像Amin J回答,帶有額外的不必要的計算。 –

+0

@TomerW是的,我看到了。不過,我仍然要離開它。 – Feathercrown