PHP string expansion - php

I have a string composed by many letters, at some point, one letter from a group can be used and this is represented by letters enclosed in []. I need to expand these letters into its actual strings.
From this:
$str = 'ABCCDF[GH]IJJ[KLM]'
To this:
$sub[0] = 'ABCCDFGIJJK';
$sub[1] = 'ABCCDFHIJJK';
$sub[2] = 'ABCCDFGIJJL';
$sub[3] = 'ABCCDFHIJJL';
$sub[4] = 'ABCCDFGIJJM';
$sub[5] = 'ABCCDFHIJJM';
UPDATE:
Thanks to #Barmar for the very valuable suggestions.
My final solution is:
$str = '[GH]DF[IK]TF[ADF]';
function parseString(string $str) : array
{
$i = 0;
$is_group = false;
$sub = array();
$chars = preg_split('//', $str, -1, PREG_SPLIT_NO_EMPTY);
foreach ($chars as $key => $value)
{
if(ctype_alpha($value))
{
if($is_group){
$sub[$i][] = $value;
} else {
if(!isset($sub[$i][0])){
$sub[$i][0] = $value;
} else {
$sub[$i][0] .= $value;
}
}
} else {
$is_group = !$is_group;
++$i;
}
}
return $sub;
}
The recommended function for combinations is (check the related post):
function array_cartesian_product($arrays)
{
$result = array();
$arrays = array_values($arrays);
$sizeIn = sizeof($arrays);
$size = $sizeIn > 0 ? 1 : 0;
foreach ($arrays as $array)
$size = $size * sizeof($array);
for ($i = 0; $i < $size; $i++) {
$result[$i] = array();
for ($j = 0; $j < $sizeIn; $j++)
array_push($result[$i], current($arrays[$j]));
for ($j = ($sizeIn - 1); $j >= 0; $j--) {
if (next($arrays[$j]))
break;
elseif (isset($arrays[$j]))
reset($arrays[$j]);
}
}
return $result;
}
Check the solution with:
$combinations = array_cartesian_product(parseString($str));
$sub = array_map('implode', $combinations);
var_dump($sub);

Convert your string into a 2-dimensional array. The parts outside brackets become single-element arrays, while each bracketed trings becomes an array of single characters. So your string would become:
$array =
array(array('ABCCDF'),
array('G', 'H', 'I'),
array('IJJ'),
array('K', 'L', 'M'));
Then you just need to compute all the combinations of those arrays; use one of the answers at How to generate in PHP all combinations of items in multiple arrays. Finally, you concatenate each of the resulting arrays with implode to get an array of strings.
$combinations = combinations($array);
$sub = array_map('implode', $combinations);

Related

How to search for word in array of slugs

I have an array of locations slugs and a sentence that might have one of the locations. So I want to get the location in the sentence from the locations array
$areas = 'garki-i,garki-ii,yaba,wuse-i,asokoro,maitama,jabi,jahi,dutse,gwarinpa,central-business-district,kubwa,lugbe,kaura,gudu,banana-island,new-karu,old-karu,kugbo,eko-atlantic,nyanya,mararaba,madalla,kuje,wuse-ii,utako,oulfa,kimunyu,ibara,cfc,joska,kabati,juja';
$a_arr = explode(',', $areas);
$tweet = "I live in Eko Atlantic and Yaba and I also work at Banana Island";
$t_arr = explode(" ", strtolower($tweet));
$location = [];
for ($i = 0; $i < count($t_arr); $i++) {
for ($j = 0; $j < count($a_arr); $j++) {
if ($t_arr[$i] == $a_arr[$j]) {
array_push($location, $a_arr[$j]);
}
}
}
$output = ["eko-atlantic", "yaba", "banana-island"];
I am getting ['yaba'] but I want ["eko-atlantic", "yaba", "banana-island"]
Here is my solution
<?php
$areas = 'garki-i,garki-ii,yaba,wuse-i,asokoro,maitama,jabi,jahi,dutse,gwarinpa,central-business-district,kubwa,lugbe,kaura,gudu,banana-island,new-karu,old-karu,kugbo,eko-atlantic,nyanya,mararaba,madalla,kuje,wuse-ii,utako,oulfa,kimunyu,ibara,cfc,joska,kabati,juja';
$a_arr = explode(',', $areas);
$tweet = "I live in Eko Atlantic and Yaba and I also work at Banana Island";
$t_arr = explode(" ", strtolower($tweet));
$location = [];
if ( $t_arr != null ) {
foreach ($a_arr as $key => $value) {
if ( preg_match ( '/'.str_replace('-', ' ', $value).'/', strtolower($tweet)) ) {
array_push($location, $value);
}
}
}
var_dump( $location );
You will need to change the inner loop such that it compares the complete string in $t arr[$i] to the entire string in $a arr[$j], rather than just comparing individual characters, in order to alter your code so that it correctly extracts the locations from the tweet. To accomplish this, compare the strings using the strcmp function:
for ($i = 0; $i < count($t_arr); $i++) {
for ($j = 0; $j < count($a_arr); $j++) {
if (strcmp($t_arr[$i], $a_arr[$j]) == 0) {
array_push($location, $a_arr[$j]);
}
}
}

