PHP: Compare the start of two strings - php

I am wondering if there is a simple way to, in PHP, compare two strings and returns the amount of characters they have in common from the start of the string.
An example:
$s1 = "helloworld";
$s1 = "hellojohn";
These two strings both start with 'hello', which means that both strings have the first 5 characters in common. '5' is the value I'd like to recieve when comparing these two strings.
Is there a computationally fast way of doing this without comparing both strings as arrays to eachother?

function commonChars($s1, $s2) {
$IMAX = min(strlen($s1), strlen($s2));
for($i = 0; $i < $IMAX; $i++)
if($s2[i] != $s1[i]) break;
return $i;
}

If the strings are really big, then I would write my own binary search. Something similar to this totally untested code that I just dreamed up.
function compareSection($start, $end, $string1, $string2) {
$substr1 = substr($string1, $start, $end-$start);
$substr2 = substr($string2, $start, $end-$start);
if ($substr1 == $substr2) return $end;
if ($firstMatches = compareSection(0, $end/2, $substr1, $substr2)) {
return $start + $firstMatches;
if ($lastMatches = compareSection($end/2, $end, $substr, $substr2)) {
return $start+$lastMatches;
}
}

If it's the similarity of the strings you wish to get and not just the actual number of identical characters, there are two functions for that:strcmp and levenshtein. Maybe they suit your goal more than what you asked for in this question.

From my knowledge, I don't think there is a built in function for something like this. Most likely, you will have to make your own.
Shouldn't be too hard. Just loop both strings by index by index until you don't find a match that doesn't match. However far you got is the answer.
Hope that helps!

Related

Is there any manual method other than "str_repeat" to repeat the string?

I mean if we give 3, b as parameters passed into function, it should return "bbb" by using loops.
I've tried some code, but I do not want to post it because it might look crazy for a well-versed developer. I can provide you links, this question has been asked in an interview, mainly they want it to be computed in C or C++. Since I am a PHP practitioner, I am curious to know it is possible in PHP. Below is the link (ROUND 2: SIMPLE CODING(3 hours))
https://www.geeksforgeeks.org/zoho-interview-set-3-campus/
A PHP function to do that would probably look like this:
function string_repeat($num, $string)
{
$result = "";
for ($x = 0; $x < $num; $x++) {
$result .= $string;
}
return $result;
}
So calling echo string_repeat(3, 'b'); would output:
bbb
One way would be to keep around a "dummy" string, of sufficient length to be longer than any string you want to generate. Then, we can use preg_replace to replace each character with whatever the input is. Finally, we can substring that replace string to the desired length.
$dummy = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$length = 3;
$dummy = preg_replace('/./', 'b', $dummy);
$output = substr($dummy, 0, $length);
echo $output;
This prints:
bbb
You could wrap this into a helper function, if you really wanted to do that. Note that internally the regex engine is most likely doing some looping of its own, so we are not really freeing ourselves from looping, just hiding it from the current context.

What is the preferred way of separating two integers?

I have variables of form like:
$x = "1-15"
$y = "2-18"
etc.
I need to extract the first and second integer as separate variables.
For example:
if $x = "1-15", return values should be $z = 1 and $w = 15.
I know that It would be possible to do this with regex, but from what I've heard, it should be avoided if possible.
What then would be the "fastest" way of achieving this?
If you are sure this is the format, you can split the string (assuming it is a string, and not literally what you wrote).
Splitting is done with explode in php:
http://php.net/manual/en/function.explode.php
$x = "1-15"; //assuming it is indeed a string
list($z, $w) = explode('-', $x);
Using explode is a better option, If you want to go with regex, Hope this solution will be okay.
Regex: ^\s*(\d+)\s*\-\s*(\d+)\s*$
1. ^\s*(\d+)\s*\-\s*(\d+)\s*$ This will match digits - digits pattern, this will take care of spaces as well.
Try this code snippet here
<?php
$x = '1-15';
extract(getVariables($x));
echo $z;
echo $w;
function getVariables($x)
{
preg_match("/^\s*(\d+)\s*\-\s*(\d+)\s*$/", $x,$matches);
return array("z"=>$matches[1],"w"=>$matches[2]);
}

Need every permutation of capitalized letters in php

I want to build an array in php that contains every possible capitalization permutation of a word. so it would be (pseudocode)
function permutate($word){
for ($i=0; $i<count($word); $i++){
...confused here...
array_push($myArray, $newWord)
}
return $myArray;
}
So say I put in "School" I should get an array back of
{school, School, sChool, SCHool, schOOl, ... SCHOOL}
I know of functions that capitalize the string or the first character, but I am really struggling with how to accomplish this.
This should do it for you:
function permute($word){
if(!$word)
return array($word);
$permutations = array();
foreach(permute(substr($word, 1)) as $permutation){
$lower = strtolower($word[0]);
$permutations[] = $lower . $permutation;
$upper = strtoupper($word[0]);
if($upper !== $lower)
$permutations[] = $upper . $permutation;
}
return $permutations;
}
Codepad Demo
However, for your particular use case there may be a better solution. As there are 2^n permutations for a string of length n. It will be infeasible to run this (or even to generate all those strings using any method at all) on a much longer string.
In reality you should probably be converting strings to one particular case before hashing them, before storing them in the database, if you want to do case-insensitive matching.

PHP: Detecting a particular sequence of elements in an array

How do I detect if a certan sequence of elements is present in an array? E.g. if I have the arrays and needle
$needle = array(1,1);
$haystack1 = array(0,1,0,0,0,1,1,0,1,0);
$haystack2 = array(0,0,0,0,1,0,1,0,0,1);
How does one detect if the subset $needle is present in e.g. $haystack1? This method should return TRUE for $haystack1 and FALSE for $haystack2.
Thanks for any suggestions!
Join the arrays, and check for the strpos of the needle.
if ( strpos( join($haystack1), join($needle) ) >= 0 ) {
echo "Items found";
}
Demo: http://codepad.org/F13DLWOI
Warning
This will not work for complicated items like objects or arrays within the haystack array. This method is best used with itesm like numbers and strings.
If they're always a single digit/character then you can convert all elements to strings, join by '', and use the regex or string functions to search.
For the specific case where no array element is a prefix of any other element (when both are converted to strings) then the already posted answers will work fine and probably be pretty fast.
Here's an approach that will work correctly in the general case:
function subarray_exists(array $needle, array $haystack) {
if (count($needle) > count($haystack)) {
return false;
}
$needle = array_values($needle);
$iterations = count($haystack) - count($needle) + 1;
for ($i = 0; $i < $iterations; ++$i) {
if (array_slice($haystack, $i, count($needle)) == $needle) {
return true;
}
}
return false;
}
See it in action.
Disclaimer: There are ways to write this function that I expect will make it execute much faster when you are searching huge haystacks, but for a first approach simple is good.

strpos for arrays

Let's say I have 90 'indexes' in my array and I have a function which checks if that value exists in that array, would it be faster if i used strpos with a String instead?
Instead of using in_array() to
$data = array('John','Mary','Steven');
It will be
$data = 'John.Mary.Steven';
then I'll just strpos() on that String?
Without bothering to profile it, I'd say that imploding to a string followed by strpos would be slower than PHP's built-in in_array() function.... because you're adding all the overhead of converting the entire array (all 90 elements) to a string before you can even use strpos(). Premature Micro-optimisation isn't a good idea, unless you really need it, and then you should test your ideas.
EDIT
If you're using your own function instead of in_array(), it probably is slower, but raises the question "why"?
I was quite sure that use of strpos will be slower but I made a test below, and it looks like (at least in this particular case - searching for the last element) strpos is faster than in_array.
$array = array();
for($i=0;$i<10000;$i++) {
$array[] = md5($i . date('now'));
}
$string = implode('.', $array);
$lastElement = $array[9999];
$start = microtime(TRUE);
$isit = in_array($lastElement, $array);
$end = microtime(TRUE);
echo ($end - $start) . PHP_EOL;
$start = microtime(TRUE);
$pos = strpos($string, $lastElement);
$end = microtime(TRUE);
echo ($end - $start) . PHP_EOL;
Results I'm getting:
0.0012338161468506
0.00036406517028809
According to this test, looping your array and checking with strpos() would be slower than just using in_array(). They claim that in_array() is actually 2.4 times faster than doing a foreach loop with strpos().
On the other hand, a question here on SO seems to indicate otherwise.
Efficiency of Searching an Array Vs Searching in Text.... Which is Better?
If I were you, I would run my own performance tests to see what works best with my specific set of data.

Categories