【问题标题】:PHP - Is there a better way to search a large string than with multiple IFsPHP - 有没有比使用多个 IF 更好的方法来搜索大字符串
【发布时间】:2017-09-18 14:18:08
【问题描述】:

我有一个名为$data 的变量正在存储大量数据。我知道数据将包含以下单词之一……cheesecrackersfruit。或者,它可能不包含这些词。现在,我正在这样做……

if (strpos($data,"cheese")!==false) $food="cheese";
else if (strpos($data,"crackers")!==false) $food="crackers";
else if (strpos($data,"fruit")!==false) $food="fruit";
else $food=”none”;

因此,如果找到奶酪,则仅搜索一次数据。如果没有找到奶酪,则再次搜索数据,因为它首先寻找奶酪,但没有找到,然后不得不再次搜索以寻找饼干。看到问题了吗?所以,如果没有找到食物,数据最终会被搜索 3 次,然后才最终设置食物变量(我是对的,它是这样工作的吗?)。

我想知道是否有更有效的搜索方式。我想到了一个可能的方法,但我不知道该怎么做…… 如果我像这样同时搜索所有三种食物会怎样……

if (strpos($data,"cheese")!==false or
strpos($data,"crackers")!==false or
strpos($data,"fruit")!==false)
$food=THE WORD THAT WAS FOUND GOES HERE

我希望能够将食物变量设置为找到的值。如果这是可能的,我是否正确地认为这会更快,因为您只搜索数据一次?还是 PHP 仍在搜索 3 次以查找每个项目?甚至可以将食物变量设置为找到的值吗?

【问题讨论】:

  • $data 是只包含单词还是包含其他单词?
  • 您的第二种方式实际上与第一种方式相同,因为它仍然调用strpos() 3 次。你确定做三遍真的有问题吗?速度明显慢吗?如果没有,微优化很少值得费心。
  • 您可以尝试使用preg_match()(cheese|crackers|fruit) 等匹配项,然后检查实际匹配的内容;但我不相信它会更快。

标签: php string variables if-statement search


【解决方案1】:

你为什么不使用数组呢?会更容易

$words = ["cheese","crackers","fruit"];
$food = null;
foreach ($words as $value){
    if (!$food && strpos($data, $value))
        $food = $value;
}

【讨论】:

  • 击败我,虽然这可能并没有真正更快,只是更有活力。微优化很少值得做,但我认为您的答案是比 OP 更好的解决方案
  • 这可能就是我要找的。这会减少搜索数据的次数吗?
  • 以目前的写法,这不会减少搜索数据的次数,我做了一个非常相似但涉及中断的答案,所以一旦找到搜索字符串不再检查数据变量
【解决方案2】:

最好的方法可能是使用数组:

$data = "cheese platter";
$toCheck = [
    "fruit",
    "crackers",
    "cheese"
];
$food = false;
foreach ($toCheck as $item){
    if (strpos($data, $item) !== false) {
        $food = $value;
        break;
    }
}`

【讨论】:

  • 赞成休息,让它可能稍微快一点
【解决方案3】:

这更简单。不一定更快。

$food = 'none';
if (preg_match('#(cheese|crackers|fruit)#', $data, $match)) {
    $food = $match[1];
}

【讨论】:

  • 我在这里看到了一些很好的答案,这可能是最好的。我担心的是,如果我的数据变量非常大,我不想一遍又一遍地搜索它来查找单词。我认为那会很慢。如果您的方法在一次数据搜索中查找所有单词,我认为它必须更快。我在这里看到的带有 for-each 循环的数组示例仍然会搜索多次。我可能会进行一些测试...谢谢
  • 我会说制作一些带有随机单词的巨大测试文件。然后将您的特殊单词放入其中并进行基准测试。除非您正在扫描非常大的字符串,否则您可能会发现它并没有您预期的那么慢。
  • @CheeseFlavored 你如何定义“非常大”?因为您很可能会担心对用户而言无关紧要的时差
  • 如果数据变量是通过 HTTP 发送的,传输它所花费的时间可能会比扫描它几次所花费的时间相形见绌。
  • 是的,我明白了,你说得对,在我的情况下可能无关紧要,但还有另一个因素需要考虑......在我的示例中,我只搜索了 3 个单词。如果我必须搜索数百个可能的单词怎么办。然后数据可能需要搜索 100 次才能找到。根据数据的大小和搜索次数,我认为在某些时候会出现减速。
【解决方案4】:

结果证明这是一个有趣的实验。我使用 IF 语句对我的原始方法进行了一些计时测试,然后使用 Jammy 和 Jason 发布的数组方法,然后使用 Daren 发布的 preg_match 方法。我很惊讶。无论您使用什么方法,PHP 都非常快。我创建了一个名为 $data 的变量,它有 1meg 长,可以搜索 10 个单词中的任何一个。当没有找到单词时,我得到了这个平均时间......

If_method = 0.01 seconds
Array_Method = 0.006 seconds
Preg_match = 0.1 seconds

因此,即使在循环所有数据 10 次之后,IF 和数组循环至少比 preg 匹配快 10 倍,但 Pregmatch 仍然会在你眨眼之前完成。

【讨论】:

  • 需要记住的一点,对于预匹配,您每次想要更改它时都必须将项目添加到列表中,使用数组您可以从其他地方拉它而不必担心更改你的逻辑:)
【解决方案5】:

这将为您提供单词的所有位置

$data = explode(' ', $data); 
$words= array('cheese', 'fruit', 'crackers');
var_dump(array_intersect($data, $words)); 

然后你可以根据结果影响食物。

【讨论】:

  • 你怎么知道单词是用空格隔开的?
  • 他的数据是一个字符串,我在这里做了一个分隔符''他可以选择他有的任何分隔符。
  • 我知道你在做什么,但给出的信息无法证明它的格式,但是例如说列表中有“葡萄柚”,那么这不会是一种水果可能是个问题,或者如果格式类似于“Apple-fruit”,它将无法正常工作
猜你喜欢
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-11
  • 1970-01-01
相关资源
最近更新 更多