I have a PHP problem where I have a string of numbers:
ie/ 1,2,3,4,5,6,7,8,9...... X
I know the first number and have to create a string X long so that it wraps around
for example if my string is 1,2,3,4,5 and my first number is 4 - i need to return the string:
4,5,1,2,3
I'd like to create a function to achieve this - any help would be great!
Thanks.
<?php
function MyWrap($string, $first)
{
$splitHere = strpos($string, $first);
return rtrim(substr($string, $splitHere).','.substr($string, 0, $splitHere), ',');
}
echo MyWrap('1,2,3,4,5', '4');
?>
Output:
4,5,1,2,3
$pos = strpos($string,$first_number);
return substr($s,$pos).','.substr($s,0,$pos);
I believe I understand what you need - try this:
function numsWrap($firstNumber, $total) {
$newStr = "";
$inc = $firstNumber;
for($i = 0; $i < $total+1; $i++) {
if($i == 0) {
$newStr .= $inc;
} else {
if($inc == $total) {
$newStr .= "," . $inc;
$inc = 0;
} else {
$newStr .= "," . $inc;
}
}
$inc++;
}
return $newStr;
}
Usage:
echo numsWrap(5, 10);
5,6,7,8,9,10,1,2,3,4,5
function wrapAroundNeedle($myString, $myNeedle)
{
$index = strrpos($myString, $myNeedle);
return substr($myString, $index).",".substr($myString, 0, $index - 1);
}
How to roll your own. Note that strrpos only allows single characters for $needle in php 4.
string substr ( string $string , int $start [, int $length ] )
int strrpos ( string $haystack , string $needle [, int $offset = 0 ] )
http://php.net/manual/en/function.substr.php
http://php.net/manual/en/function.strrpos.php
Related
I came across Decode string problem which is given an encoded string s, decode it With rule:
N[encoded] => encoded*N.
Examples:
$input = "4[abc]";
// output: abcabcabcabc
$input = "ac3[ab]d";
// output: acabababd
$input = "a2[b3[cd]]";
// output: abcdcdcdbcdcdcd
I have tried solving it, using string manipulation with if conditions, It works only for two inputs, However it fails at last one when the given input has multiple encoded string.
$output = '';
$arr = str_split($input);
for ($i=0; $i < count($arr); $i++) {
$char = $arr[$i];//current character
if($char == '['){
$closed = strpos($input, ']');
$len = $closed - ($i+1);
$output .= str_repeat(substr($input, $i+1, $len), $prev);
$i = strpos($input, ']');
}elseif(ctype_digit($char)){
$prev = $char;
}else{
$output .= $char;
}
}
echo $output;
Is there any ways to solving it using this approach or another. Or only can be solved using stack?
Thank you for any idea can help solving this problem!
To solve nested [], you have to decode from the inside out. The solution uses preg_replace_callback until there is nothing left to replace.
function fkdecode($str){
while(true){
$newStr = preg_replace_callback('~(\d+)\[([^\[\]]+)\]~',
function($m){
return str_repeat($m[2],(int)$m[1]);
},
$str);
if($newStr == $str) break;
$str = $newStr;
}
return $str;
}
//test
$inputs = ["4[abc]", // output: abcabcabcabc
"ac3[ab]d", // output: acabababd
"a2[b3[cd]]", // output: abcdcdcdbcdcdcd
];
foreach($inputs as $input){
echo $input.' := '. fkdecode($input)."<br>\n";
}
Output:
4[abc] := abcabcabcabc
ac3[ab]d := acabababd
a2[b3[cd]] := abcdcdcdbcdcdcd
Use strpos() with offset ($i in your case) specified to decode multiple encoded string.
You could've used strlen instead of count. It's to avoid array to string conversion error. Also, you should take into consideration the case when N > 9.
$output = '';
for ($i = 0; $i < strlen($input); $i++) {
$char = $input[$i];//current character
if($char == '['){
$closed = strpos($input, ']', $i);
$len = $closed - ($i+1);
$output .= str_repeat(substr($input, $i+1, $len), $prev);
$i = strpos($input, ']', $i);
}elseif(ctype_digit($char)){
$end = strpos($input, '[', $i);
$len = $end - $i;
$prev = substr($input, $i, $len);
$i = strpos($input, '[', $i) - 1;
}else{
$output .= $char;
}
}
echo $output;
?>
BTW, this doesn't solve the nested []. You could use a stack to solve it. Hint: Check if there's a [ before $closed. Or use this non-O(n) approach.
I have a string like $str.
$str = "00016cam 321254300022cam 321254312315300020cam 32125433153";
I want to split it in array like this. The numbers before 'cam' is the string length.
$splitArray = ["00016cam 3212543", "00022cam 3212543123153", "00020cam 32125433153"]
I have tried following code:
$lengtharray = array();
while ($str != null)
{
$sublength = substr($str, $star, $end);
$star += (int)$sublength; // echo $star."<br>"; // echo $sublength."<br>";
if($star == $total)
{
exit;
}
else
{
}
array_push($lengtharray, $star); // echo
print_r($lengtharray);
}
You can try this 1 line solution
$str = explode('**', preg_replace('/\**cam/', 'cam', $str)) ;
If your string doesn't contain stars then I'm afraid you need to write a simple parser that will:
take characters from the left until it's not numeric
do substr having the length
repeat previous steps on not consumed string
<?php
$input = "00016cam 321254300022cam 321254312315300020cam 32125433153";
function parseArray(string $input)
{
$result = [];
while ($parsed = parseItem($input)) {
$input = $parsed['rest'];
$result[] = $parsed['item'];
}
return $result;
}
function parseItem(string $input)
{
$sLen = strlen($input);
$len = '';
$pos = 0;
while ($pos < $sLen && is_numeric($input[$pos])) {
$len .= $input[$pos];
$pos++;
}
if ((int) $len == 0) {
return null;
}
return [
'rest' => substr($input, $len),
'item' => substr($input, 0, $len)
];
}
var_dump(parseArray($input));
this code works for me. hope helps.
$str = "**00016**cam 3212543**00022**cam 3212543123153**00020**cam 32125433153";
$arr = explode("**", $str);
for ($i=1; $i < sizeof($arr); $i=$i+2)
$arr_final[]=$arr[$i].$arr[$i+1];
I have a string that that is an unknown length and characters.
I'd like to be able to truncate the string after x amount of characters.
For example from:
$string = "Hello# m#y name # is Ala#n Colem#n"
$character = "#"
$x = 4
I'd like to return:
"Hello# m#y name # is Ala#"
Hope I'm not over complicating things here!
Many thanks
I'd suggest explode-ing the string on #, then getting the 1st 4 elements in that array.
$string = "Hello# m#y name # is Ala#n Colem#n";
$character = "#";
$x = 4;
$split = explode($character, $string);
$split = array_slice($split, 0, $x);
$newString = implode($character, $split).'#';
function posncut( $input, $delim, $x ) {
$p = 0;
for( $i = 0; $i < $x; ++ $i ) {
$p = strpos( $input, $delim, $p );
if( $p === false ) {
return "";
}
++ $p;
}
return substr( $input, 0, $p );
}
echo posncut( $string, $character, $x );
It finds each delimiter in turn (strpos) and stops after the one you're looking for. If it runs out of text first (strpos returns false), it gives an empty string.
Update: here's a benchmark I made which compares this method against explode: http://codepad.org/rxTt79PC. Seems that explode (when used with array_pop instead of array_slice) is faster.
Something along these lines:
$str_length = strlen($string)
$character = "#"
$target_count = 4
$count = 0;
for ($i = 0 ; $i<$str_length ; $i++){
if ($string[$i] == $character) {
$count++
if($count == $target_count) break;
}
}
$result = sub_str($string,0,$i)
This question already has answers here:
Reverse the letters in each word of a string
(6 answers)
Closed 1 year ago.
This task has already been asked/answered, but I recently had a job interview that imposed some additional challenges to demonstrate my ability to manipulate strings.
Problem: How to reverse words in a string? You can use strpos(), strlen() and substr(), but not other very useful functions such as explode(), strrev(), etc.
Example:
$string = "I am a boy"
Answer:
I ma a yob
Below is my working coding attempt that took me 2 days [sigh], but there must be a more elegant and concise solution.
Intention:
1. get number of words
2. based on word count, grab each word and store into array
3. loop through array and output each word in reverse order
Code:
$str = "I am a boy";
echo reverse_word($str) . "\n";
function reverse_word($input) {
//first find how many words in the string based on whitespace
$num_ws = 0;
$p = 0;
while(strpos($input, " ", $p) !== false) {
$num_ws ++;
$p = strpos($input, ' ', $p) + 1;
}
echo "num ws is $num_ws\n";
//now start grabbing word and store into array
$p = 0;
for($i=0; $i<$num_ws + 1; $i++) {
$ws_index = strpos($input, " ", $p);
//if no more ws, grab the rest
if($ws_index === false) {
$word = substr($input, $p);
}
else {
$length = $ws_index - $p;
$word = substr($input, $p, $length);
}
$result[] = $word;
$p = $ws_index + 1; //move onto first char of next word
}
print_r($result);
//append reversed words
$str = '';
for($i=0; $i<count($result); $i++) {
$str .= reverse($result[$i]) . " ";
}
return $str;
}
function reverse($str) {
$a = 0;
$b = strlen($str)-1;
while($a < $b) {
swap($str, $a, $b);
$a ++;
$b --;
}
return $str;
}
function swap(&$str, $i1, $i2) {
$tmp = $str[$i1];
$str[$i1] = $str[$i2];
$str[$i2] = $tmp;
}
$string = "I am a boy";
$reversed = "";
$tmp = "";
for($i = 0; $i < strlen($string); $i++) {
if($string[$i] == " ") {
$reversed .= $tmp . " ";
$tmp = "";
continue;
}
$tmp = $string[$i] . $tmp;
}
$reversed .= $tmp;
print $reversed . PHP_EOL;
>> I ma a yob
Whoops! Mis-read the question. Here you go (Note that this will split on all non-letter boundaries, not just space. If you want a character not to be split upon, just add it to $wordChars):
function revWords($string) {
//We need to find word boundries
$wordChars = 'abcdefghijklmnopqrstuvwxyz';
$buffer = '';
$return = '';
$len = strlen($string);
$i = 0;
while ($i < $len) {
$chr = $string[$i];
if (($chr & 0xC0) == 0xC0) {
//UTF8 Characer!
if (($chr & 0xF0) == 0xF0) {
//4 Byte Sequence
$chr .= substr($string, $i + 1, 3);
$i += 3;
} elseif (($chr & 0xE0) == 0xE0) {
//3 Byte Sequence
$chr .= substr($string, $i + 1, 2);
$i += 2;
} else {
//2 Byte Sequence
$i++;
$chr .= $string[$i];
}
}
if (stripos($wordChars, $chr) !== false) {
$buffer = $chr . $buffer;
} else {
$return .= $buffer . $chr;
$buffer = '';
}
$i++;
}
return $return . $buffer;
}
Edit: Now it's a single function, and stores the buffer naively in reversed notation.
Edit2: Now handles UTF8 characters (just add "word" characters to the $wordChars string)...
My answer is to count the string length, split the letters into an array and then, loop it backwards. This is also a good way to check if a word is a palindrome. This can only be used for regular string and numbers.
preg_split can be changed to explode() as well.
/**
* Code snippet to reverse a string (LM)
*/
$words = array('one', 'only', 'apple', 'jobs');
foreach ($words as $d) {
$strlen = strlen($d);
$splits = preg_split('//', $d, -1, PREG_SPLIT_NO_EMPTY);
for ($i = $strlen; $i >= 0; $i=$i-1) {
#$reverse .= $splits[$i];
}
echo "Regular: {$d}".PHP_EOL;
echo "Reverse: {$reverse}".PHP_EOL;
echo "-----".PHP_EOL;
unset($reverse);
}
Without using any function.
$string = 'I am a boy';
$newString = '';
$temp = '';
$i = 0;
while(#$string[$i] != '')
{
if($string[$i] == ' ') {
$newString .= $temp . ' ';
$temp = '';
}
else {
$temp = $string[$i] . $temp;
}
$i++;
}
$newString .= $temp . ' ';
echo $newString;
Output: I ma a yob
I'm looking for a way to rotate a string to the left N times. Here are some examples:
Let the string be abcdef
if I rotate it 1 time I want
bcdefa
if I rotate it 2 time I want
cdefab
if I rotate it 3 time I want
defabc
.
.
If I rotate the string its string
length times, I should get back the
original string.
$rotated = substr($str, $n) . substr($str, 0, $n);
Here is one variant that allows arbitrary shifting to the left and right, regardless of the length of the input string:
function str_shift($str, $len) {
$len = $len % strlen($str);
return substr($str, $len) . substr($str, 0, $len);
}
echo str_shift('abcdef', -2); // efabcd
echo str_shift('abcdef', 2); // cdefab
echo str_shift('abcdef', 11); // fabcde
function rotate_string ($str, $n)
{
while ($n > 0)
{
$str = substr($str, 1) . substr($str, 0, 1);
$n--;
}
return $str;
}
There is no standard function for this but is easily implemented.
function rotate_left($s) {
return substr($s, 1) . $s[0];
}
function rotate_right($s) {
return substr($s, -1) . substr($s, 0, -1);
}
You could extend this to add an optional parameter for the number of characters to rotate.
function rotate_string($str) {
for ($i=1; $i<strlen($str)+1;$i++) {
#$string .= substr($str , strlen($str)-$i , 1);
}
return $string;
}
echo rotate_string("string"); //gnirts
Use this code
<?php
$str = "helloworld" ;
$res = string_function($str,3) ;
print_r ( $res) ;
function string_function ( $str , $count )
{
$arr = str_split ( $str );
for ( $i=0; $i<$count ; $i++ )
{
$element = array_pop ( $arr ) ;
array_unshift ( $arr, $element ) ;
}
$result=( implode ( "",$arr )) ;
return $result;
}
?>
You can also get N rotated strings like this.
$str = "Vijaysinh";
$arr1 = str_split($str);
$rotated = array();
$i=0;
foreach($arr1 as $a){
$t = $arr1[$i];
unset($arr1[$i]);
$rotated[] = $t.implode($arr1);
$arr1[$i] = $t;
$i++;
}
echo "<pre>";print_r($rotated);exit;