views:

317

answers:

1

I created this function and it works on small strings, but for longer strings it times-out. I'm looking for a way to make the function work faster and not timeout, or a better way to accomplish what I want.

function find_diffs($string1, $string2)
{
    $array1 = preg_split("/\b/", $string1);
    $array2 = preg_split("/\b/", $string2);
    $array3 = array();


    for($i=0, $j=0; $i < count($array1) || $j < count($array2); $i++, $j++)
    {
     while(badchars($array1, $i))
     {
      $i++;
     }
     while(badchars($array2, $j))
     {
      $j++;
     }

     if($array1[$i] != $array2[$j])
     {
      //-------------------------Find Subtractions--------------------//
      $k = $i;
      while($array1[$i] != $array2[$j])
      {
       $i++;
       if($i == count($array1))
       {
        $end = true;
        break;
       }
       while(badchars($array1, $i))
       {
        $i++;
       }
      }
      if($end)
      {
       //-------------------------Find Additions--------------------//
       $end = false;
       $i = $k;
       $k = $j;
       while($array1[$i] != $array2[$j])
       {
        $j++;
        if($j == count($array2))
        {
         $end = true;
         break;
        }
        while(badchars($array2, $j))
        {
         $j++;
        }
       }
       if($end)
       {
        //-------------------------Find Changes--------------------//
        $end = false;
        $j = $k;
        $l = $i;
        while($array1[$i] != $array2[$j])
        {

         $k = $j;
         while($array1[$i] != $array2[$j])
         {
          $j++;
          if($j == count($array2))
          {
           $end = true;
           break;
          }
          while(badchars($array2, $j))
          {
           $j++;
          }
         }

         if($end)
         {
          $j = $k;
          $i++;
          while(badchars($array1, $i))
          {
           $i++;
          }
          while(badchars($array2, $j))
          {
           $j++;
          }
         }
         else
         {
          $array3[] = array($l,$i,'-');
          $array3[] = array($k,$j,'+');
         }
         if($i == count($array1))
         {
          $end = true;
          break;
         }
         if($j == count($array2))
         {
          $end = true;
          break;
         }
         $end=false;
        }
        if($end)
        {
          break;   
        }
        else
        {
         $array3[] = array($l,$i,'-');
         $array3[] = array($k,$j,'+');
        } 
        //---------------------End Find Changes--------------------//
       }
       else
       {
        $array3[] = array($k,$j,'+');
       }
      }
      else
      {
       $array3[] = array($k,$i,'-');
      }

     }
    }

    $array3[] = array(0,count($array1),'=');
    return array($array1,$array2,$array3);
}
+5  A: 

Don't reinvent the wheel. This is the sort of thing that is easy to get wrong and hard to get right.

Check out the Text_Diff Pear Package. I have used it for this sort of thing and it is very well done.

Paolo Bergantino
+1. Text_Diff is a great package, and the maintainers even fixed the bug I reported in a fairly timely manner.
Frank Farmer
Thanks, much easier than trying to do my own
Mijoja