how to read a substring as a whole - php

This was difficult to put into a title.
Essentially what I want to do is, when I get some random binary code i need certain number patterns be converted into a declared symbol.
For example :
input: 11100011111
Output: ABF
So essentially
111 = A, 000 = B, 11111 = C, 1111 = D
Note!That the output has to correspond in order so if it started with 111 the output hast to start with A(declared symbol for said pattern).
There's a D there also essentially the first four characters of C is the same as D but it must output the one most similar.
First i tried to put this into a for loop
so, check string characters, if there's a 1 echo one and vice versa
for ($i=0; $i < $getInput[$i] ; $i++) {
if ($getInput[$i] == 1) {
echo "ONE";
} elseif ($getInput[$i] == 0) {
echo "ZERO";
}
}
this was just for testing, essentially in this theory i can check if if there is a consecutive pattern so 000 it will refer to an array with different patterns already assigned and then output the symbol whatever was assigned to that pattern.
I also tried using foreaches but due to inexperience...
I did some research and found this topic:
How do I check if a string contains a specific word?
which kinda helped since with this code
$a = '1110001111';
if (strpos($a, '1111') !== false) {
echo 'D';
}
It outputs the character in right order, problem with this approach is that well it kinda means id need to write out if statements repetitively, and secondly if there were to be 1111 in the input, it would take the part 111 and 1111 as two different strings and output both of them
EDIT:
Essentially what i just thought is, i actually need to compare 4 digits to different patterns, i can put the string into an array split it into 4's and then compare with another array which holds the declared patterns (1111 = a etc..), so in a 4 digit binary 0000 there can be about 17 different patterns therefor no need for anything above >4
Then again if there were an odd number of 1's and 0's there'd be some left off.
Then these should just be outputted as is. so if there were 1010110 = A110 since A is declared as a pattern of 1010

You can use str_split to split the string in chunkes of four digits.
Then I use an associative array with replacements.
I loop the match array and echo replacement character.
$str = "111000111111";
//preg_match_all('/(.)\1*/', $str, $match);
$digits = str_split($str, 4);
$replace = array("1110" => "A", "0011" => "B", "1111" => "C");
Foreach($digits as $val){
Echo $replace[$val];
}
https://3v4l.org/QfQQ8

This code will give you an array of the 4 digits and then you can parse that via a foreach and lookup.
<?php
$string = "11111001011100001111";
$matches = [];
preg_match_all("/[1|0]{4}/", $string, $matches);
echo "<pre>";
print_r($matches);
Which the output of that would be:
<pre>Array
(
[0] => Array
(
[0] => 1111
[1] => 1001
[2] => 0111
[3] => 0000
[4] => 1111
)
)

Related

Fatal error: Allowed memory size exhausted while looping through a 14 element long single-character-array

I have a simple string. I need to produce an output Array such that the order of every 2 consecutive characters is reversed.
Input string is 14f05000034e69 and I need the following output Array [4, 1, 0, f, 0, 5, 0, 0, 4, 3, 6, e, 9, 6].
Here is my PHP code:
$myString = "14f05000034e69";
$myStringArray = str_split($myString);
$newArray = array();
for ($index=0; $index<count($myStringArray)-1; $index+2) {
$newArray[] = $myStringArray[$index+1];
$newArray[] = $myStringArray[$index];
}
print_r($newArray);
And it is giving me
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 134217736 bytes) in /var/www/html/test.php on line 8
The question is why and how do I fix it?
<?php
$myString = "14f05000034e69";
$myStringArray = str_split($myString);
$i=0;
foreach($myStringArray as $row){
if(array_key_exists($i,$myStringArray)) {
$newArray[$i] = $myStringArray[$i + 1];
$newArray[$i + 1] = $myStringArray[$i];
$i = $i + 2;
}
}
echo '<pre>';
print_r($newArray);
I found a workaround in a bit "dirty" way but i managed to do what you asked.
Basically i split the string like you did but i play with the new array positions around and push in my new array the positions that i want to that's why i used a counter for that.
The output is:
Array
(
[0] => 4
[1] => 1
[2] => 0
[3] => f
[4] => 0
[5] => 5
[6] => 0
[7] => 0
[8] => 3
[9] => 0
[10] => e
[11] => 4
[12] => 9
[13] => 6
)
Basically i thought that i need to loop the array by two but every time i loop i need to handle 2 array positions and then the next two.
So that led me to handle my $new_array in a way that i push at the same time data in the current position i am and in the next position, that's why the counter $i+1 is used to handle array position.
If i did not use it there and used simple $newArray[] it would put the data in my current position and overwrite it again in the second step and also i could not move my array pointer to positions 1,3,5,6 etc etc that's why i am "forcing" it to use my $i counter so i keep pointing every after position.
My $i counter is set at the end of each loop to move with step 2.
The shortest alternative I could come up with is to use some of the array methods instead...
$myString = "14f05000034e69";
$out = str_split(implode(array_map ('strrev', str_split($myString, 2))));
print_r( $out );
This uses str_split() to split it into 2 char chunks, then uses array_map() and strrev() to reverse each item and then implode() to put them all back again.
The outer call to str_split() just splits the result back down to 1 char elements in an array for the output (miss this off if you just need the string itself)
In my opinion, the str_split is redundant in this operation, strings can be iterated through as of arrays, like this:
$myString = "14f05000034e69";
$newArray = array();
for ($index=0; $index<strlen($myString)-1; $index+=2)
{
$newArray[] = $myString[$index+1];
$newArray[] = $myString[$index];
}
print_r($newArray);
But yeah, as said before, just missing += in the for loop.
I made a small test on regex to see if it could be done, works as a charm. But of course, I only deliver a string in this case. :)
$myString = "14f05000034e69";
$test = preg_replace('/(.)(.)/', '$2$1', $myString);
echo $test;
This is the most elegant solution I could come up with.
Code tested here: https://3v4l.org/mtdca
And for the regex: https://3v4l.org/nI4UP
An answer has already been marked as the solution an many other answers too however I think this can help to know that we can achieve the inversion in the string itself and then split it.If an array is not needed we can just keep the string.This way we use less memory i think:
$myString = "14f05000034e69";
$length=strlen($myString);
for ($index=-1, $length=$length%2==0?$length-1:$length-2; $index<$length-1; $index+=2) {
$tmp=$myString[$index+1];
$myString[$index+1]=$myString[$index+2];
$myString[$index+2]=$tmp;
}
print_r(str_split($myString));// return an array
print_r($myString); //here a string
This can handle variable length of strings

