Simplify and Abstract my Code: Combining Strings - php

I want to combine strings in PHP. My script creates every possible combination like below.
$part1 = array('','d','n','s','g');
$part2 = array('a','e','o','oo');
$part3 = array('m','n','s','d','l','t','g','j','p');
$part4 = array('g','p','l','');
$part5 = array('g','p','l');
$part6 = array('a','e','o');
$part7 = array('d','l','r','');
$names = array();
foreach ($part1 as $letter1) {
foreach ($part2 as $letter2) {
foreach ($part3 as $letter3) {
foreach ($part4 as $letter4) {
foreach ($part5 as $letter5) {
foreach ($part6 as $letter6) {
foreach ($part7 as $letter7) {
$names[] = $letter1 . $letter2 . $letter3 . $letter4 . $letter5 . $letter6 . $letter7;
}
}
}
}
}
}
}
But I am not happy with my solution. I is quick and dirty code. Is there a solution wich works with a flexible number of part arrays, so I can extend the script by e.g. $part8 easiely? (without changing the loop construction)

Recursive one:
function buildNames( $parts, $chars = ''){
// Nothing to do, shouldn't happen
if( !count( $parts)){
return array();
}
$names = array();
$part = array_shift( $parts);
// Max level, we can build final names from characters
if( !count( $parts)){
foreach( $part as $char){
$names[] = $chars . $char;
}
return $names;
}
// "We need to go deeper" and build one more level with remembered chars so far
foreach( $part as $char){
$names = array_merge( $names, buildNames( $parts, $chars . $char));
}
return $names;
}
$parts = array( $part1, $part2, $part3, $part4, $part5, $part6, $part7);
$names = buildNames( $parts);
From head, from scratch, comment if something, but idea should be good

You could reduce this problem to six cartesian products:
cartesianProduct($part1,
cartesianProduct($part2,
cartesianProduct($part3,
cartesianProduct($part4,
cartesianProduct($part5,
cartesianProduct($part6, $part7))))));
function cartesianProduct($p1, $p2) {
$ret = array();
foreach($p1 as $l1)
foreach($p2 as $l2)
$ret[] = $l1 . $l2;
return $ret;
}

Related

How to splitting words match by patterns with PHP

I have an array of words. e.g.,
$pattern = ['in', 'do', 'mie', 'indo'];
I wanna split a words match by the patterns to some ways.
input =
indomie
to output =
$ in, do, mie
$ indo, mie
any suggests?
*ps sorry for bad english. thank you very much!
it was an very interesting question.
Input:-
$inputSting = "indomie";
$pattern = ['in', 'do', 'mie', 'indo','dom','ie','indomi','e'];
Output:-
in,do,mie
in,dom,ie
indo,mie
indomi,e
Approach to this challenge
Get the pattern string length
Get the all the possible combination of matrix
Check whether the pattern matching.
if i understand your question correctly then above #V. Prince answer will work only for finding max two pattern.
function sampling($chars, $size, $combinations = array()) {
if (empty($combinations)) {
$combinations = $chars;
}
if ($size == 1) {
return $combinations;
}
$new_combinations = array();
foreach ($combinations as $combination) {
foreach ($chars as $char) {
$new_combinations[] = $combination . $char;
}
}
return sampling($chars, $size - 1, $new_combinations);
}
function splitbyPattern($inputSting, $pattern)
{
$patternLength= array();
// Get the each pattern string Length
foreach ($pattern as $length) {
if (!in_array(strlen($length), $patternLength))
{
array_push($patternLength,strlen($length));
}
}
// Get all the matrix combination of pattern string length to check the probablbe match
$combination = sampling($patternLength, count($patternLength));
$MatchOutput=Array();
foreach ($combination as $comp) {
$intlen=0;
$MatchNotfound = true;
$value="";
// Loop Through the each probable combination
foreach (str_split($comp,1) as $length) {
if($intlen<=strlen($inputSting))
{
// Check whether the pattern existing
if(in_array(substr($inputSting,$intlen,$length),$pattern))
{
$value = $value.substr($inputSting,$intlen,$length).',';
}
else
{
$MatchNotfound = false;
break;
}
}
else
{
break;
}
$intlen = $intlen+$length;
}
if($MatchNotfound)
{
array_push($MatchOutput,substr($value,0,strlen($value)-1));
}
}
return array_unique($MatchOutput);
}
$inputSting = "indomie";
$pattern = ['in', 'do', 'mie', 'indo','dom','ie','indomi','e'];
$output = splitbyPattern($inputSting,$pattern);
foreach($output as $out)
{
echo $out."<br>";
}
?>
try this one..
and if this solves your concern. try to understand it.
Goodluck.
<?php
function splitString( $pattern, $string ){
$finalResult = $semiResult = $output = array();
$cnt = 0;
# first loop of patterns
foreach( $pattern as $key => $value ){
$cnt++;
if( strpos( $string, $value ) !== false ){
if( implode("",$output) != $string ){
$output[] = $value;
if( $cnt == count($pattern) ) $semiResult[] = implode( ",", $output );
}else{
$semiResult[] = implode( ",", $output );
$output = array();
$output[] = $value;
if( implode("",$output) != $string ){
$semiResult[] = implode( ",", $output );
}
}
}
}
# second loop of patterns
foreach( $semiResult as $key => $value ){
$stackString = explode(",", $value);
/* if value is not yet equal to given string loop the pattern again */
if( str_replace(",", "", $value) != $string ){
foreach( $pattern as $key => $value ){
if( !strpos(' '.implode("", $stackString), $value) ){
$stackString[] = $value;
}
}
if( implode("", $stackString) == $string ) $finalResult[] = implode(",", $stackString); # if result equal to given string
}else{
$finalResult[] = $value; # if value is already equal to given string
}
}
return $finalResult;
}
$pattern = array('in','do','mie','indo','mi','e', 'i');
$string = 'indomie';
var_dump( '<pre>',splitString( $pattern, $string ) );
?>

