在数组中查找重复的三元组
Find repeated triads in arrays
我有一个数组集合,其中包含从 1 到 10 的数字。每个数组的大小为 5。例如
[1,2,3,4,5]
[3,4,9,8,2]
[1,5,7,9,2]
[1,2,5,9,7]
...........
[3,8,1,6,9]
我应该使用什么算法来查找这些数组中重复的三元组?
例如,其中一个结果应该是 1、2、5,因为这个三元组包含在某些数组中。我不介意某个三合会重复了多少次。我最常查看 n(可能是 3 或 4 或其他)。
[1,2,3] 与 [3,1,2] 相同,每个数字只允许出现一次。 [3,3,4] 无效。
如果我们假设数组包含 10 个或更多数字,那么这个问题会变得更难,这样每个数组都可以有三元组的组合。深思
[1,3,5,19,45,11,12,13,9,31]
[1,3,5,32,46,15,12,18,29,37]
result : (1,3,5) (1,3,12) (3,5,12) etc
我会用蛮力去。取决于您如何定义 'triad'([1,2,3] 与 [3,2,1] 不同吗?[3,3,3] 是否可以接受?)来自 C(10,3)= 120 到 1000 个可能的三元组,每个数组生成 C(5,3)=10 个三元组。
为三元组准备一个(哈希)table 计数器,遍历数组更新计数器,select 个具有最大计数的三元组。
我已经完全检查了我的回复:
- **修复错误**:`array function computeRepettition(array $a);`
- **避免**如果已在 pass-1 中找到三元组,则重复增加
- **Return**一个数组的数组,每个三元组的重复次数在'**numberOfRepetition**'中设置,self中的三元组是数组的键
- **支持**2位及以上数字组成
-
**新** `array function iCombination(array $a);` 减少找到三元组的概率,因为顺序不重要,并且不允许重复数字
- `array function detectRepetition(array $a);` 的**Update** 检测所有可以找到的三元组
<?php
define ("MIN_LENGTH_VECTOR" , 3 );
define ("KEY_SEPERATOR" , '-');
$src2D = array (
array(1,3,5,19,45,11,12,13,9, 100,31),
array(1,3,5,32,46,15,100, 12,18,29,37),
array(1222,32222,5,3222222,4622222,1522222,100, 12,182222,292222,372222));
var_dump (computeRepetition ($src2D));
function computeRepetition ($src2D) {
$repetition = array ();
for ($i=0 ; $i<count($src2D)-1 ; $i++) {
foreach ($repetition as &$rep) {
$rep['escape'] = TRUE;
}
for ($j=$i+1 ; $j<count($src2D) ; $j++) {
$t = buildTruth ($src2D[$i], $src2D[$j]);
$r = detectRepetition ($t);
if (is_null ($r)) continue;
$comb = iCombination ($r);
foreach ($comb as $cb) {
if (isset ($repetition[$cb]['escape']) && $repetition[$cb]['escape'] === TRUE) continue;
if (array_key_exists ($cb, $repetition)) {
$repetition[$cb]['numberOfRepetition']++;
} else {
$repetition[$cb]['numberOfRepetition'] = 2;
$repetition[$cb]['escape'] = FALSE;
}
}
}
}
return $repetition;
}
function detectRepetition ($t) {
$a = array ();
foreach ($t as $key => $value) {
if ($value === TRUE) {
$a[] = $key;
}
}
if (count($a) < MIN_LENGTH_VECTOR) return NULL;
return $a;
}
function iCombination ($array) {
$res = array ();
sort ($array, SORT_NUMERIC);
for ($i = 0 ; $i < count ($array) - 2 ; $i++) {
for ($k = $i + 1 ; $k < count ($array) - 1 ; $k++) {
for ($l = $k + 1 ; $l < count ($array) ; $l++) {
$res[] = $array[$i] . KEY_SEPERATOR . $array[$k] . KEY_SEPERATOR . $array[$l];
}
}
}
return $res;
}
function buildTruth ($vec1, $vec2) {
foreach ($vec1 as $v) {
$t[$v] = FALSE;
}
foreach ($vec2 as $v) {
if (isset ($t[$v]) && $t[$v] === FALSE ) $t[$v] = TRUE ;
}
return $t;
}
我有一个数组集合,其中包含从 1 到 10 的数字。每个数组的大小为 5。例如
[1,2,3,4,5]
[3,4,9,8,2]
[1,5,7,9,2]
[1,2,5,9,7]
...........
[3,8,1,6,9]
我应该使用什么算法来查找这些数组中重复的三元组? 例如,其中一个结果应该是 1、2、5,因为这个三元组包含在某些数组中。我不介意某个三合会重复了多少次。我最常查看 n(可能是 3 或 4 或其他)。
[1,2,3] 与 [3,1,2] 相同,每个数字只允许出现一次。 [3,3,4] 无效。
如果我们假设数组包含 10 个或更多数字,那么这个问题会变得更难,这样每个数组都可以有三元组的组合。深思
[1,3,5,19,45,11,12,13,9,31]
[1,3,5,32,46,15,12,18,29,37]
result : (1,3,5) (1,3,12) (3,5,12) etc
我会用蛮力去。取决于您如何定义 'triad'([1,2,3] 与 [3,2,1] 不同吗?[3,3,3] 是否可以接受?)来自 C(10,3)= 120 到 1000 个可能的三元组,每个数组生成 C(5,3)=10 个三元组。
为三元组准备一个(哈希)table 计数器,遍历数组更新计数器,select 个具有最大计数的三元组。
我已经完全检查了我的回复:
- **修复错误**:`array function computeRepettition(array $a);`
- **避免**如果已在 pass-1 中找到三元组,则重复增加
- **Return**一个数组的数组,每个三元组的重复次数在'**numberOfRepetition**'中设置,self中的三元组是数组的键
- **支持**2位及以上数字组成
- **新** `array function iCombination(array $a);` 减少找到三元组的概率,因为顺序不重要,并且不允许重复数字
- `array function detectRepetition(array $a);` 的**Update** 检测所有可以找到的三元组
<?php
define ("MIN_LENGTH_VECTOR" , 3 );
define ("KEY_SEPERATOR" , '-');
$src2D = array (
array(1,3,5,19,45,11,12,13,9, 100,31),
array(1,3,5,32,46,15,100, 12,18,29,37),
array(1222,32222,5,3222222,4622222,1522222,100, 12,182222,292222,372222));
var_dump (computeRepetition ($src2D));
function computeRepetition ($src2D) {
$repetition = array ();
for ($i=0 ; $i<count($src2D)-1 ; $i++) {
foreach ($repetition as &$rep) {
$rep['escape'] = TRUE;
}
for ($j=$i+1 ; $j<count($src2D) ; $j++) {
$t = buildTruth ($src2D[$i], $src2D[$j]);
$r = detectRepetition ($t);
if (is_null ($r)) continue;
$comb = iCombination ($r);
foreach ($comb as $cb) {
if (isset ($repetition[$cb]['escape']) && $repetition[$cb]['escape'] === TRUE) continue;
if (array_key_exists ($cb, $repetition)) {
$repetition[$cb]['numberOfRepetition']++;
} else {
$repetition[$cb]['numberOfRepetition'] = 2;
$repetition[$cb]['escape'] = FALSE;
}
}
}
}
return $repetition;
}
function detectRepetition ($t) {
$a = array ();
foreach ($t as $key => $value) {
if ($value === TRUE) {
$a[] = $key;
}
}
if (count($a) < MIN_LENGTH_VECTOR) return NULL;
return $a;
}
function iCombination ($array) {
$res = array ();
sort ($array, SORT_NUMERIC);
for ($i = 0 ; $i < count ($array) - 2 ; $i++) {
for ($k = $i + 1 ; $k < count ($array) - 1 ; $k++) {
for ($l = $k + 1 ; $l < count ($array) ; $l++) {
$res[] = $array[$i] . KEY_SEPERATOR . $array[$k] . KEY_SEPERATOR . $array[$l];
}
}
}
return $res;
}
function buildTruth ($vec1, $vec2) {
foreach ($vec1 as $v) {
$t[$v] = FALSE;
}
foreach ($vec2 as $v) {
if (isset ($t[$v]) && $t[$v] === FALSE ) $t[$v] = TRUE ;
}
return $t;
}