【问题标题】:Getting different output for same PHP code为相同的 PHP 代码获取不同的输出
【发布时间】:2014-07-19 19:43:13
【问题描述】:

(由于比赛结束,无法粘贴确切的问题,我无法访问该问题。抱歉。)

您好,最近我参加了一个编程竞赛(PHP)。我在我的 PC 上测试了代码并得到了所需的输出,但是当我在比赛网站和 ideone 上检查我的代码时,我得到了错误的输出。这是第二次发生同样的事情。相同的 PHP 代码,但输出不同。

它正在从命令行获取输入。目的是带上接触字符'A','B','C','a','b','c'的子串。

例如:将字符串“AaBbCc”视为 CLI 输入。 子串:A,a,B,b,C,c,Aa,AaB,AaBb,AaBbC,AaBbCc,aB,aBb,aBbC,aBbCc,Bb,BbC,BbCc,bC,bCc,Cc。

Total substrings: 21 这是正确的输出。

我的机器:

Windows 7 64 位 PHP 5.3.13(Wamp 服务器)

以下是代码:

<?php
$stdin = fopen('php://stdin', 'r');
    while(true) {
        $t = fread($stdin,3);
        $t = trim($t);
        $t = (int)$t;
        while($t--) {
            $sLen=0;
            $subStringsNum=0;
            $searchString="";
            $searchString = fread($stdin,20);
            $sLen=strlen($searchString);
            $sLen=strlen(trim($searchString));
            for($i=0;$i<$sLen;$i++) {
                for($j=$i;$j<$sLen;$j++) {                  
                    if(preg_match("/^[A-C]+$/i",substr($searchString,$i,$sLen-$j))) {$subStringsNum++;}
                }
            }
            echo $subStringsNum."\n";

        }
        die;
    }
?>

Input:
2
AaBbCc
XxYyZz

Correct Output (My PC):
21
0

Ideone/Contest Website Output:
20
0

【问题讨论】:

  • 代码的用途是什么?它正在读取文件,因此可能取决于服务器响应...
  • 它正在从命令行获取输入。输入必须是字符串。目的是查找包含字符 'A','B','C','a','b','c' 的子字符串。
  • 那么命令行参数是什么?您确定您给出的论点与竞赛网站相同吗?为什么不直接在$t = fread($stdin,3); 之后回显$t,看看它在本地机器和服务器上产生了什么。
  • 我在这里没有看到任何错误。第一件事 - 你为什么使用 PHP 4?第二个 - 你对 Ideone/Contest 测试环境了解多少?
  • 联系比赛负责人不是更方便吗?

标签: php


【解决方案1】:

您必须记住,您的代码也在处理换行符。

在 Windows 系统上,换行符由两个字符组成,转义表示为 \r\n

在包括 Linux 在内的 UNIX 系统上,仅使用 \n,而在 MAC 上则使用 \r

由于您依赖于标准输出,因此很容易受到这些架构差异的影响,即使它是一个文件,您也在创建文件句柄时使用标志 "r" 而不是 @987654327 来强制执行架构标准@,明确声明您不想以二进制安全模式读取文件。

您可以在this Ideone.com version of your code 中看到当您强制执行家庭系统使用的换行符时,那里的 PHP 脚本将如何给出预期的输出,而在this other version using UNIX newlines 中它给出了“错误”的输出。

我想你应该使用fgets() 来分别读取每个字符串,而不是fread(),然后trim() 在处理之前删除这些字符。

【讨论】:

  • 我使用 fgets() 而不是 fread() 并且我在 ideone 和我的 PC 上得到了正确的答案,但奇怪的是,当使用 fgets() 输入测试用例 ($t) ,在输入 $t 的输入后,我看到 '0' 作为输出。这仅在我的系统上不是ideone。另外,知道为什么 fgets() 有效而 fread() 无效吗?
  • 我忘了提到我没有对代码进行任何其他更改,而是用 fgets() 替换了 fread() 并且它正在工作。
  • “在 MAC 上他们使用 \r 代替” - 这已经过时了,现代 Mac OS 也是 UNIX。
【解决方案2】:

我试图分析这段代码,这就是我所知道的:

  1. 输入字符串似乎没有问题。如果有的话就不可能返回结果20

  2. 我认为循环没有任何问题,我通常使用预增量,但它根本不会影响结果

对我来说,导致意外结果的可能性只有两种:

  1. 其中一个循环迭代没有被执行——它可能只是最后一个内部循环(当$i == 5 然后$j == 5 因为这个循环只运行一次)所以它将匹配 21 之间的差异和 20.

  2. preg_match 不会在其中一次匹配此字符串(preg_match 的检查有 21 次,其中之一 - 可能最后一次不匹配)。

如果我必须选择,我会选择第一个可能的原因。如果我是你,我会联系概念作者并询问他们有关版本和测试其他代码的可能性。在这种情况下,最重要的是preg_match() 总共启动了多少次 - 20 或 21(使用简单的 echo 或额外的计数器会告诉我们)以及preg_match() 检查的字符串是什么。只有这样,您才能找出我认为此代码不起作用的原因。

如果您能在发现更多信息时将任何信息放在这里,那就太好了。

附言。当然我也得到了 21 的结果,所以很难说有什么问题

【讨论】:

    猜你喜欢
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 2018-01-29
    • 1970-01-01
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多