PHP - How to create all possibility from a string

Here, there is a example string "XjYAKpR" .. how to create all new string possibility with that string ??
I've tried before
function containAllRots($s, $arr) {
$n = strlen($s);
$a = array();
for ($i = 0; $i < $n ; $i++) {
$rotated = rotate(str_split($s), $i);
$a[] = $rotated;
}
print_r($a);die();
if (array_diff($arr, $a)) {
return True;
}
else
{
return False;
}
}
I make 2 function rotate and generate
function rotate($l, $n) {
$b = $l[$n];
$sisa = array_values(array_diff($l, array($b)));
for ($i = 0; $i < count($sisa) ; $i++) {
$random[] = generate($sisa, $b);
}
print_r($random);die();
$hasil = $l[$n] . implode("",$random);
return $hasil;
}
function generate($sisa, $b) {
$string = implode("",$sisa);
$length = count($sisa);
$size = strlen($string);
$str = '';
for( $i = 0; $i < $length; $i++ ) {
$str .= $string[ rand( 0, $size - 1 ) ];
}
Here there is a pair of functions that lets you calculate a permutation set
(no repetitions are taken in account)
function extends_permutation($char, $perm) {
$result = [];
$times = count($perm);
for ($i=0; $i<$times; $i++) {
$temp = $perm;
array_splice($temp, $i, 0, $char);
array_push($result, $temp);
}
array_push($result, array_merge($perm, [$char]));
return $result;
}
function extends_set_of_permutations($char, $set) {
$step = [];
foreach ($set as $perm) {
$step = array_merge($step, extends_permutation($char, $perm));
}
return $step;
}
you can use them to generate the required set of permutations. Something like this:
$seed = "XjYAKpR";
// the first set of permutations contains only the
// possible permutation of a one char string (1)
$result_set = [[$seed[0]]];
$rest = str_split(substr($seed,1));
foreach($rest as $char) {
$result_set = extends_set_of_permutations($char, $result_set);
}
$result_set = array_map('implode', $result_set);
sort($result_set);
At the end of the execution you will have the 5040 permutations generated by your string in the result_set array (sorted in alphabetical order).
Add a char and you will have more than 40000 results.
The functions are quite naive in implementation and naming, both aspects can be improved.

Find the 3 longest words from string

What I need to add to this script to get 3 longest words from string?
<?php
$text = 'one four eleven no upstairs';
$arr = explode(" ", $text);
$max = $arr[0];
for ($i = 0; $i < count($arr); $i++) {
if (strlen($arr[$i]) > strlen($max)) {
$max = $arr[$i];
}
}
echo $max;
?>
Please help to modify the script. We have to not use the usort function.
The solution would be like this:
Use explode() to get the words of the string in an array
"Partially" sort the array elements in descending order of length
Use a simple for loop to print the longest three words from the array.
So your code should be like this:
$text = 'one four eleven no upstairs';
$arr = explode(" ", $text);
$count = count($arr);
for($i=0; $i < $count; $i++){
$max = $arr[$i];
$index = $i;
for($j = $i + 1; $j < $count; ++$j){
if(strlen($arr[$j]) > strlen($max)){
$max = $arr[$j];
$index = $j;
}
}
$tmp = $arr[$index];
$arr[$index] = $arr[$i];
$arr[$i] = $tmp;
if($i == 3) break;
}
// print the longest three words
for($i=0; $i < 3; $i++){
echo $arr[$i] . '<br />';
}
Alternative method: (Using predefined functions)
$text = 'one four eleven no upstairs';
$arr = explode(" ", $text);
usort($arr,function($a, $b){
return strlen($b)-strlen($a);
});
$longest_string_array = array_slice($arr, 0, 3);
// display $longest_string_array
var_dump($longest_string_array);
You need to create your own comparative function and pass it with array to usort php function.
Ex.:
<?php
function lengthBaseSort($first, $second) {
return strlen($first) > strlen($second) ? -1 : 1;
}
$text = 'one four eleven no upstairs';
$arr = explode(" ", $text);
usort($arr, 'lengthBaseSort');
var_dump(array_slice($arr, 0, 3));
It will output 3 longest words from your statement.
According to author changes:
If you have no ability to use usort for some reasons (may be for school more useful a recursive function) use following code:
<?php
$text = 'one four eleven no upstairs';
$arr = explode(" ", $text);
function findLongest($inputArray) {
$currentIndex = 0;
$currentMax = $inputArray[$currentIndex];
foreach ($inputArray as $key => $value) {
if(strlen($value) > strlen($currentMax)){
$currentMax = $value;
$currentIndex = $key;
}
}
return [$currentIndex, $currentMax];
}
for($i = 0; $i < 3; $i++) {
$result = findLongest($arr);
unset($arr[$result[0]]);
var_dump($result[1]);
}
?>

how to make pairs of array value?

I have an array something like that:
array('A','B','C','D','E');
and I want to make pairs of each value like that :
A, AB, ABC, ABCD, ABCDE
B, BC, BCD, BCDE
C, CD, CDE
D, DE
E
as an Array (ALL PAIRS SHOULD BE IN A SAME ARRAY).
And I have followed this Question:
How do I make pairs of array values?
But i'm not able to do that.
Please Help
For each of your inputs, loop between it and the end of the input array. For each result, add the range between the present and end inputs to your result.
$input = array('A', 'B', 'C', 'D', 'E');
$output = array();
for ($i = 0; $i < count($input); $i++) {
$row = array($input[$i]);
for ($j = $i + 1; $j < count($input); $j++) {
$row[] = implode('', range($input[$i], $input[$j]));
}
$output[] = $row;
}
$data = array('A','B','C','D','E');
$chars = count($data);
$combinations = array();
foreach ($data as $key => $startChar) {
$length = 0;
while ($length < $chars - $key) {
$combinations[] = implode(array_slice($data, $key, ++$length));
}
}
var_dump($combinations);
Looks like the format output:
$letters = array('A','B','C','D','E');
$result = array();
$x = 0;
while(count($letters) > 0) {
$l = array_shift($letters);
$result[$x][] = $l;
foreach($letters as $k => $letter){
$result[$x][] = $l . implode(array_slice($letters, 0, $k+1));
}
$result[$x] = implode(', ', $result[$x]);
$x++;
}
echo '<pre>';
print_r($result);

How to create a 2D array that values BA and AB are treated as the same

I am trying to create function that allows me to get all combinations of an array to later generate a list.
But my problem is that currently my function treat "ab" as different from "ba". I dont know how to explain it in words but I guess the picture below exemplify what I try to achieve.
function everyCombination($array) {
$arrayCount = count($array);
$maxCombinations = pow($arrayCount, $arrayCount);
$returnArray = array();
$conversionArray = array();
foreach ($array as $key => $value) {
$conversionArray[base_convert($key, 10, $arrayCount)] = $value;
}
for ($i = 0; $i < $maxCombinations; $i++) {
$combination = base_convert($i, 10, $arrayCount);
$combination = str_pad($combination, $arrayCount, "0", STR_PAD_LEFT);
$returnArray[] = strtr($combination, $conversionArray);
}
return $returnArray;
}
$a = everyCombination(array('a', 'b', 'c','d'));
print_r($a);
The desired ouput would be
a
ab
abc
abcd
b
bc
bcd
c
cd
d
What you need to do is iterate through the array recursively, for each recursion you should only iterate through all the greater elements. Like so:
function everyCombination($arr) {
$combos = array();
$len = count($arr);
for( $i=0; $i<$len; $i++) {
for( $j=$i+1; $j<=$len; $j++) {
$combos[] = implode("",array_slice($arr,$i,$j-$i));
}
}
return $combos;
}
Example call:
everyCombination(['a','b','c','d']);
Returns:
['a','ab','abc','abcd','b','bc','bcd','c','cd','d']
It seems that you're after consecutive results, so a double loop would be a better choice here; recursion requires more control.
function combos($array)
{
if (!$array) {
return [];
}
$n = count($array);
$r = [];
for ($i = 0; $i < $n; ++$i) {
$prefix = '';
for ($j = $i; $j < $n; ++$j) {
$r[] = $prefix . $array[$j];
$prefix .= $array[$j];
}
}
return $r;
}
print_r(combos([1, 2, 3, 4]));

Categories