2013-04-04 2 views
1

Я хочу сравнить каждый элемент массива друг с другом.Как сравнить каждый элемент массива друг с другом?

$char=array();  
for($i=0;$i<=10;$i++) 
{ 
     $char[$i]=rand(0,35); 
} 

Я хочу сравнить каждый элемент массива $ char. Если есть какое-либо значение повторяется, чем это должно изменить значение и выбрать другое случайное значение, которое должно быть уникальным в массиве ..

ответ

7

В этом конкретном примере, где диапазон возможных значений очень мал, было бы лучше сделать это по-другому:

$allPossible = range(0, 35); 
shuffle($allPossible); 

// Guaranteed exactly 10 unique numbers in the range [0, 35] 
$char = array_slice($allPossible, 0, 10); 

Или с эквивалентной версии с помощью array_rand:

$allPossible = range(0, 35); 
$char = array_rand(array_flip($allPossible), 10); 

Если диапазон значений были больше, то этот подход был бы очень расточительно, и вы должны идти с проверкой на уникальность на каждой итерации:

$char = array(); 
for ($i = 0; $i < 10; ++$i) { 
    $value = null; 

    // Try random numbers until you find one that does not already exist 
    while($value === null || in_array($value, $char)) { 
     $value = rand(0, 35); 
    } 

    $char[] = $value; 
} 

Однако это вероятностный подход и может занять много времени, чтобы закончить в зависимости от результата rand (это будет особенно плохо, если количество значений, которое вы хотите, близко к числу все возможные значения).

Кроме того, если количество значений, которые вы хотите выбрать, довольно велико (скажем, более 50 или около того), то in_array может оказаться узким местом. В этом случае он должен быть быстрее, чтобы использовать ключи массива для проверки уникальности вместо значений, так как в поисках существования ключа постоянная время вместо линейного:

$char = array(); 
for ($i = 0; $i < 100; ++$i) { 
    $value = null; 

    // Try random numbers until you find one that does not already exist 
    while($value === null || array_key_exists($char, $value)) { 
     $value = rand(0, 1000); 
    } 

    $char[$value] = $value; 
} 

$char = array_values($char); // reindex keys to start from 0 
+0

Short and sweet +1 –

0

Чтобы изменить любое повторное значение случайной, вы должны перебрать массив дважды:

$cont= 0; 
foreach($char as $c){ 
    foreach($char as $d){ 
     if($c == $d){ 
      //updating the value 
      $char[$cont] = rand(0,35); 
     } 
    } 
    $cont++; 
} 

Но то, что я не знаю, если случайная величина может быть повторен. В таком случае это было бы не так просто.

+0

Это заменит * все * значения, потому что $ C и $ D может ссылаться на одно и то же значение в списке (например, первая позиция).Подумайте об этом;) Также имейте в виду, что каждое повторное значение означает сохранение первого члена значения, которое повторяется в более позднем члене. – hakre

0

Я взял этот код из PHP Manual page for rand()

<?php 
function uniqueRand($n, $min = 0, $max = null) 
{ 
    if($max === null) 
    $max = getrandmax(); 
    $array = range($min, $max); 
    $return = array(); 
    $keys = array_rand($array, $n); 
    foreach($keys as $key) 
    $return[] = $array[$key]; 
    return $return; 
} 
?> 

Эта функция генерирует массив, который имеет размер $ п, и вы можете установить минимальное и максимальное значения, как в рандов.

Таким образом, вы могли бы использовать его как

uniqueRand(10, 0, 35); 
+0

