Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 计算字符中的可能性。使用连续重复标准的组合_Php_Algorithm_Math_Combinatorics - Fatal编程技术网

Php 计算字符中的可能性。使用连续重复标准的组合

Php 计算字符中的可能性。使用连续重复标准的组合,php,algorithm,math,combinatorics,Php,Algorithm,Math,Combinatorics,在PHP中,给定 最后的字符串长度 它可以使用的字符范围 可能的最小连续重复计数 您如何计算符合这些标准的匹配数?要更好地描述 $range = array('a','b','c'); $length = 2; // looking for 2 digit results $minRep = 2; // with >=2 consecutive characters // aa,bb,cc = 3 possibilities 另一个: $range = array('a','b','

在PHP中,给定

  • 最后的字符串长度
  • 它可以使用的字符范围
  • 可能的最小连续重复计数
您如何计算符合这些标准的匹配数?
要更好地描述

$range = array('a','b','c');
$length = 2; // looking for 2 digit results
$minRep = 2; // with >=2 consecutive characters
// aa,bb,cc = 3 possibilities
另一个:

$range = array('a','b','c');
$length = 3; // looking for 3 digit results
$minRep = 2; // with >=2 consecutive characters
// aaa,aab,aac,baa,caa
// bbb,bba,bbc,abb,cbb
// ccc,cca,ccb,acc,bcc
// 5 + 5 + 5 = 15 possibilities
// note that combos like aa,bb,cc are not included
// because their length is smaller than $length
最后一个:

$range = array('a','b','c');
$length = 3; // looking for 3 digit results
$minRep = 3; // with >=3 consecutive characters
// aaa,bbb,ccc = 3 possibilities
因此,基本上,在第二个例子中,第三个标准使它在aab中捕捉到了[aa]b,因为a连续重复了不止一次,而[a]b[a]不会匹配,因为那些a是分开的


不用说,没有一个变量是静态的。

我认为最好用数学来处理这个问题

$range = array('a','b','c');
$length = 3; // looking for 3 digit results
$minRep = 2; // with >=2 consecutive characters

$rangeLength = count($range);
$count = (pow($rangeLength,$length-$minRep+1) * ($length-$minRep+1)) - ($rangeLength * ($length-$minRep)); // is the result
现在,$count得到了三种情况的真实结果。但这可能不是一般公式,需要改进

试着解释一下:

pow($rangeLength,$length-$minRep+1)
在本例中,我们将重复字符计算为一个。例如,在你们给出的第二个例子中,我们认为在aab中,aa是一个字符。因为,两个字符需要一起更改。我们认为现在有两个字符像xy。因此,字符a、b和c都有相同的可能性,即两个字符的3($rangeLength)可能值($length-$minRep+1)。因此,对于第二个例子,3^2=9是可能的情况

我们计算9只代表xy而不是yx。为此,我们乘以xy的长度($length-$minRep+1)。然后我们有18个

似乎我们计算了结果,但我们的计算有重复。我们没有考虑这种情况:xy=>aaa和yx=>aaa。为此,我们计算并减去重复结果

- ($rangeLength * ($length-$minRep))
在这之后,我们得到了结果。
正如我在描述的开头所说,这个公式可能需要改进。

对于数学,工作变得非常复杂。但是,总有一种方法,即使没有数学那么漂亮。我们可以使用php创建所有可能的字符串,并使用regexp控制它们,如下所示:

$range = array('a','b','c');
$length = 3; 
$minRep = 2; 

$rangeLength = count($range);

$createdStrings = array();
$matchedStrings = array();

function calcIndex(){
    global $range;
    global $length;
    global $rangeLength;

    static $ret;

    $addTrigger = false;

    // initial values
    if(is_null($ret)){ 
        $ret = array_fill(0, $length, 0);
        return $ret;
    }

    for($i=$length-1;$i>=0;$i--){
        if($ret[$i] == ($rangeLength-1)) {
            if($i==0) return false;
            $ret[$i] = 0;
        }
        else {
            $ret[$i]++;
            break;
        }
    }

    return $ret;
}

function createPattern()
{
    global $minRep;
    $patt = '/(.)\\1{'.($minRep-1).'}/';
    return $patt;
}

$pattern = createPattern();


while(1) 
{
    $index = calcIndex();
    if($index === false) break;

    $string = '';
    for($i=0;$i<$length;$i++)
    {
        $string .= $range[$index[$i]];
    }

    if(!in_array($string, $createdStrings)){ 
        $createdStrings[] = $string;
        if(preg_match($pattern, $string)){
            $matchedStrings[] = $string;
        }
    }
}

echo count($createdStrings).' is created:';
var_dump($createdStrings);

