I'm looking for a function that searchs a word, like "ONE" in a multidimentional array, but I need to find the word in all the 8 ways, example "from left to right, from right to left, up to down, down to up and diagonal upper to diagonal lower"
The array's size may vary (3x3, 1x10, 5x5, 7x2).
I already tried to make this in nested if's, but I don't like that way.
I need to count how many times the word appears in my array, I dont know if exist a php or laravel function that resolve this problem or I must create one
I translate this C++ code into PHP. It works fine and returns the same result as C++ code.
/**
* This function searches in all 8-direction from point
* #param array $grid
* #param int $row in grid[][]
* #param int $col in grid[][]
* #param string $word
* #return bool
*/
function search2D(array $grid, int $row, int $col, string $word): bool {
$x = [-1, -1, -1, 0, 0, 1, 1, 1];
$y = [-1, 0, 1, -1, 1, -1, 0, 1];
// Rows and columns in given grid
$R = count($grid);
$C = count($grid[0]);
// If first character of word doesn't match with
// given starting point in grid.
if ($grid[$row][$col]!= $word[0])
return false;
$len = strlen($word);
for ($dir = 0; $dir < 8; $dir++)
{
// Initialize starting point for current direction
$rd = $row + $x[$dir];
$cd = $col + $y[$dir];
// First character is already checked, match remaining
// characters
for ($k = 1; $k < $len; $k++)
{
// If out of bound break
if ($rd >= $R || $rd < 0 || $cd >= $C || $cd < 0)
break;
// If not matched, break
if ($grid[$rd][$cd] != $word[$k])
break;
// Moving in particular direction
$rd += $x[$dir];
$cd += $y[$dir];
}
// If all character matched, then value of must
// be equal to length of word
if ($k == $len)
return true;
}
return false;
}
/**
* Searches given word in a given matrix in all 8 directions
* #param array $grid
* #param string $word
*/
function patternSearch(array $grid, string $word):void {
// Rows and columns in given grid
$R = count($grid);
$C = count($grid[0]);
// Consider every point as starting point and search
// given word
for ($row = 0; $row < $R; $row++)
for ($col = 0; $col < $C; $col++)
if (search2D($grid, $row, $col, $word))
echo "pattern found at {$row}, {$col}" . "\r\n";
}
$grid = [
['G','E','E','K','S','F','O','R','G','E','E','K','S'],
['G','E','E','K','S','Q','U','I','Z','G','E','E','K'],
['I','D','E','Q','A','P','R','A','C','T','I','C','E'],
];
patternSearch($grid, 'GEEKS');
echo "\r\n";
patternSearch($grid, 'EEE');
Output:
pattern found at 0, 0
pattern found at 0, 8
pattern found at 1, 0
pattern found at 0, 2
pattern found at 0, 10
pattern found at 2, 2
pattern found at 2, 12
function searchWord($array, $word) {
$rows = count($array);
$cols = count($array[0]);
$directions = [
[-1, -1], [-1, 0], [-1, 1],
[0, -1], [0, 1],
[1, -1], [1, 0], [1, 1]
];
$count = 0;
for ($i = 0; $i < $rows; $i++) {
for ($j = 0; $j < $cols; $j++) {
foreach ($directions as $dir) {
$k = 0;
$x = $i;
$y = $j;
while (isset($array[$x][$y]) && $array[$x][$y] === $word[$k]) {
$x += $dir[0];
$y += $dir[1];
$k++;
if ($k === strlen($word)) {
$count++;
break;
}
}
}
}
}
return $count;
}
The function takes in two parameters: $array which is the multi-dimensional array and $word which is the word to be searched.
The function first initializes the $directions array which contains 8 possible directions to search the word.
Then, it loops through the array and checks each character in the array. For each character, it loops through all 8 directions to see if the word can be found by following that direction. If the word is found, the count is incremented. The loop continues until all directions for all characters have been checked.
Finally, the function returns the count of the number of times the word appears in the array.
Related
I need to write a function who prints Look-and-Say Sequence hat takes a number as nth iteration.
The first iteration is 0 and output has to contain every previous lines. For example, if we test sequence(3), the result need to be :
1
11
21
1211
SO I made a function for each line and another to stack them but it doesn't work =/
Here's my code
<?php
function Conway($n)
{
if ($n == 1)
return "1";
if ($n == 2)
return "11";
for ($i = 3; $i <= $n; $i++) {
$str = "11";
$str = $str.'$';
$len = strlen($str);
$cnt = 1;
$tmp = "";
for ($j = 1; $j < $len; $j++)
{
if ($str[$j] != $str[$j - 1])
{
$tmp = $tmp.$cnt + 0;
$tmp = $tmp. $str[$j - 1];
$cnt = 1;
}
else $cnt++;
}
$str = $tmp;
}
return $str;
}
function sequence($nth) {
for ($i = 1; $i <= $nth+1; $i++)
do {
echo Conway($i)."\n";
} while ($i > $nth+1);
}
As explained here en.wikipedia.org/wiki/Look-and-say_sequence, the idea is to construct a string based on the previous constructed string (in a loop):
To generate a member of the sequence from the previous member, read
off the digits of the previous member, counting the number of digits
in groups of the same digit. For example:
1 is read off as "one 1" or 11.
11 is read off as "two 1s" or 21.
21 is read off as "one 2, one 1" or 1211.
1211 is read off as "one 1, one 2, two 1s" or 111221.
111221 is read off as "three 1s, two 2s, one 1" or 312211.
An attempt to solve this problem, we'll have a function called lookAndSay($n) that accepts a number $n. Basically, that function will have a loop that runs $n times.
To simplify things, we'll have a another function, let's call it tokenize($str), that will basically count the occurrence of a number, concatenates that count to the number (like 31 where 3 is the number of occurrences of the number 1), repeat until all the numbers in the string $str are dealt with.
A usage of that function can result in (for example):
tokenize('11'); // returns: '21'
Our main function, lookAndSay($n), will call tokenize($str) after making some initialization and in the end will return the resulting string.
Here's a code sample illustrating what's being said:
/**
* A function that generate look-and-say sequence based on a number "$n"
*
* #param int $n
* #return string
*/
function lookAndSay(int $n): string {
if ($n <= 1) return '1';
/** "$lastSeq" will hold the latest sequence tokenized by "tokenize" function */
$r = $lastSeq = '1';
/** loop based on "$n" and construct the final string along the way */
while($n-- > 0) $r .= ' '.($lastSeq = tokenize($lastSeq));
/** return the look-and-say string for the number "$n" */
return $r;
}
/**
* A function that "tokenizes" a string of numbers
* and return a string having the format "CN" where C is the number of occurrences of a number N in the string
*
* #param string $str
* #return string
*/
function tokenize(string $str): string {
/** will hold the string of tokens that will be returned after the function finishes */
$r = '';
/** holds the count of a number in the string $str */
$c = 1;
for ($i = 0; $i < strlen($str); $i++) {
/** we still count the number of occurrences of the same number "$str[$i]" ... */
if($str[$i] == ($str[$i + 1] ?? '')) {
/** increment the count and skip the rest of the loop */
$c++;
continue;
}
/** at this point we have the count for "$str[$i]" number so we concatenate the result to the final string and reset the count to "1" to prepare it for the next number (if any) */
($r .= $c.$str[$i]) && ($c = 1);
}
/** return the "tokenized" string */
return $r;
}
A call to lookAndSay could result in:
echo lookAndSay(3); // prints: 1 11 21 1211
Also here's a live demo of the above attempt.
Is that you looking for ?
function sequence($str) {
$str .= '';
$len = strlen($str);
$count= 0;
$result= '';
$temp= $str[0];
for($i=0;$i<$len;$i++) {
if($temp!=$str[$i]) {
$result.=$count.$temp;
$temp = $str[$i];
$count=1;
} else {
$count++;
}
}
$result.=$count.$temp;
return $result;
}
$num = 1;
echo "$num\n";
for($i=0;$i<3;$i++) {
$num=sequence($num);
print $num."\n";
}
output 1 11 21 1211
Given an array such as the following
$array = ('1', '2', '3', '4', '5', '6', '7');
I'm looking for a method to generate all possible combinations, with a minimum number of elements required in each combination r. (eg if r = 5 then it will return all possible combinations containing at least 5 elements)
Combinations of k out of n items can be defined recursively using the following function:
function combinationsOf($k, $xs){
if ($k === 0)
return array(array());
if (count($xs) === 0)
return array();
$x = $xs[0];
$xs1 = array_slice($xs,1,count($xs)-1);
$res1 = combinationsOf($k-1,$xs1);
for ($i = 0; $i < count($res1); $i++) {
array_splice($res1[$i], 0, 0, $x);
}
$res2 = combinationsOf($k,$xs1);
return array_merge($res1, $res2);
}
The above is based on the recursive definition that to choose k out n elements, one can fix an element x in the list, and there are C(k-1, xs\{x}) combinations that contain x (i.e. res1), and C(k,xs\{xs}) combinations that do not contain x (i.e. res2 in code).
Full example:
$array = array('1', '2', '3', '4', '5', '6', '7');
function combinationsOf($k, $xs){
if ($k === 0)
return array(array());
if (count($xs) === 0)
return array();
$x = $xs[0];
$xs1 = array_slice($xs,1,count($xs)-1);
$res1 = combinationsOf($k-1,$xs1);
for ($i = 0; $i < count($res1); $i++) {
array_splice($res1[$i], 0, 0, $x);
}
$res2 = combinationsOf($k,$xs1);
return array_merge($res1, $res2);
}
print_r ($array);
print_r(combinationsOf(5,$array));
//print_r(combinationsOf(5,$array)+combinationsOf(6,$array)+combinationsOf(7,$array));
A combination can be expressed as
nCr = n! / (r! - (n - r)!)
First, we determine $n as the number of elements in the array. And $r is the minimum number of elements in each combination.
$a = ['1', '2', '3', '4', '5', '6', '7']; // the array of elements we are interested in
// Determine the `n` and `r` in nCr = n! / (r! * (n-r)!)
$r = 5;
$n = count($a);
Next, we determine $max as the maximum number that can be represented by $n binary digits. That is, if $n = 3, then $max = (111)2 = 7. To do this, we first create a empty string $maxBinary and add $n number of 1s to it. We then convert it to decimal, and store it in $max.
$maxBinary = "";
for ($i = 0; $i < $n; $i++)
{
$maxBinary .= "1";
}
$max = bindec($maxBinary); // convert it into a decimal value, so that we can use it in the following for loop
Then, we list out every binary number from 0 to $max and store those that have more than $r number of 1s in them.
$allBinary = array(); // the array of binary numbers
for ($i = 0; $i <= $max; $i++)
{
if (substr_count(decbin($i), "1") >= $r) // we count the number of ones to determine if they are >= $r
{
// we make the length of the binary numbers equal to the number of elements in the array,
// so that it is easy to select elements from the array, based on which of the digits are 1.
// we do this by padding zeros to the left.
$temp = str_pad(decbin($i), $n, "0", STR_PAD_LEFT);
$allBinary[] = $temp;
}
}
Then, we use the same trick as above to select elements for our combination. I believe the comments explain enough.
$combs = array(); // the array for all the combinations.
$row = array(); // the array of binary digits in one element of the $allBinary array.
foreach ($allBinary as $key => $one)
{
$combs[$key] = "";
$row = str_split($one); // we store the digits of the binary number individually
foreach ($row as $indx => $digit)
{
if ($digit == '1') // if the digit is 1, then the corresponding element in the array is part of this combination.
{
$combs[$key] .= $a[$indx]; // add the array element at the corresponding index to the combination
}
}
}
And that is it. You are done!
Now if you have something like
echo count($combs);
then it would give you 29.
Additional notes:
I read up on this only after seeing your question, and as a newcomer, I found these useful:
Wikipedia - http://en.wikipedia.org/wiki/Combination
Php recursion to get all possibilities of strings
Algorithm to return all combinations of k elements from n
Also, here are some quick links to the docs, that should help people who see this in the future:
http://php.net/manual/en/function.decbin.php
http://php.net/manual/en/function.bindec.php
http://php.net/manual/en/function.str-pad.php
function arrToBit(Array $element) {
$bit = '';
foreach ($element as $e) {
$bit .= '1';
}
$length = count($element);
$num = bindec($bit);
$back = [];
while ($num) {
$back[] = str_pad(decbin($num), $length, '0', STR_PAD_LEFT);
$num--;
}
//$back[] = str_pad(decbin(0), $length, '0', STR_PAD_LEFT);
return $back;
}
function bitToArr(Array $element, $bit) {
$num = count($element);
$back = [];
for ($i = 0; $i < $num; $i++) {
if (substr($bit, $i, 1) == '1') {
$back[] = $element[$i];
}
}
return $back;
}
$tags = ['a', 'b', 'c'];
$bits = arrToBit($tags);
$combination = [];
foreach ($bits as $b) {
$combination[] = bitToArr($tags, $b);
}
var_dump($combination);
$arr = array(1,2,3,4,5,6);
$check_value =[];
$all_values = [];
CONT:
$result = $check_value;
shuffle($arr);
$check_value = array_slice($arr,0,3);
if(count($check_value) == 3 && serialize($check_value) !== serialize($result)){
$result = $check_value;
array_push($all_values,$result);
goto CONT;
}
print_r($all_values);
This question already has answers here:
PHP get the item in an array that has the most duplicates
(2 answers)
Closed 1 year ago.
I have an array of numbers like this:
$array = array(1,1,1,4,3,1);
How do I get the count of most repeated value?
This should work:
$count=array_count_values($array);//Counts the values in the array, returns associatve array
arsort($count);//Sort it from highest to lowest
$keys=array_keys($count);//Split the array so we can find the most occuring key
echo "The most occuring value is $keys[0][1] with $keys[0][0] occurences."
I think array_count_values function can be useful to you. Look at this manual for details : http://php.net/manual/en/function.array-count-values.php
You can count the number of occurrences of values in an array with array_count_values:
$counts = array_count_values($array);
Then just do a reverse sort on the counts:
arsort($counts);
Then check the top value to get your mode.
$mode = key($counts);
If your array contains strings or integers only you can use array_count_values and arsort:
$array = array(1, 1, 1, 4, 3, 1);
$counts = array_count_values($array);
arsort($counts);
That would leave the most used element as the first one of $counts. You can get the count amount and value afterwards.
It is important to note that if there are several elements with the same amount of occurrences in the original array I can't say for sure which one you will get. Everything depends on the implementations of array_count_values and arsort. You will need to thoroughly test this to prevent bugs afterwards if you need any particular one, don't make any assumptions.
If you need any particular one, you'd may be better off not using arsort and write the reduction loop yourself.
$array = array(1, 1, 1, 4, 3, 1);
/* Our return values, with some useless defaults */
$max = 0;
$max_item = $array[0];
$counts = array_count_values($array);
foreach ($counts as $value => $amount) {
if ($amount > $max) {
$max = $amount;
$max_item = $value;
}
}
After the foreach loop, $max_item contains the last item that appears the most in the original array as long as array_count_values returns the elements in the order they are found (which appears to be the case based on the example of the documentation). You can get the first item to appear the most in your original array by using a non-strict comparison ($amount >= $max instead of $amount > $max).
You could even get all elements tied for the maximum amount of occurrences this way:
$array = array(1, 1, 1, 4, 3, 1);
/* Our return values */
$max = 0;
$max_items = array();
$counts = array_count_values($array);
foreach ($counts as $value => $amount) {
if ($amount > $max) {
$max = $amount;
$max_items = array($value);
} elif ($amount = $max) {
$max_items[] = $value;
}
}
$vals = array_count_values($arr);
asort($vals);
//you may need this end($vals);
echo key($vals);
I cant remember if asort sorts asc or desc by default, you can see the comment in the code.
<?php
$arrrand = '$arr = array(';
for ($i = 0; $i < 100000; $i++)
{
$arrrand .= rand(0, 1000) . ',';
}
$arrrand = substr($arrrand, 0, -1);
$arrrand .= ');';
eval($arrrand);
$start1 = microtime();
$count = array_count_values($arr);
$end1 = microtime();
echo $end1 - $start1;
echo '<br>';
$start2 = microtime();
$tmparr = array();
foreach ($arr as $key => $value);
{
if (isset($tmparr[$value]))
{
$tmparr[$value]++;
} else
{
$tmparr[$value] = 1;
}
}
$end2 = microtime();
echo $end2 - $start2;
Here check both solutions:
1 by array_count_values()
and one by hand.
<?php
$input = array(1,2,2,2,8,9);
$output = array();
$maxElement = 0;
for($i=0;$i<count($input);$i++) {
$count = 0;
for ($j = 0; $j < count($input); $j++) {
if ($input[$i] == $input[$j]) {
$count++;
}
}
if($count>$maxElement){
$maxElement = $count;
$a = $input[$i];
}
}
echo $a.' -> '.$maxElement;
The output will be 2 -> 3
$arrays = array(1, 2, 2, 2, 3, 1); // sample array
$count=array_count_values($arrays); // getting repeated value with count
asort($count); // sorting array
$key=key($count);
echo $arrays[$key]; // get most repeated value from array
String S;
Scanner in = new Scanner(System.in);
System.out.println("Enter the String: ");
S = in.nextLine();
int count =1;
int max = 1;
char maxChar=S.charAt(0);
for(int i=1; i <S.length(); i++)
{
count = S.charAt(i) == S.charAt(i - 1) ? (count + 1):1;
if(count > max)
{
max = count;
maxChar = S.charAt(i);
}
}
System.out.println("Longest run: "+max+", for the character "+maxChar);
here is the solution
class TestClass {
public $keyVal;
public $keyPlace = 0;
//put your code here
public function maxused_num($array) {
$temp = array();
$tempval = array();
$r = 0;
for ($i = 0; $i <= count($array) - 1; $i++) {
$r = 0;
for ($j = 0; $j <= count($array) - 1; $j++) {
if ($array[$i] == $array[$j]) {
$r = $r + 1;
}
}
$tempval[$i] = $r;
$temp[$i] = $array[$i];
}
//fetch max value
$max = 0;
for ($i = 0; $i <= count($tempval) - 1; $i++) {
if ($tempval[$i] > $max) {
$max = $tempval[$i];
}
}
//get value
for ($i = 0; $i <= count($tempval) - 1; $i++) {
if ($tempval[$i] == $max) {
$this->keyVal = $tempval[$i];
$this->keyPlace = $i;
break;
}
}
// 1.place holder on array $this->keyPlace;
// 2.number of reapeats $this->keyVal;
return $array[$this->keyPlace];
}
}
$catch = new TestClass();
$array = array(1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 1, 2, 3, 1, 1, 2, 5, 7, 1, 9, 0, 11, 22, 1, 1, 22, 22, 35, 66, 1, 1, 1);
echo $catch->maxused_num($array);
I've created an array with $my_array = range(1,3) and I'd like to have an array created containing all the permutations of this one (1,2,3 1,3,2 2,1,3 ..).
The second number in the range function can change (it could be 4, 5, 7, 50 instead of 3).
Code from Christer's blog o' fun :
function permute($str) {
/* If we only have a single character, return it */
if (strlen($str) < 2) {
return array($str);
}
/* Initialize the return value */
$permutations = array();
/* Copy the string except for the first character */
$tail = substr($str, 1);
/* Loop through the permutations of the substring created above */
foreach (permute($tail) as $permutation) {
/* Get the length of the current permutation */
$length = strlen($permutation);
/* Loop through the permutation and insert the first character of the original
string between the two parts and store it in the result array */
for ($i = 0; $i <= $length; $i++) {
$permutations[] = substr($permutation, 0, $i) . $str[0] . substr($permutation, $i);
}
}
/* Return the result */
return $permutations;
}
$array_of_natural_numbers = range(1, 5);
$string_of_natural_numbers = implode("",$array_of_natural_numbers);
$permutations = permute($string_of_natural_numbers);
Given:
$this->objPHPExcelReader = PHPExcel_IOFactory::createReaderForFile($this->config['file']);
$this->objPHPExcelReader->setLoadSheetsOnly(array($this->config['worksheet']));
$this->objPHPExcelReader->setReadDataOnly(true);
$this->objPHPExcel = $this->objPHPExcelReader->load($this->config['file']);
I can iterate through the rows like this but it is very slow, i.e. in a 3MB Excel file with a worksheet that has "EL" columns, it takes about 1 second per row:
foreach ($this->objPHPExcel->setActiveSheetIndex(0)->getRowIterator() as $row)
{
$dataset = array();
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false);
foreach ($cellIterator as $cell)
{
if (!is_null($cell))
{
$dataset[] = $cell->getCalculatedValue();
}
}
$this->datasets[] = $dataset;
}
When I iterate like this, it it significantly faster (approx. 2000 rows in 30 seconds), but I will have to convert the letters e.g. "EL" to a number:
$highestColumm = $this->objPHPExcel->setActiveSheetIndex(0)->getHighestColumn(); // e.g. "EL"
$highestRow = $this->objPHPExcel->setActiveSheetIndex(0)->getHighestRow();
$number_of_columns = 150; // TODO: figure out how to get the number of cols as int
for ($row = 1; $row < $highestRow + 1; $row++) {
$dataset = array();
for ($column = 0; $column < $number_of_columns; $column++) {
$dataset[] = $this->objPHPExcel->setActiveSheetIndex(0)->getCellByColumnAndRow($column, $row)->getValue();
}
$this->datasets[] = $dataset;
}
Is there a way to get the highest column as an integer (e.g. "28") instead of in Excel-styled letters (e.g. "AB")?
$colNumber = PHPExcel_Cell::columnIndexFromString($colString);
returns 1 from a $colString of 'A', 26 from 'Z', 27 from 'AA', etc.
and the (almost) reverse
$colString = PHPExcel_Cell::stringFromColumnIndex($colNumber);
returns 'A' from a $colNumber of 0, 'Z' from 25, 'AA' from 26, etc.
EDIT
A couple of useful tricks:
There is a toArray() method for the worksheet class:
$this->datasets = $this->objPHPExcel->setActiveSheetIndex(0)->toArray();
which accepts the following parameters:
* #param mixed $nullValue Value returned in the array entry if a cell doesn't exist
* #param boolean $calculateFormulas Should formulas be calculated?
* #param boolean $formatData Should formatting be applied to cell values?
* #param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero
* True - Return rows and columns indexed by their actual row and column IDs
although it does use the iterators, so would be slightly slower
OR
Take advantage of PHP's ability to increment character strings Perl Style
$highestColumm = $this->objPHPExcel->setActiveSheetIndex(0)->getHighestColumn(); // e.g. "EL"
$highestRow = $this->objPHPExcel->setActiveSheetIndex(0)->getHighestRow();
$highestColumm++;
for ($row = 1; $row < $highestRow + 1; $row++) {
$dataset = array();
for ($column = 'A'; $column != $highestColumm; $column++) {
$dataset[] = $this->objPHPExcel->setActiveSheetIndex(0)->getCell($column . $row)->getValue();
}
$this->datasets[] = $dataset;
}
and if you're processing a large number of rows, you might actually notice the performance improvement of ++$row over $row++
This is a somewhat simplified version of dqhendricks answer. I have added to copies, one function assuming you enter the full excel cell reference (ie. "AB12") and the other assuming you enter just the column reference (ie. "AB"). They both return a zero based index.
Input Full Cell Reference
function getIndex ($cell) {
// Strip cell reference down to just letters
$let = preg_replace('/[^A-Z]/', '', $cell);
// Iterate through each letter, starting at the back to increment the value
for ($num = 0, $i = 0; $let != ''; $let = substr($let, 0, -1), $i++)
$num += (ord(substr($let, -1)) - 65) * pow(26, $i);
return $num;
}
Input Column Reference Only
function getIndex ($let) {
// Iterate through each letter, starting at the back to increment the value
for ($num = 0, $i = 0; $let != ''; $let = substr($let, 0, -1), $i++)
$num += (ord(substr($let, -1)) - 65) * pow(26, $i);
return $num;
}
The function goes from the back of the string to the front to increase the value of the column. It uses the ord() function to get the numeric value of a character and then has the letter value subtracted to give the local column value. Finally it is multiplied by the current power of 26.
I suggest to convert excel to array, clean it from empty elements and then count the number of columns:
protected function getColumnsCheck($file, $col_number) {
if (strstr($file, ".xls") != false && strstr($file, ".xlsx") != false) {
$fileType = PHPExcel_IOFactory::identify($file);
$objReader = PHPExcel_IOFactory::createReader($fileType);
$objPHPExcel = $objReader->load($file);
$columns_empty = $objPHPExcel->getActiveSheet(0)->toArray()[0];
$columns = array_filter($columns_empty);
return ($col_number==count($columns));
}
return false;
}
/**
* Example 0 = A, 1 = B
*/
function getNameFromNumber(int $num): string {
if ($num < 0) throw new TypeError('$num must be at least 0');
$numeric = $num % 26;
$letter = chr(65 + $numeric);
$num2 = intval($num / 26);
if ($num2 > 0) {
return (__FUNCTION__)($num2 - 1) . $letter;
} else {
return $letter;
}
}
getNameFromNumber(0) // returns "A"
Not sure if your class has a built in method, but you could always use the ord() function on each letter of the column index string. You will of course have to subtract out the base value of 'A', and multiply by 26^x for each position from the far right of the string. Something like:
$input_string = 'BC';
$base_value = 64;
$decimal_value = 26;
$column_index = 0;
for ($i = 0; $i < strlen($input_string); $i++) {
$char_value = ord($input_string[$i]);
$char_value -= $base_value;
$char_value *= pow($decimal_value, (strlen($input_string) - ($i + 1)));
$column_index += $char_value;
}
echo $column_index;
Basically this would make 'BC' equal (2 * 26^1) + (3 * 26^0) = 55.
$input_string being the column index string, $base_value being the ord() value of 'A' minus 1, and $decimal_value being the value of A0. Should work up to any number column. Have tested. Hope this helps.
/**
*
*/
function number_to_alphabet($number) {
$number = intval($number);
if ($number <= 0) {
return '';
}
$alphabet = '';
while($number != 0) {
$p = ($number - 1) % 26;
$number = intval(($number - $p) / 26);
$alphabet = chr(65 + $p) . $alphabet;
}
return $alphabet;
}
/**
* Required PHP 5.6.
* #see: http://php.net/manual/en/language.operators.arithmetic.php
*/
function alphabet_to_number($string) {
$string = strtoupper($string);
$length = strlen($string);
$number = 0;
$level = 1;
while ($length >= $level ) {
$char = $string[$length - $level];
$c = ord($char) - 64;
$number += $c * (26 ** ($level-1));
$level++;
}
return $number;
}
Test:
for ($x=1; $x<=1000; $x++) {
echo 'number_to_alphabet('.$x.') = ',$y = number_to_alphabet($x),'; ';
echo 'alphabet_to_number('.$y.') = '.alphabet_to_number($y).'; ';
echo PHP_EOL;
}
Since this question is 10 years old, and the packages referenced here are not the newest ones any more:
Here is how you do it using phpspreadsheet:
$colNumber = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($colString); // e.g. 5
Source:
https://phpspreadsheet.readthedocs.io/en/latest/topics/accessing-cells/