['getrandmax()'] (http://php.net/getrandmax) в качестве значения по умолчанию. получайте удовольствие, посетив кухню адов. Вместо этого нужно указать его. Также см. ['Shuffle()'] (http://php.net/shuffle). – hakre

0

Использование array_count_values() первой на $char массиве.

Впоследствии вы можете просто соединить все записи с более чем 1 и рандомизировать их. Вы должны продолжать проверять, пока все значения не равны 1 tho. Так как даже случайный может снова продублировать дубликат.

0

Я sugggest два параметра, чтобы сделать массив случайный:

<?php 
    $questions = array(1, 2, 3, 4, 5, ..., 34, 35); 
    $questions = shuffle($questions); 
    ?> 

после этого вы выбираете 10 лучших элементов.

0

вы можете попробовать этот код, чтобы заменить любое повторное значение.

for ($i = 0; $i < count($char); $i++) { 
    for ($n = 0; $n < count($char); $n++) { 
     if($char[$i] == $char[$n]){ 
      $char[$i] = rand(0,35); 
     } 
    } 
} 
0

Функция array_unique() получает все уникальные значения из массива, шпонкой их первого появления.

Функция array_diff() позволяет удалять значения из одного массива, находящегося внутри другого массива.

В зависимости от того, как вам нужно (или не иметь) результат ключа или порядок сохраненных ключей, вам нужно выполнить несколько шагов. Как правило, он работает в следующих параграфах (с примерами кода PHP):

В массиве у вас есть N элементы, из которых Nu уникальны.

$N = array(...); 
$Nu = array_unique($N); 

Число случайных элементов r вам нужно то, чтобы заменить дубликаты являются подсчет N минус отсчет Nu. Поскольку подсчет N обычно полезное значение, я также назначить его nc:

$nc = count($N); 
$r = $nc - count($Nu); 

Это делает r целое число в диапазоне от 0 до count(N) - 1:

  0 : no duplicate values/all values are unique 
      1 : one duplicate value/all but one value are unique 
      ... 
count(N) - 1 : all duplicate values/no unique value 

Таким образом, в случае, если вам нужно ноль случайные значения ($r === 0), результат $N. Это граничное условие является вторым самым простым результатом (первый простой результат - входной массив без членов).

Для всех остальных случаев вам нужны r случайные уникальные значения. В вашем вопросе вы пишете от 0 до 35. Однако это не может быть полная история. Представьте, что ваш входной массив имеет 36 дублированных значений, каждый номер в диапазоне от 0 до 35 дублируется один раз. Добавление случайных чисел из диапазона от 0 до 35 снова в массив приведет к созданию дубликатов снова - гарантировано.

Вместо этого я прочитал ваш вопрос, что вы просто ищете уникальные значения, которые еще не являются частью входного массива.

Таким образом, вы не только вам нужно r случайные значения (Nr), но они также не должны быть частью N или Nu до сих пор.

Для этого вам нужно только создать count(N) уникальные значения, удалить из них уникальные значения Nu, чтобы гарантировать, что ничто не дублирует значения в Nu. Поскольку это теоретический максимум, а не точное количество, которое необходимо, что массив используется для получения среза ровно r элементов из:

$Nr = array_slice(array_diff(range(0, $nc - 1), $Nu), 0, $r); 

Если вы хотите, чтобы эти новые значения будут добавлены перемешиваются в range(0, $nc - 1) упорядочен , вы можете сделать следующее:

shuffle($Nr); 

Это должно принести хаотичность вы , кажется попросить ваш вопрос обратно в ответ.

То, что сейчас оставляет вас с уникальными частями исходного массива $Nu и r новых значений в $Nr. Объединение обоих этих массивов даст вам результирующий массив, который игнорирует ключ => значение отношения (массив Переиндексирование):

array_merge($Nu, $Nr); 

Например с примерным array(3, 4, 2, 1, 4, 0, 5, 0, 3, 5) для $N, результат это дает это:

Array 
(
    [0] => 3 
    [1] => 4 
    [2] => 2 
    [3] => 1 
    [4] => 0 
    [5] => 5 
    [6] => 7 
    [7] => 9 
    [8] => 6 
    [9] => 8 
) 

Как видите, все уникальные значения (0-5) начинаются с новых значений (6-9). Исходные ключи не сохраняются, например. ключом значения 5 был 6 первоначально, теперь это 5.

Отношение или значение ключа => не сохраняются из-за array_merge(), оно переустанавливает числовые клавиши. Также рядом с уникальными номерами в Nr ключи также должны быть уникальными в массиве. Таким образом, для каждого нового номера, добавляемого к незанятым существующим номерам, необходимо использовать ключ, который был ключом для дублирующего номера. Для того, чтобы получить все ключи дублирующих номеров наборов ключей в исходном массиве уменьшается набором ключей всех для матчей дублирующих номеров (ключей в «уникальном массиве» $Nu):

$Kr = array_keys(array_diff_assoc($N, $Nu)); 

Существующего результат $Nr теперь можно вводить с помощью этих клавиш. Функция в PHP, чтобы установить все ключи массива является использование функции array_combine():

$Nr = array_combine($Kr, $Nr); 

Это позволяет получить результат с ключевыми => стоимостных отношений, сохраняемых с помощью накидной оператора массива (+):

$Nu + $Nr; 

, например, с $N из последнего примера, результат это дает это:

Array 
(
    [0] => 3 
    [1] => 4 
    [2] => 2 
    [3] => 1 
    [5] => 0 
    [6] => 5 
    [4] => 8 
    [7] => 6 
    [8] => 9 
    [9] => 7 
) 

Как теперь вы можете видеть, для значения 5 это ключ 6 было сохранено, а также для значения 0, который имел ключ 5 в исходном массиве, и теперь, а на выходе вместо ключа 4, как и в предыдущем примере ,

Однако, поскольку теперь ключи сохранены для первых вхождений исходных значений, порядок все еще изменяется: сначала все ранее уникальные значения, а затем все новые значения. Однако вы можете добавить новые значения. Для этого вам нужно получить порядок исходных ключей для новых значений. Это можно сделать путем сопоставления заказа по ключу и использования array_multisort() для сортировки на основе этого заказа.

Поскольку это требует прохождения через возвращаемые значения параметров, это требует дополнительных, временные переменные, которые я выбрал, чтобы ввести начиная с буквы V:

// the original array defines the order of keys: 
$orderMap = array_flip(array_keys($N)); 

// define the sort order for the result with keys preserved 
$Vt = $Nu + $Nr; 
$order = array(); 
foreach ($Vt as $key => $value) { 
    $order[] = $orderMap[$key]; 
} 

Затем делается сортировкой (здесь с сохранением ключи):

// sort an array by the defined order, preserve keys 
$Vk = array_keys($Vt); 
array_multisort($order, $Vt, $Vk); 

результат затем:

array_combine($Vk, $Vt); 

Опять с примерами значений сверху:

Array 
(
    [0] => 3 
    [1] => 4 
    [2] => 2 
    [3] => 1 
    [4] => 7 
    [5] => 0 
    [6] => 5 
    [7] => 8 
    [8] => 6 
    [9] => 9 
) 

Этот пример показывает выход красиво, что ключи упорядочены от 0 до 9, как они были хорошо во входном массиве. По сравнению с предыдущим выходом вы можете, например, увидеть, что первое добавленное значение 7 (keyed 4) находится на 5-й позиции - то же самое, что и значение 4 в исходном массиве. Также был получен порядок ключей.

Если это результат, к которому вы стремитесь, вы можете сократить путь к этому шагу, повторив исходные ключи массивов, и в случае, если каждый из этих ключей не является первым значением любого повторяющегося значения, вы можете поп от новых значений массива вместо:

$result = array(); 
foreach ($N as $key => $value) { 
    $result[$key] = array_key_exists($key, $Nu) ? $Nu[$key] : array_pop($Nr); 
} 

Опять примере массив значений результат (зависит от предыдущего, потому что $Nr перемешивается:

Array 
(
    [0] => 3 
    [1] => 4 
    [2] => 2 
    [3] => 1 
    [4] => 7 
    [5] => 0 
    [6] => 5 
    [7] => 8 
    [8] => 9 
    [9] => 6 
) 

Который в конце концов, может быть, самый простой способ ответить на ваши вопрос. Надеюсь, что эта помощь вы отвечаете на вопрос. Имейте в виду следующее:

  • разделите вашу проблему:
    1. вы хотите знать, является ли значение уникального мировоззрения или нет - array_unique() поможет вам здесь.
    2. Вы хотите создать X уникальные номера/значения. array_diff() помогает вам здесь.
  • выравнивание потока:
    1. получить уникальные номера в первую очередь.
    2. сначала получите новые номера.
    3. использовать как для обработки исходного массива.

как в этом примере:

// original array 
$array = array(3, 4, 2, 1, 4, 0, 5, 0, 3, 5); 

// obtain unique values (1.) 
$unique = array_unique($array); 

// obtain new unique values (2.) 
$new = range(0, count($array) - 1); 
$new = array_diff($new, $unique); 
shuffle($new); 

// process original array (3.) 
foreach ($array as $key => &$value) { 
    if (array_key_exists($key, $unique)) { 
     continue; 
    } 
    $value = array_pop($new); 
} 
unset($value, $new); 

// result in $array: 
print_r($array); 

Который затем (в качестве примера из shuffle($new)) выходы:

Array 
(
    [0] => 3 
    [1] => 4 
    [2] => 2 
    [3] => 1 
    [4] => 9 
    [5] => 0 
    [6] => 5 
    [7] => 8 
    [8] => 7 
    [9] => 6 
) 
Смежные вопросы