How to use strstr() php

I want to cut text in array but I have no idea to cut this
I try strstr() but it not true.
I try
$ff='';
while($row = mysqli_fetch_array($result,MYSQLI_ASSOC)){
$ff .= $row['fav'] . ",";
}
if( strpos( $ff, "_" )) {
$text = strstr($ff, '_');
echo $text;
}
$ff ='A_0089,A_5677,B_4387,A_B_5566,'
I want output show
0089,5677,4387,B_5566,
Here is one example, using substr() with strpos():
$ff='A_0089,A_5677,B_4387,A_B_5566';
$items = explode(',', $ff);
foreach($items as $item) {
echo substr($item, strpos($item, '_')) . "\n";
}
The above code returns:
_0089
_5677
_4387
_B_5566
You're better off not building a string, but building an array. The way you build the string you have a dangling comma, which you do not want.
$ff = array();
while($row = mysqli_fetch_array($result,MYSQLI_ASSOC)){
$ff[] = $row['fav'];
}
foreach($ff as $item) {
echo substr($item, strpos($item, '_')) . "\n";
}
Based on your desire to keep the commas and create a string:
$ff='A_0089,A_5677,B_4387,A_B_5566,';
$items = explode(',', $ff);
foreach($items as $item) {
$new[] = substr($item, strpos($item, '_'));
}
$newFF = implode(',', $new);
echo $newFF;
returns:
_0089,_5677,_4387,_B_5566,
Probably this is what you are looking for
<?php
function test_alter(&$item1)
{
$pattern = '/^[A-Z]{1}[_]{1}/';
$item1 =preg_replace($pattern,"",$item1);
}
$ff="A_0089,A_5677,B_4387,A_B_5566,";
$nff=explode(",",$ff);
array_walk($nff, 'test_alter');
echo implode(",",$nff);
?>

Multiple String Replace Based on Index

I need to replace multiple sections of a string based on their indices.
$string = '01234567890123456789';
$replacements = array(
array(3, 2, 'test'),
array(8, 2, 'haha')
);
$expected_result = '012test567haha0123456789';
Indices in $replacements are expected not to have overlaps.
I have been trying to write my own solution, split the original array into multiple pieces based on sections which needs to be replaced or not, and finally combine them:
echo str_replace_with_indices($string, $replacements);
// outputs the expected result '012test567haha0123456789'
function str_replace_with_indices ($string, $replacements) {
$string_chars = str_split($string);
$string_sections = array();
$replacing = false;
$section = 0;
foreach($string_chars as $char_idx => $char) {
if ($replacing != (($r_idx = replacing($replacements, $char_idx)) !== false)) {
$replacing = !$replacing;
$section++;
}
$string_sections[$section] = $string_sections[$section] ? $string_sections[$section] : array();
$string_sections[$section]['original'] .= $char;
if ($replacing) $string_sections[$section]['new'] = $replacements[$r_idx][2];
}
$string_result = '';
foreach($string_sections as $s) {
$string_result .= ($s['new']) ? $s['new'] : $s['original'];
}
return $string_result;
}
function replacing($replacements, $idx) {
foreach($replacements as $r_idx => $r) {
if ($idx >= $r[0] && $idx < $r[0]+$r[1]) {
return $r_idx;
}
}
return false;
}
Is there any more effective way to achieve the same result?
The above solution doesn't look elegant and feels quite long for string replacement.
Use this
$str = '01234567890123456789';
$rep = array(array(3,3,'test'), array(8,2,'haha'));
$index = 0;
$ctr = 0;
$index_strlen = 0;
foreach($rep as $s)
{
$index = $s[0]+$index_strlen;
$str = substr_replace($str, $s[2], $index, $s[1]);
$index_strlen += strlen($s[2]) - $s[1];
}
echo $str;

