如何更有效地循环此过程

时间:2014-03-04 00:50:26

标签: php computer-science

我写了一个小脚本来为我自动化一些计算。这很简单。 1 * 3 = 3 2 * 3 = 6 3 * 3 = 9,依此类推。当答案(产品)长度超过一位数时,我希望它添加答案的数字。 3 * 4 = 12 || 1 + 2 = 3。 我想让它自动添加答案,如果它超过一位数,无论多少次添加答案到达大于一位数。 当你达到13 * 3 = 39 ||时3 + 9 = 12 || 1 + 2 = 3 目前我的代码没有循环,我无法弄清楚如何在这里循环。

http://screencast.com/t/MdpQ9XEz

此外,它不会超过2位数的答案,请参阅34 * 3 = 102。任何帮助,以允许它无限添加将是伟大的。 生成每一行时,答案会变大,所以它应该在答案中添加尽可能多的数字。

这是我的代码:

$i = 1; //Start with one
function count_digit($number) {
    return strlen((string) $number);
};
 while($i < 500){
    $product = $i * 3; //Multiply set
    $number_of_digits = count_digit($product); //calls function to count digits of $sum

        if($number_of_digits > 1){  //if $sum has more than one digit add the digits together
        $addproduct = strval($product);//seperates the digits of $sum
        $ii = 0;

        while($ii <= $number_of_digits -1){
            $io = $ii + 1;
            if($io < $number_of_digits){
                $one = intval($addproduct[$ii]);
                $two = intval($addproduct[$io]);
                $sum = $one + $two;
                print($i . ' * 3 = ' .$product. ' || ' .$one. ' + ' .$two. ' = ' .$sum. '<br>');
            };$ii++;
        };

    }else{
        Print ($i . ' * 3 = ' .$product.'<br>'); //Print Set
    };
$i++; //add one

}

2 个答案:

答案 0 :(得分:0)

首先,您可以将$i=1while ...$i++替换为一个语句:for ($i=0; $i<500; $i++) {.... - 有关for的更多信息,请参阅http://nz1.php.net/manual/en/control-structures.for.php循环。它实际上是相同的代码,但将三个部分(初始化,测试,增量计数器)保持在一起;它清楚地表明它们是相关的,并且更快理解。

接下来我会将数字的转换替换为字符串,看看字符串的长度是否大于等等......用:

while ($product>10) {
   $out=0;
   while ($product) {
       $out+=$product%10;
       $product=(integer)($product/10);
   }
   $product=$out;
}

请注意,我在任何时候都不会将数字视为字符串 - 我尽可能避免使用。

如果您不熟悉它,$something+=$somethingelse$something=$sometime+$somethingelse相同,只是简写。 $ out是运行总计,每次围绕内循环(而$ product),$ out增加最右边的数字(一列):$out+=$product%10 - 有关详细信息,请参阅http://nz2.php.net/operators.arithmetic,然后$ product除以10并转换为整数,因此12变为1.2,然后是1,删除最右边的数字。

每次内循环完成($ product的所有数字都用完,$ product为0),结果($ out)被复制到$ product,然后你回到外循环(看看所有这些数字的总和现在是否小于10)。

同样重要的是你在每个循环中的确切位置。第一部分,乘法,立即在'500'循环; '||'每次'$ product'减少到'$ out'时发生一次;数字的添加发生在最里面的循环内,除了第一个数字之外,每个数字之前都加上“+”,或者除了最后一个数字之外的每个数字之后。由于“除了最后一个之外的所有内容”更容易计算($ product&gt; = 10,请注意那些边缘情况!),我选择了那个。

另请注意,由于我将数字从右向左添加,而不是从左向右添加,因此添加相反。我不知道这是不是一个问题。始终考虑是否撤销订单将为您节省大量工作。显然,如果他们需要按特定顺序完成,那么这可能是一个问题。

结果是:

 for ($i=0; $i<500; $i++) {
     $product = $i * 3; //Multiply set
     print ($i . ' * 3 = ' .$product);
     while ($product>10) {
         print ' || ';
         $out=0;
         while ($product>0) {
             print ($product%10);
             if ($product>=10) {
                 print " + ";
             }
             $out+=$product%10;
             $product=(integer)($product/10);
         }
         $product=$out;
         print(' = ' .$product);
      }
      print "<br>";
  };

答案 1 :(得分:0)

我决定将此作为单独的答案添加,因为它使用不同的方法来回答您的问题:解决问题的最少量更改,而不是以易于阅读的方式重写代码。

您的代码存在两个问题,需要两个单独的修复程序。

问题1:您的代码未正确添加3位数(或更多)数字。

如果仔细查看代码,您会发现自己正在添加数字对($one$two);每次添加一对数字时,都会将其打印出来。这意味着,对于数字102,您要添加10,打印结果,然后添加02并将其打印出来。仔细查看结果,您会看到102出现两次!

解决这个问题的一种方法是使用$ 3和$ 4(4位数就足够500 * 3)。这不是一个好的编程,因为如果你以后需要5位数,你需要和$ 5,等等。

对此进行编程的方法是从零$sum开始,然后遍历每个数字,并将其添加到总和中,因此:

    $ii = 0;
    $sum = 0;

    while($ii <= $number_of_digits - 1){
        $one = intval($addproduct[$ii]);
        $sum = $sum + $one;
        $ii++;
    }
    print($i . ' * 3 = ' .$product. ' || ' . $sum . '<br>');
    };

