Is there any built-in PHP function through which I can count the sum of indexes of letters of the alphabet found in a string?
<?php
$a = "testword";
echo "Count of Characters is: " . strlen($a);
?>
Now I want to get a cumulative "total" of this word.
e.g.
A is the first letter of the alphabet so it maps to 1
B is the second letter of the alphabet so it maps to 2
C is the third letter of the alphabet so it maps to 3
D is the fourth letter of the alphabet so it maps to 4
So the word ABCD gives 1+2+3+4=10
Similarly I need a function for "testword" or any word.
function WordSum($word)
{
$cnt = 0;
$word = strtoupper(trim($word));
$len = strlen($word);
for($i = 0; $i < $len; $i++)
{
$cnt += ord($word[$i]) - 64;
}
return $cnt;
}
var_dump(WordSum("testword"));
Just to show a totally different method, for the sheer pleasure of demonstrating some of PHP's array functions:
$data = "testword";
$testResult = array_values(array_merge(array_fill_keys(range('A','Z'),
0
),
array_count_values(str_split(strtoupper($data)
)
)
)
);
$wordCount = 0;
foreach($testResult as $letterValue => $letterCount) {
$wordCount += ++$letterValue * $letterCount;
}
var_dump($wordCount);
$a = "test";
$b = "word";
echo (strlen($a) + strlen($b));
Related
I'd like the code to output index 6 since d is the starting point in terms of the longest identical consecutive portion in the string.
Not sure what I'm doing wrong here but it's currently returning 3 instead. Seems like I'm going in the right direction but something is missing but I can't pinpoint what.
Any feedback is appreciated! :)
$str = "abbcccddddcccbba";
$array = preg_split('/(.)(?!\1|$)\K/', $str);
$lengths = array_map('strlen', $array);
$maxLength = max($lengths);
$ans = array_search($maxLength, $lengths); // returns 3 but need it to return 6
echo $ans;
$lengths = array_map('strlen', $array);
Above line has only lengths of adjacent similar characters. array_search on max of those lengths will only yield the index where the maximum length is stored. It is totally unrelated with getting the index 6 of your string. If you still wish to get it, you will have to array_sum till that index to get the start index in the actual string.
Snippet:
<?php
$str = "abbcccddddcccbba";
$array = preg_split('/(.)(?!\1|$)\K/', $str);
$lengths = array_map('strlen', $array);
$maxLength = max($lengths);
array_splice($lengths,array_search($maxLength, $lengths));
$ans = array_sum($lengths);
echo $ans;
Online Demo
Alternate Solution:
I would write a simple for loop that uses 2 pointers to keep track of start index of similar characters and record the frequency and start index whenever it is greater than max frequency.
Snippet:
<?php
$str = "abbcccddddcccbba";
$len = strlen($str);
$maxF = 1;
$maxIdx = $startIdx = 0;
for($i = 1; $i < $len; ++$i){
if($str[ $i ] != $str[ $i - 1] || $i === $len - 1){
if($str[ $i ] === $str[ $i - 1] && $i === $len - 1) $i++;
if($maxF < $i - $startIdx){
$maxF = $i - $startIdx;
$maxIdx = $startIdx;
}
$startIdx = $i;
}
}
echo $maxIdx;
Online Demo
I am trying to calculate a few 'streaks', specifically the highest number of wins and losses in a row, but also most occurences of games without a win, games without a loss.
I have a string that looks like this; 'WWWDDWWWLLWLLLL'
For this I need to be able to return:
Longest consecutive run of W charector (i will then replicate for L)
Longest consecutive run without W charector (i will then replicate for L)
I have found and adapted the following which will go through my array and tell me the longest sequence, but I can't seem to adapt it to meet the criteria above.
All help and learning greatly appreciated :)
function getLongestSequence($sequence){
$sl = strlen($sequence);
$longest = 0;
for($i = 0; $i < $sl; )
{
$substr = substr($sequence, $i);
$len = strspn($substr, $substr{0});if($len > $longest)
$longest = $len;
$i += $len;
}
return $longest;
}
echo getLongestSequence($sequence);
You can use a regular expression to detect sequences of identical characters:
$string = 'WWWDDWWWLLWLLLL';
// The regex matches any character -> . in a capture group ()
// plus as much identical characters as possible following it -> \1+
$pattern = '/(.)\1+/';
preg_match_all($pattern, $string, $m);
// sort by their length
usort($m[0], function($a, $b) {
return (strlen($a) < strlen($b)) ? 1 : -1;
});
echo "Longest sequence: " . $m[0][0] . PHP_EOL;
You can achieve the maximum count of consecutive character in a particular string using the below code.
$string = "WWWDDWWWLLWLLLL";
function getLongestSequence($str,$c) {
$len = strlen($str);
$maximum=0;
$count=0;
for($i=0;$i<$len;$i++){
if(substr($str,$i,1)==$c){
$count++;
if($count>$maximum) $maximum=$count;
}else $count=0;
}
return $maximum;
}
$match="W";//change to L for lost count D for draw count
echo getLongestSequence($string,$match);
In PHP, given
the final string length
the range of characters it can use
min consecutive repetition count possible
how can you calculate the number of matches that fits these criteria?To draw a better picture…
$range = array('a','b','c');
$length = 2; // looking for 2 digit results
$minRep = 2; // with >=2 consecutive characters
// aa,bb,cc = 3 possibilities
another one:
$range = array('a','b','c');
$length = 3; // looking for 3 digit results
$minRep = 2; // with >=2 consecutive characters
// aaa,aab,aac,baa,caa
// bbb,bba,bbc,abb,cbb
// ccc,cca,ccb,acc,bcc
// 5 + 5 + 5 = 15 possibilities
// note that combos like aa,bb,cc are not included
// because their length is smaller than $length
last one:
$range = array('a','b','c');
$length = 3; // looking for 3 digit results
$minRep = 3; // with >=3 consecutive characters
// aaa,bbb,ccc = 3 possibilities
So basically, in the 2nd example the 3rd criterion made it catch e.g. [aa]b in aab because a was repeating consecutively more than once, whereas [a]b[a] wouldn't be a match because those a's are separate.
Needless to say, none of the variables is static.
Got it. All credit to leonbloy #mathexchange.com.
/* The main function computes the number of words that do NOT contain
* a character repetition of length $minRep (or more). */
function countStrings($rangeLength, $length, $minRep, &$results = array())
{
if (!isset($results[$length]))
{
$b = 0;
if ($length < $minRep)
$b = pow($rangeLength, $length);
else
{
for ($i = 1; $i < $minRep; $i++)
$b += countStrings($rangeLength, $length - $i, $minRep, $results);
$b *= $rangeLength - 1;
}
$results[$length] = $b;
}
return $results[$length];
}
/* This one answers directly the question. */
function printNumStringsRep($rangeLength, $length, $minRep)
{
$n = (pow($rangeLength, $length)
- countStrings($rangeLength, $length, $minRep));
echo "Size of alphabet : $rangeLength<br/>"
. "Size of string : $length<br/>"
. "Minimal repetition : $minRep<br/>"
. "<strong>Number of words : $n</strong>";
}
/* Prints :
*
Size of alphabet : 3
Size of string : 3
Minimal repetition : 2
Number of words : 15
*
*/
printNumStringsRep(3, 3, 2);
I think it is best to handle this with math.
$range = array('a','b','c');
$length = 3; // looking for 3 digit results
$minRep = 2; // with >=2 consecutive characters
$rangeLength = count($range);
$count = (pow($rangeLength,$length-$minRep+1) * ($length-$minRep+1)) - ($rangeLength * ($length-$minRep)); // is the result
Now, $count is getting true result for three situation. But it may not be general formula and need to improve.
Try to explain it:
pow($rangeLength,$length-$minRep+1)
in this, we count repetitive characters like as one. For instance, in second example that you gave, we think in aab, aa is a one character. Because, two characters need to change together. We think now there is two character like xy. So there is same possibilities for both character a, b, and c namely 3 ($rangeLength) possible value for two characters($length-$minRep+1). So 3^2=9 is possible situations for second example.
We calculate 9 is for just xy not yx. For this, we multiply length of xy ($length-$minRep+1). And then we have 18.
It can be seemed that we calculated the result, but there is a repeat in our calculation. We didn't reckon with this situation: xy => aaa and yx => aaa. For this, we calculate and substract repeated results
- ($rangeLength * ($length-$minRep))
So after this, we get result.
As i said begining of the description, this formula may need to improve.
With Math, work becomes really complex. But, there is always a way, even not beautiful as much as Math. We can create all possible strings with php and control them with regexp like below:
$range = array('a','b','c');
$length = 3;
$minRep = 2;
$rangeLength = count($range);
$createdStrings = array();
$matchedStrings = array();
function calcIndex(){
global $range;
global $length;
global $rangeLength;
static $ret;
$addTrigger = false;
// initial values
if(is_null($ret)){
$ret = array_fill(0, $length, 0);
return $ret;
}
for($i=$length-1;$i>=0;$i--){
if($ret[$i] == ($rangeLength-1)) {
if($i==0) return false;
$ret[$i] = 0;
}
else {
$ret[$i]++;
break;
}
}
return $ret;
}
function createPattern()
{
global $minRep;
$patt = '/(.)\\1{'.($minRep-1).'}/';
return $patt;
}
$pattern = createPattern();
while(1)
{
$index = calcIndex();
if($index === false) break;
$string = '';
for($i=0;$i<$length;$i++)
{
$string .= $range[$index[$i]];
}
if(!in_array($string, $createdStrings)){
$createdStrings[] = $string;
if(preg_match($pattern, $string)){
$matchedStrings[] = $string;
}
}
}
echo count($createdStrings).' is created:';
var_dump($createdStrings);
echo count($matchedStrings).'strings is matched:';
var_dump($matchedStrings);
i need to do a simple loop in php to get char from a to z.. something like:
for($i=0;$i<aNumber;$i++)
echo "char = ".intToChar($i)."<br>";
where aNumber is less then 20
You can create an array of characters easily with range [docs]:
$chars = range('a', 'z');
Or if you really only want to print them:
echo implode('<br />', range('a', 'z'));
You need understand ASCII table. See in this link. Codes for A - Z is 65 - 90 and a - z is 97 - 122.
for($i = 97; $i <= 122; $i++)
echo chr($i);
I SOLVED IN THIS WAY:
$i = 0;
$char = 'a';
$aNumber = xx;
while($i<$aNumber){
echo $char."<br>";
$char++;
$i++;
}
To return character specified by ASCII code/number use chr function. Since you want to loop from 0 to 20, then you need to add 97 to $i, 97 is ASCII code for letter a:
for($i=0;$i<$aNumber;$i++)
echo "char = ".chr($i+97)."<br>"; // + 97 because it is ASCII 'a'
If you just want to loop through those letters you can do it like this:
for($i = ord('a'); $i < ord('z'); $i++)
echo "char = ".chr($i)."<br>";
Additionally if you just want to get array of those characters you can use range function:
$chars = range('a', 'z');
I am trying to write a function that will replace characters in a string with their HTML entity encoded equivalent.
I want it to be able to go through all the possible combinations for the given string, for example:
go one-by-one
then combo i.e.. 2 at a time, then three at a time, till you get length at a time
then start in combo split, i.e.. first and last, then first and second to last
then first and last two, fist and second/third last
So for the characters "abcd" it would return:
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
etc.......... so on and so forth till there are no other combinations
Any ideas, or has anyone seen a function somewhere I could modify for this purpose?
loop from 0 to 2^length - 1. On each step, if Nth bit of the loop counter is 1, encode the Nth character
$str = 'abcd';
$len = strlen($str);
for($i = 0; $i < 1 << $len; $i++) {
$p = '';
for($j = 0; $j < $len; $j++)
$p .= ($i & 1 << $j) ? '&#' . ord($str[$j]) . ';' : $str[$j];
echo $p, "\n";
}
There are 2^n combinations, so this will get huge fast. This solution will only work as long as it fits into PHP's integer size. But really who cares? A string that big will print so many results you'll spend your entire life looking at them.
<?php
$input = 'abcd';
$len = strlen($input);
$stop = pow(2, $len);
for ($i = 0; $i < $stop; ++$i)
{
for ($m = 1, $j = 0; $j < $len; ++$j, $m <<= 1)
{
echo ($i & $m) ? '&#'.ord($input[$j]).';' : $input[$j];
}
echo "\n";
}
How about this?
<?php
function permutations($str, $n = 0, $prefix = "") {
if ($n == strlen($str)) {
echo "$prefix\n";
return;
}
permutations($str, $n + 1, $prefix . $str[$n]);
permutations($str, $n + 1, $prefix . '&#' . ord($str[$n]) . ';');
}
permutations("abcd");
?>