php split mysql field type into parts with preg_replace

I have a string... ENUM('0','1')
and I want to get an array... array('ENUM', array(0, 1));
and I want to do it with preg_replace instead of using multiple complicated explode statements
like so...
$showColumns = 'SHOW COLUMNS FROM table';
if (strpos($show[$k][1], '(')!==FALSE) {
$showType = explode("(", $show[$k][1]);//PREG_SPLIT IS BETTER
}
$elementType = strtoupper($showType[0]);
$type = $this->FIELD_TYPE[$elementType];
$vals = explode(")", $showType[1]);
if (is_integer($vals[0])) {
$values = $vals[0];
}elseif (strpos($vals[0], ',')!==FALSE) {
$vs = explode(',', $vals[0]);
$vs = array_map('str_replace', $vs, array('\'', '', $vs[0]));
$values=array();
foreach ($vs as $v) {
$values[] = $v;
}
}
$values = $vals[0];
print $values; print '<br /><br />';

Help with a PHP Algorithm class

I'm trying to build a class that will parse CSV files in a certain way.
Unfortunately I am NOT an OO programmer in any way shape or form, my
company is requiring me to write a class for some future functionality
and I seriously, seriously need some help on it. So...
Our $value will be formulated by counting the second marker in the file
which is a semicolon, and create a new feed for each carriage return.
Input is like this:
Code:
Jeff Goes, Mika Enrar;Triple Threat, Dogs on Bikes
Sonny Ray, Lars McGarvitch, Jason McKinley;Kasabian, Lords of Acid, Hard-Fi
So for ease of understandability, lets say that the names are $name, the
bands are $item, and the equatible score is $value.
The Run Down:
If the number of letters in the $item is even (Triple Threat = 12)
then the $value is equal to the number of vowels in $name times
one and a half (Jeff Goes [3x1.5] = 4.50)
If the number of the $item is odd (Dogs on Bikes = 11) then the $value
is the number of consonants in $name (Mika Enrar = 5)
If the number of letters in $name share a commonality in $item besides one,
multiply the output by one and a half. So (Sonny Ray = 8; Kasabian = 8;
then 6x1.5 = 9; or lets say $name = 112; $item = 12; we share a commonality of 12)
The idea is to implement a class that assigns each $name a $item to be offered in a way
that maximizes the combined total $value across all of the $item. As a fail safe,
there may be a different number of $name and $item.
My output should be the max $value in two decimal places as in
12.00
38.50
UPDATED ANSER
If you are looking for something a bit more OOP, and to do so with some built-in function of PHP, I would start by doing this:
class CSVParser
{
public $output = NULL;
public $digits = NULL;
public function __construct($file)
{
if (!file_exists($file)) {
throw new Exception("$file does not exist");
}
$this->contents = file_get_contents($file);
$this->output = array();
$this->digits = array();
}
public function parse($separatorChar1 = ',', $separatorChar2 = ';', $enclosureChar = '"', $newlineChar = "\n")
{
$lines = explode($newlineChar, $this->contents);
foreach ($lines as $line) {
if (strlen($line) == 0) continue;
$group = array();
list($part1, $part2) = explode($separatorChar2, $line);
$group[] = array_map(array($this, "trim_value"), explode($separatorChar1, $part1), array("$enclosureChar \t"));
$group[] = array_map(array($this, "trim_value"), explode($separatorChar1, $part2), array("$enclosureChar \t"));
$this->output[] = $group;
}
}
private function trim_value($value, $chars)
{
return preg_replace("#^( |" . $chars . ")+#", '', $value);
}
public function algorithm()
{
$alpha = array(
'c' => str_split('bcdfghjklmnpqrstvwxz'),
'v' => str_split('aeiouy')
);
$i = 0;
$k = 0;
foreach ($this->output as $item) {
$cnt = 0;
$this->digits[$i] = array();
foreach ($item as $part) {
$this->digits[$i][$cnt] = array();
$new = array();
foreach ($part as $str) {
$v = count(array_intersect(str_split($str), $alpha['v']));
$c = count(array_intersect(str_split($str), $alpha['c']));
$t = strlen(str_replace(' ', '', $str));
$new = array('v' => $v, 'c' => $c, 't' => $t);
$this->digits[$i][$cnt][] = $new;
}
$cnt++;
}
$i++;
}
}
}
$parser = new CSVParser("file.txt");
$parser->parse();
print_r($parser->output);
$parser->algorithm();
print_r($parser->digits);

Categories