内部if当然消失了,因为它与我们不再使用的$ io有关。

当然,现在你在添加它们时失去了打印个别数字的能力。如果你想要那些,并且因为我们事先不知道有多少,你将不得不记录它们。字符串适合于此。我将如何做到这一点:

    $ii = 0;
    $sum = 0;
    $maths = "";

    while($ii <= $number_of_digits-1){
        $one = intval($addproduct[$ii]);

        if ($maths=="") {
            $maths=$one;
        } else {
            $maths=$maths . " + " .$one;
        }

        $sum = $sum + $one;
        $ii++;
    }
    print($i . ' * 3 = ' .$product. ' || ' . $maths . " = " . $sum . '<br>');
    };

注意带有$ math的行;顶部有一个,将其设置为空字符串。然后,一旦我们确定了要添加的数字,我们就将其添加到$ maths中。第一轮是特殊情况,因为我们在第一个数字之前不想要“+”,所以我们会例外 - 如果$maths为空,我们将其设置为$one;循环后来,它不是空的,所以我们添加“+”。 $酮;

问题2:如果添加的结果超过1位数,请再次转向。再次,根据需要多次。

此时我建议进行一些重构:我会将print语句分成几个部分。首先是乘法 - 在实际乘法之后立即可以很容易地移到顶部。打印<br>可以在$i++之前结束。这也意味着您不再需要else子句 - 它已经完成了。这只留下' || ' . $maths . " = " . $sum。每次进行添加都会发生这种情况。

现在,将您的if($number_of_digits...替换为while($number_of_digits...;这意味着它会根据需要经历多次,如果它为零或100.这意味着您将需要在循环结束时使用$product更新$product = $sum; - put这在印刷声明之后立即生效。您还需要更新$number_of_digits;将行从顶部复制到循环结束。

如果你一直在跟随,你应该:

$i = 1; //Start with one
function count_digit($number) {
    return strlen((string) $number);
};
 while($i < 500){
    $product = $i * 3; //Multiply set
    print($i . ' * 3 = ' .$product); // Print basic multiplication
    $number_of_digits = count_digit($product); //calls function to count digits of $sum

        while ($number_of_digits > 1){  //if $sum has more than one digit add the digits together
        $addproduct = strval($product);//seperates the digits of $sum
    $ii = 0;
    $sum = 0;
    $maths = "";

    while($ii <= $number_of_digits-1){
        $one = intval($addproduct[$ii]);

        if ($maths=="") {
            $maths=$one;
        } else {
            $maths=$maths . " + " .$one;
        }

        $sum = $sum + $one;
        $ii++;
    }
    print(" || " . $maths . " = " . $sum ); // print one lot of adding
    $product=$sum;
    $number_of_digits = count_digit($product); //calls function to count digits of $sum
    };
    Print ("<br>"); //go to next line
$i++; //add one
}