echo count($matchedStrings).'strings is matched:';
var_dump($matchedStrings);
$range=array('a','b','c');
$length=3;
$minRep=2;
$rangeLength=计数($range);
$createdStrings=array();
$matchedStrings=array();
函数CANCINDEX(){
全球美元范围;
全球美元长度;
全球$rangeLength;
静态$ret;
$addTrigger=false;
//初始值
如果(是null($ret)){
$ret=数组填充(0,$length,0);
返回$ret;
}
对于($i=$length-1;$i>=0;$i--){
如果($ret[$i]==($rangeLength-1)){
如果($i==0),则返回false;
$ret[$i]=0;
}
否则{
$ret[$i]++;
打破
}
}
返回$ret;
}
函数createPattern()
{
全球$minRep;
$patt='/(..\\1{'($minRep-1)。'}/';
返回$patt;
}
$pattern=createPattern();
而(1)
{
$index=calcIndex();
如果($index==false)中断;
$string='';

因为($i=0;$i得到了它。这一切都归功于leonbloy

/*主函数计算不包含
*长度为$minRep(或更多)的字符重复*/
函数countStrings($rangeLength、$length、$minRep、&$results=array())
{
如果(!isset($results[$length]))
{
$b=0;
如果($length<$minRep)
$b=功率($rangeLength,$length);
其他的
{
对于($i=1;$i<$minRep;$i++)
$b+=CountString($rangeLength,$length-$i,$minRep,$results);
$b*=$rangeLength-1;
}
$results[$length]=$b;
}
返回$results[$length];
}
/*这一个直接回答了这个问题*/
函数printNumStringsRep($rangeLength,$length,$minRep)
{
$n=(pow($rangeLength,$length)
-CountString($rangeLength,$length,$minRep));
echo“字母表大小:$rangeLength
” “字符串大小:$length
” “最小重复次数:$minRep
” .“字数:$n”; } /*印刷品: * 字母表大小:3 字符串大小:3 最少重复次数:2次 字数:15 * */ printNumStringsRep(3,3,2);
字符是否总是按字母顺序连续?是否应该将
$maxRep
命名为
$minRep
?这似乎更像是一个数学问题。@nickb没有。$maxRep实际上定义了最大可能的连续重复次数。同样,第一个问题的另一个“否”。字符不是静态的,所以它们可以是
 a、X、b以及
r1R
。我们只知道它们在提供的$range数组中是唯一的。不,不是。在第一个示例中,
$maxRep=1;
,您将其描述为“具有>1个连续字符”,并给出“aa”作为可能的解决方案。如果
$maxRep
定义了“最多可能连续重复”,那么“aa”不可能是一个有效的解决方案-它有两次重复。@inhan我会在上问这个问题,看看它从哪里来。谢谢你的解释。我正在考虑它-它是否需要调整。不起作用。对于
$range=array('a','b')),$length=5,$minRep=2
返回58,大于
$range
$length
定义的集合大小(32).@Amine是的,你是对的。重复结果的计算有问题。@Bilal你的尝试很好,但有太多重复场景需要考虑,我怀疑只有重组合数学才能解决这个问题。我已经将此标记为书签,因为我对知道正确答案非常感兴趣。创造所有的可能性听起来不太可能因为你可以有,比如说32位数字。首先生成所有的可能性(32位的大写27个基本拉丁字符范围为6.3626854411359E+45),然后使用
RegExp
,需要相当长的时间(并消耗惊人的内存量)。对数字稍加更正(我没有明确地数字母表):1.901722472685e+45我不知道有一个叫做mathexchange的东西。谢谢你。我正在努力理解
/* The main function computes the number of words that do NOT contain
 * a character repetition of length $minRep (or more). */
function countStrings($rangeLength, $length, $minRep, &$results = array())
{
  if (!isset($results[$length]))
  {
    $b = 0;

    if ($length < $minRep)
      $b = pow($rangeLength, $length);
    else
    {
      for ($i = 1; $i < $minRep; $i++)
        $b += countStrings($rangeLength, $length - $i, $minRep, $results);
      $b *= $rangeLength - 1;
    }

    $results[$length] = $b;
  }

  return $results[$length];
}

/* This one answers directly the question. */
function printNumStringsRep($rangeLength, $length, $minRep)
{
  $n = (pow($rangeLength, $length) 
            - countStrings($rangeLength, $length, $minRep));
  echo  "Size of alphabet : $rangeLength<br/>"
        . "Size of string : $length<br/>"
        . "Minimal repetition : $minRep<br/>"
        . "<strong>Number of words : $n</strong>";
}

/* Prints :
 * 
   Size of alphabet : 3
   Size of string : 3
   Minimal repetition : 2
   Number of words : 15
 *
 */
printNumStringsRep(3, 3, 2);