【问题标题】:An odd assignment about adding dashes to strings. PHP关于向字符串添加破折号的奇怪任务。 PHP
【发布时间】:2012-10-03 23:59:17
【问题描述】:

我需要一个可以执行以下操作的函数:

如果我有一个像 "2 1 3 6 5 4 8 7" 这样的字符串,我必须按照一些规则在成对的数字之间插入破折号。

规则很简单。

如果第一个数字小于后面的数字,则在两个数字之间添加一个破折号。做所有可能的组合,如果一对已经有破折号,那么它旁边的空格就不能有破折号。

基本上我对上述字符串的结果是

2 1-3 6 5 4 8 7
2 1-3 6 5 4-8 7
2 1 3-6 5 4 8 7
2 1 3-6 5 4-8 7
2 1 3 6 5 4-8 7

我确实创建了一个函数来执行此操作,但我认为它非常缓慢,我不想用它来污染您的想法。如果可能的话,我想知道你们是怎么想的,甚至一些伪代码或代码也会很棒。

编辑 1: 这是我到目前为止的代码

$string = "2 1 3 6 5 4 8 7";

function dasher($string){
   global $dasherarray;
   $lockcodes = explode(' ', $string);

   for($i = 0; $i < count($lockcodes) - 1; $i++){
      if(strlen($string) > 2){
         $left = $lockcodes[$i];
         $right = $lockcodes[$i+1];
         $x = $left . ' ' . $right;
         $y = $left . '-' . $right;
         if (strlen($left) == 1 && strlen($right) == 1 && (int)$left < (int)$right) {
            $dashercombination = str_replace($x, $y, $string); 
            $dasherarray[] = $dashercombination;
            dasher($dashercombination);
         }
      }
   }
   return array_unique($dasherarray);
}

foreach(dasher($string) as $combination) {
   echo $combination. '<br>';
}

【问题讨论】:

  • 请向我们展示您已经完成的工作并解释您认为其中有什么问题。不要害怕“用它来玷污我们的想法”,这里有足够经验的人来确保这样的事情不会发生。但是 - 我们确实喜欢看到提问者的努力,这给了我们动力,他们确实自己尝试过(而不是问陌生人作为解决问题的第一次尝试),并且答案更有可能对你更好 - 因为它将引导您找到解决方案。
  • 我认为它的错误在于我想避免递归并且可能不调用 str_replace。我尝试用 $string[($*2)-1] = '-' 简单地替换 str_replace ,但我没有得到预期的结果。
  • 我编辑了条目 amit。感谢您查看此内容。

标签: php string recursion replace


【解决方案1】:

也许这有助于提供不同的方法来解析字符串。

$str="2 1 3 6 5 4 8 7";
$sar=explode(' ',$str);
for($i=1;$i<count($sar);$i++)
  if($sar[$i-1]<$sar[$i])
    print substr_replace($str,'-',2*($i-1)+1,1) . "\n";

请注意,代码只需要字符串中的单个数字。

请注意,代码期望字符串按照您的示例进行格式化。最好添加一些完整性检查(折叠多个空格,在开始/结束处去除/修剪空白)。

我们可以通过查找字符串中的所有空格并使用它们来索引子字符串进行比较来改进这一点,仍然假设只有一个空格分隔相邻的数字。

<?php
$str="21 11 31 61 51 41 81 71";
$letter=' ';
#This finds the locations of all the spaces in the strings
$spaces = array_keys(array_intersect(str_split($str),array($letter)));

#This function takes a start-space and an end-space and finds the number between them.
#It also takes into account the special cases that we are considering the first or 
#last space in the string
function ssubstr($str,$spaces,$start,$end){
    if($start<0)
        return substr($str,0,$spaces[$end]);
    if($end==count($spaces))
        return substr($str,$spaces[$start],strlen($str)-$spaces[$start]);
    return substr($str,$spaces[$start],$spaces[$end]-$spaces[$start]);
}

#This loops through all the spaces in the string, extracting the numbers on either side for comparison
for($i=0;$i<count($spaces);$i++){
    $firstnum=ssubstr($str,$spaces,$i-1,$i);
    $secondnum=ssubstr($str,$spaces,$i,$i+1) . "\n";
    if(intval($firstnum)<intval($secondnum))
        print substr_replace($str,'-',$spaces[$i],1) . "\n";
}

?>

注意显式转换为整数以避免字典比较。

【讨论】:

  • 字符串不能超过 8 位,数字不能超过 8。数字在初始字符串中用空格分隔,但在我的示例中,辅助生成的字符串已经可以包含破折号。您创建的第一个代码示例没有提供正确的解决方案。如果您查看我发布的示例结果,则同一字符串中可能存在双对。
  • 任何时候有人说“规则很简单”,你几乎可以打赌,事实并非如此。 @user1743071,您正在对我制定更多规则!我会建议将这些作为处理字符串的替代方法,但您仍然需要找到最终解决问题的方法。
  • 嗯,他们写作业时在纸上很简单 :) 否则我会分享你对“简单规则”的看法。我上面的功能或多或少都可以,我真的希望消除 str_replace 并以某种方式更好地完成那部分。甚至避免递归(我仍在努力)
  • 感谢您查看此 Richard,我会看看是否可以应用您的想法来改进我的。
猜你喜欢
  • 2011-03-27
  • 1970-01-01
  • 2014-12-08
  • 2021-04-02
  • 2015-12-24
  • 1970-01-01
  • 1970-01-01
  • 2015-07-26
  • 2021-07-01
相关资源
最近更新 更多