生成26(A-Z)* 26(A-Z)* 26(A-Z)的功能

时间:2010-07-22 03:36:52

标签: php math function

我想创建一个函数,在每次循环后生成一个3字符串字符串。

字母表中有26个字符,我想生成完全独特的3个字符键(A-Z)。

输出将是17,576个唯一的3个字符键(A-Z) - 不区分大小写。

任何人都可以告诉我如何在不随机生成密钥和检查重复密钥的情况下创建更优雅的功能吗?

是否可能

谢谢。

4 个答案:

答案 0 :(得分:9)

如果我正确地阅读了你的问题,你想要一个函数返回“ABC”形式的键,其中每个字母是随机选择的,但是相同的字母组合永远不会发出两次。

您的意思是从未执行过两次代码或从未发出两次“永远”吗?

无论哪种方式,我都会考虑生成所有可能的组合,对它们进行混洗,然后根据您的需要将它们存储在成员数组或文件/数据库中。您还需要存储一个索引,每次发出密钥时都会增加该索引。

<?php
  private $keys = array();
  private $keyIndex = -1;

  function generateKeys()
  {
      $this->keys = array();
      $this->keyIndex = -1;

      for ($i=1; $i<=26; $i++)
      {
         for ($j=1; $j<=26; $j++)
         {
            for ($k=1; $k<=26; $k++)
            {
                $this->keys[] = sprintf('%c%c%c', 64+$i, 64+$j, 64+$k);
            }
         }
      }

      shuffle($this->keys);

      return $this->keys;
  }

  function getKey()
  {
      $this->keyIndex++;
      return $this->keys[$this->keyIndex];
  }

?>

答案 1 :(得分:2)

var使用任何数学库生成0到26立方的随机数 - 1,然后根据该随机整数的值分配字母......

在下文中,反斜杠表示整数除法,即丢弃任何小数余数

第一个字符= ascii(65 +整数模数26)
 第二个字符= ascii(65 +(整数\ 26)模数26
 第三个字符= ascii(65 +((整数\ 26)\ 26)模数26

啊,对@Graphain来说,我意识到你想要消除任何再次挑选相同三个角色组合的机会......那么这是一种方式......

  1. 创建一个包含676(26 * 26)个32位整数的集合(List?),全部初始化为2 ^ 26-1(所以0-25位都设置为1)。将这些整数中的26个放入26个内部词典中的每一个中,这样就成了26个词典的字典,每个词典都有26个这样的整数。标记内部词典A-Z。在每个内部数组中,标记整数A-Z。
  2. 随机选择26个外部数组中的一个(这将设置第一个字符)。
  3. 从所选的数组中随机选择其中一个包含的内部数组。这将设置第二个字符。
  4. 然后随机选择一个从0到n的数字,(其中n是整数中仍然设置为1的位数)...数字中的哪一位确定最后一个字符。
  5. 将该位设置为零
  6. 如果整数中的所有位都设置为零,则从数组中删除整数
  7. 如果此内部数组现在为空,(所有整数都消失了)将其从外部数组中删除。
  8. 从第2步开始重复,直到外部阵列为空或者你累了......
  9. 这是一些示例代码(未经测试):

     public class RandomAlphaTriplet
     {
        private static readonly Dictionary<char, Dictionary<char, int>> vals =
             new Dictionary<char, Dictionary<char, int>>();
        const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        private static readonly Random rnd = new Random(DateTime.Now.Millisecond);
    
        private const int initVal = 0x3FFFFFF;
        static RandomAlphaTriplet()
        {
            foreach (var c in chars)
                vals.Add(c, chars.ToDictionary(
                    ic => ic, ic => initVal));
        }
        public static string FetchNext()
        {
            var c1 = chars[rnd.Next(vals.Count)];
            var inrDict = vals[c1];
            var c2 = chars[rnd.Next(inrDict.Count)];
            var intVal = inrDict[c2];
            var bitNo = rnd.Next(BitCount(intVal));
            var bitPos = 0;
            while (bitNo > 0)
            {
                if ((intVal & 0x0001) > 0) bitNo--;
                bitPos++;
                intVal <<= 1;
            }
            var c3 = chars[bitPos];
            inrDict[c2] &= ~(1 << bitPos);
            if (inrDict[c2] == 0) inrDict.Remove(c2);
            if (vals[c1].Count == 0) vals.Remove(c1);
            return string.Concat(c1, c2, c3);
        }
        private static int BitCount(int x)
        { return ((x == 0) ? 0 : ((x < 0) ? 1 : 0) + BitCount(x << 1)); }
    } 
    

答案 2 :(得分:0)

如果你感兴趣,我可以只用一把钥匙。 (我不知道是否有可能没有密钥来检查重复)。

function getAlpha($Index) {
    $Alphabets = 'abcdefghijklmnopqrstuvwxyz';
    $Char      = substr($Alphabets, $Index, 1);
    return $Char;
}
function getRandom($Index) {
    $RandOne    =  $Index          % 26;
    $RandTwo    = ($Index / 26   ) % 26;
    $RandThree  = ($Index / 26*26) % 26;
    $AlphaOne   = getAlpha($RandOne);
    $AlphaTwo   = getAlpha($RandTwo);
    $AlphaThree = getAlpha($RandThree);
    $Rand = $AlphaOne.$AlphaTwo.$AlphaThree;
    return $Rand;
}
$Rands = array();
function getRandom() {
    global $Rands;
    while (true) {
        $RandNum = rand(0, 26*26*26 - 1);
        if (isset($Rands[$RandNum]))
            continue;
        $Rand            = getRandom($RandNum);
        $Rands[$RandNum] = $Rand;
        return $Rand;
    }
}

这只需要一个键来查找。

希望这有帮助。

答案 3 :(得分:0)

Ehrm这不是“简单”的组合数学吗? (选择26个中的3个的所有组合?或26个中的3个的排列?)