i want to compare the string and show to characters which match in both strings in php

i want to compare the string and show to characters which match in both strings in php i tried everything but failed to do this please give me any idea how to do this in php
e.g i have two variables
I have to compare $a and $b and give the output as letters whicj are common in both
$a="hello ";
$b= "hell";
output should be : :: hell as first 4 character matches so it should show hell please help me to do this
i have tried everything almost everything which i know or could i find on web
What I tried.. I spit the strings to array... Using nested for loop to find the non matched letters... I wrote code more than 35 lines.. But no result :( Please help me ......
In your case, it would be enough to use array_intersect and str_split functions to get characters common to both input strings(of course, if order of characters doesn't matter):
$a = "hello ";
$b = "hell";
$common = array_intersect(str_split(trim($a)), str_split(trim($b)));
print_r($common);
The output:
Array
(
[0] => h
[1] => e
[2] => l
[3] => l
)
http://php.net/manual/en/function.array-intersect.php
This PHP code is the one you need.
<?php
$a = "hello";
$b = "hell";
$str = "";
for ($i=0; $i < strlen($a); $i++) {
for ($j=0; $j < strlen($b); $j++) {
if ($a[$i]==$b[$j]) {
$str.=$a[$i];
break;
}
}
}
echo $str;
?>
PHP Strings can be seen as Char arrays so $a[0] get you the first char of the string.

PHP- Search for string in an array, in a loop

What I would like to do is search a file containing; multiple space delimited words and characters, on multiple lines, using preg_grep, containing a certain string, and store as a variable. I would like to then "for loop" through those matched lines, and search within for yet another string.
For sake of example, assume $c contains all the lines that match variable $a (in an Array?), in the file $o, and returns 9 lines that contain that variable. How
$c = preg_grep("/\b$a\b/", $o);
So I set $max = sizeof($c)
$max = sizeof($c); // In this example contains 9
Here I try to loop through $c to find variable $b, and would like to print that line that matches
for ($i = 0; $i < $max; $i++) {
$st = preg_grep("/\b$b\b/", $c);
echo implode($st, ' ');
}
In the first search if I echo implode($c, ' '), I get all 9 values displayed as one solid string. It seems though using the same technique after my loop, I am not getting the result I want, which is a single line resulting from matching both variables.
Additionally, I know there may be much easier ways to accomplish this, but following this example, Where am I making a mistake(s).
EDIT
If it helps, a sample of the text file:
13 04000 Atlanta city GA 394017 +33.762900 -08.4422592
13 56000 North Atlanta CDP PA 27812 0000000147 +33.862550
Where $c = preg_grep("/\b$a\b/", $o); would match both lines
And ideally, if $b= PA, the second preg_grep would yeild:
13 56000 North Atlanta CDP PA 27812 0000000147 +33.862550
Assuming $o is an array of lines:
$result = preg_grep("/\b$b\b/", preg_grep("/\b$a\b/", $o));
echo implode(" ", $result);
This will give an array of elements from $o that match both $a and $b.

how to count hindi string in array with php and count how many letter and vowel in string

I have something like
$a = "आलोक"
I want to achieve something like in php
a[0] = आ
a[1] = लो
a[3] = क
I want counting in numbers like :-
i put a name आलोक
i want output like letter=3 and vowel=2
because in आलोक
first letter (आ),
second letter (लो)
and third letter is (क).
so out put become is letter= 3
and for vowel ,
first vowel ( ा) and
second vowel( ो)
so out put vowel=2
name can be dynamic not static
I was going through the other question you had posted and the accepted answer suggests a function on the following lines to break up the string into characters:
function mbStringToArray ($string) {
$strlen = mb_strlen($string);
while ($strlen) {
$array[] = mb_substr($string,0,1,"UTF-8");
$string = mb_substr($string,1,$strlen,"UTF-8");
$strlen = mb_strlen($string);
}
return $array;
}
$a = "आलोक";
print_r(mbStringToArray($a));
If you run this code, it will give you the following output:
Array
(
[0] => आ
[1] => ल
[2] => ो
[3] => क
)
I'm going to build upon this function and just extend it a little bit and you'll be able to get the count of vowels and consonants easily.
Thankfully, I found this handy guide on the UTF-8 encodings of all the characters in the Devnagri script. Another simple tool to confirm and sort of get the decimal and octal representations as well for this characters is http://unicodelookup.com/.
From the table, I looked up 0x093F and easily cross referenced it with ि.
Now once you have this, it's just a matter of getting the decoded unicode character from the HEX code. You can achieve that easily with :
echo json_decode('"\u093F"'); //Ouputs ि
I have combined these steps together in a function called countVowels:
function countVowels ($req){
//I have hard coded the hex values of some characters that are vowels in Hindi
//This does NOT include all the vowels
//You might want to add more as per your needs from the table that I have provided before
$hindi = array("\u0906","\u0908","\u093E","\u093F","\u0945","\u0946","\u0947","\u0948","\u0949","\u094A","\u094B","\u094C","\u094D");
$vowels= array();
$vowelcount = 0;
for($i = 0; $i<count($hindi); $i++){
//Push the decoded unicode character into the $vowels array
array_push($vowels,json_decode('"'.$hindi[$i].'"'));
}
for($j=0;$j<count($req);$j++){
if(in_array($req[$j], $vowels))
$vowelcount++;
}
return $vowelcount;
}
The input to this function is $req which could be the output array for the previously defined function mbStringToArray. Once you have the count of vowels, you can easily get the count of other consonants. The flow might look something like:
$a = "आलोक";
$arr = mbStringToArray($a)
$vows = countVowels($arr); //Number of vowels
$cons = count($arr) - $vows; //Number of consonants
So in this case, the consonants returned would be 2 and vowels would also be 2. That's because I have hardcoded आ as a vowel and therefore it gets accounted for in the countVowels function. Have a look at the working demo.
You can modify the array I use there and take care of such discrepancies as per your requirements. I hope this gets you started in the right direction.

php challenge: parse pseudo-regex

I have a challenge that I have not been able to figure out, but it seems like it could be fun and relatively easy for someone who thinks in algorithms...
If my search term has a "?" character in it, it means that it should not care if the preceding character is there (as in regex). But I want my program to print out all the possible results.
A few examples: "tab?le" should print out "table" and "tale". The number of results is always 2 to the power of the number of question marks. As another example: "carn?ati?on" should print out:
caraton
caration
carnaton
carnation
I'm looking for a function that will take in the word with the question marks and output an array with all the results...
Following your example of "carn?ati?on":
You can split the word/string into an array on "?" then the last character of each string in the array will be the optional character:
[0] => carn
[1] => ati
[2] => on
You can then create the two separate possibilities (ie. with and without that last character) for each element in the first array and map these permutations to another array. Note the last element should be ignored for the above transformation since it doesn't apply. I would make it of the form:
[0] => [carn, car]
[1] => [ati, at]
[2] => [on]
Then I would iterate over each element in the sub arrays to compute all the different combinations.
If you get stuck in applying this process just post a comment.
I think a loop like this should work:
$to_process = array("carn?ati?on");
$results = array();
while($item = array_shift($to_process)) {
$pos = strpos($item,"?");
if( $pos === false) {
$results[] = $item;
}
elseif( $pos === 0) {
throw new Exception("A term (".$item.") cannot begin with ?");
}
else {
$to_process[] = substr($item,0,$pos).substr($item,$pos+1);
$to_process[] = substr($item,0,$pos-1).substr($item,$pos+1);
}
}
var_dump($results);

Categories