php - How can I avoid duplicate random three-word combinations from a table of words? -


i trying pull list of words database, create unique three-word combination in form $word1.$word2.$word3, , assign star.

i want avoid duplicate combinations - want each star have unique three-word identifier.

my current method involves creating array of possible three-word combinations , deleting each combination array once has been assigned star. intend, however, use few-thousand words in word list, means array contain tens of billions of combinations, method seems incredibly inefficient.

how can achieve more effectively? initial thoughts should loop through each star, create , assign three-word combination, add combo array, , each star, check if newly generated combo in array.

code

 <?php      // initiate connection database...     $db = mysqli_connect('localhost', 'root', '', 'stellar');      // query database of words     $words_sql = "select * words";     $words_res = mysqli_query($db, $words_sql)or die(mysqli_error());      // create array of words     $words = array();      // loop through each word database , add each array      while($row = mysqli_fetch_array($words_res)){          $words[] = $row['word'];     }      // create array of possible three-word combinations, randomly select our combinations      $triplets = array();     foreach ($words $word1){         foreach ($words $word2){             foreach($words $word3){                 if ($word1 !== $word2 && $word2 !== $word3 && $word1 !== $word3){                      $triplets[] = "$word1.$word2.$word3";                 }             }             }     }      // pull stars database     $stars_sql = "select * stars";     $stars_res = mysqli_query($db, $stars_sql)or die(mysqli_error());      // loop through every star in array     while($row = mysqli_fetch_array($stars_res)){          // store star name , star_id in variables          $star    = $row['star_name'];          $star_id = $row['star_id'];           // set $three_words random combination array of possible combinations...          $ran_num     = array_rand($triplets);          $three_words = $triplets[$ran_num];           // ...and remove particular combination, in order prevent repating combinations          array_splice($triplets, $ran_num, 1);           // attach random 3-word combination star           echo $star.'&nbsp;&nbsp;&nbsp;&nbsp;'.$three_words.'<br/><br/>';     } ?> 

there (possibly) minor tweak can make mysql of heavy lifting you.

$words_sql = "select concat(w1.word,'.',w2.word,'.',w3.word) triplet  (words w1 join words w2 on w1.word != w2.word)      join words w3 on w3.word != w1.word , w3.word != w2.word"; $words_res = mysqli_query($db, $words_sql)or die(mysqli_error());  // create array of words $words = array();  // loop through each word database , add each array  while($row = mysqli_fetch_array($words_res)){      $triplets[] = $row['triplet']; } 

this you're going because end of process you'll have assigned triplets star, means whether pre-generate triplets or generate them later, you'll end generating them anyway.

now there alternative solution case number of triplets much greater number of stars need name: have 2.5 million stars 2000 words (or 8 billion triplets). in case stars tiny fraction of possible triplets can following:

$words = array();  // loop through each word database , add each array  while($row = mysqli_fetch_array($words_res)){      $words[] = $row['word']; }  // pull stars database $stars_sql = "select * stars"; $stars_res = mysqli_query($db, $stars_sql)or die(mysqli_error());  // loop through every star in array $used = []; while($row = mysqli_fetch_array($stars_res)){      // store star name , star_id in variables      $star    = $row['star_name'];      $star_id = $row['star_id'];       {          //generate non-repeating triplet of words (sample without replacement?)          $word1 = array_rand($words);          {            $word2 = array_rand($words);          } while ($word2 == $word1);             {            $word3 = array_rand($words);          } while ($word3 == $word2 || $word1 == $word3);             $triplet = $words[$word1].".".$words[$word2].".".$words[$word3];      } while (isset($used[$triplet])); //try again if we've used it. unlikely.       $used[$triplet] = true; //keep track of we've used.         echo $star.'&nbsp;&nbsp;&nbsp;&nbsp;'.$triplet.'<br/><br/>';        }  

in second case, works because chance generate same triplet twice small because of possible number of triplets , fact we're using tiny fraction of them in total.


Comments