Decrementing alphabetical values
PHP has overloaded ++
for strings; this isn't the case for --
. You can do the same thing with much cleaner code with chr
, ord
, and array_map
:
function decrementLetter($l) {
return chr(ord($l) - 1);
}
function move_up_left($x) {
if($x['orientation'] === 'down') $arr = &$x[0];
else $arr = &$x[1];
$arr = array_map('decrementLetter', $arr);
return $x;
}
Here's a demo. Note that you may need to add a special case for decrementing a
- I'm not sure how you want to deal with that.
Decrementing an alphabetical value in php
if your string is a hex value, you can use the following code:
$char = 'AF';
$value = hexdec($char);
$value--;
$char = dechex($value);
if you string is just a string:
$len = strlen($char);
$char[$len - 1] = chr(ord($char[$len - 1]) - 1);
PHP 2 chars decrement (AB - AA)
Here's a decrement function that will work for you:
function decrement($str) {
$index = strlen($str)-1;
$ord = ord($str[$index]);
if ($ord > 65) {
// The final character is still greater than A, decrement
return substr($str, 0, $index) . chr($ord-1);
}
if ($index > 0) {
// Strip the final 2 characters and append a Z
return substr($str, 0, $index-1) . 'Z';
}
// Can't be decremented
return false;
}
https://3v4l.org/WaaKY
Decrement character with php
There is no direct way to decrement alphabets. But with a simple function you can achieve it:
function decrementLetter($Alphabet) {
return chr(ord($Alphabet) - 1);
}
Source, thanks to Ryan O'Hara
How to decrement a character value alphabetically in C++
Characters are essentially one byte integers (although the representation may vary between compilers). While there are many encodings which map integer values to characters, almost all of them map 'a'
to 'z'
characters in successive numerical order. So, if you wanted to change the string "aaab"
to "aaaa"
you could do something like the following:
char letters [4] = {'a','a','a','b'};
letters[3]--;
Decrement only letters
Please read @StephenC's excellent answer about wrap-around. In short, you don't shift left, you rotate left, such that B
→ A
→ Z
→ Y
. When you rotate, you wrap around to the other end.
So, for letters you want A
-Z
to rotate. The easiest rotation method is using modulus (%
).
Your logic will be as follows:
- Convert letters
A
-Z
into numbers0
-25
:n = ch - 'A'
- Apply shift and wrap around. Since you're shifting left, you're subtracting from the number, so to prevent negative numbers, you start by shifting a full cycle to the right:
n = (n + 26 - shift) % 26
- Convert numbers back to letters:
ch = (char)(n + 'A')
Here is the code:
private static String rotateLeft(String text, int count) {
char[] buf = text.toCharArray();
for (int i = 0; i < buf.length; i++)
buf[i] = (char)((buf[i] - 'A' + 26 - count) % 26 + 'A');
return new String(buf);
}
Of course, you should validate input, and test your code:
private static String rotateLeft(String text, int count) {
char[] buf = text.toCharArray();
if (count <= 0 || count >= 26)
throw new IllegalArgumentException("Invalid count: " + count);
for (char ch : buf)
if (ch < 'A' || ch > 'Z')
throw new IllegalArgumentException("Invalid character: " + ch);
for (int i = 0; i < buf.length; i++)
buf[i] = (char)((buf[i] - 'A' + 26 - count) % 26 + 'A');
return new String(buf);
}
public static void main(String[] args) {
System.out.println(rotateLeft("VQREQFGT", 2));
System.out.println(rotateLeft("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 10));
System.out.println(rotateLeft("LIPPSASVPH", 4));
}
OUTPUT
TOPCODER
QRSTUVWXYZABCDEFGHIJKLMNOP
HELLOWORLD
How to cyclically increment and decrement 26 latin characters in a loop
Don't overcomplicate. Use modulo to keep the increment or decrement amount in a range of 26 characters, then simply do a range check:
char cyclicIncrementDecrement(char ch, int amount)
{
int newValue = int(ch) + (amount % 26);
if (newValue < 'a') newValue += 26;
if (newValue > 'z') newValue -= 26;
return char(newValue);
}
This method of course assumes ch
already is in range of 'a'
to 'z'
. If not, you need to handle that (put it in range or throw an exception or whatever is appropriate for your application).
Running this:
int main()
{
std::cout << cyclicIncrementDecrement('w', -2) << std::endl;
std::cout << cyclicIncrementDecrement('w', 2) << std::endl;
std::cout << cyclicIncrementDecrement('w', -28) << std::endl;
std::cout << cyclicIncrementDecrement('a', -256) << std::endl;
std::cout << cyclicIncrementDecrement('z', -256) << std::endl;
std::cout << cyclicIncrementDecrement('z', -51) << std::endl;
std::cout << cyclicIncrementDecrement('z', -52) << std::endl;
}
gives:
u
y
u
e
d
a
z
What is a method that can be used to increment letters?
Simple, direct solution
function nextChar(c) {
return String.fromCharCode(c.charCodeAt(0) + 1);
}
nextChar('a');
As others have noted, the drawback is it may not handle cases like the letter 'z' as expected. But it depends on what you want out of it. The solution above will return '{' for the character after 'z', and this is the character after 'z' in ASCII, so it could be the result you're looking for depending on what your use case is.
Unique string generator
(Updated 2019/05/09)
Since this answer has received so much visibility I've decided to expand it a bit beyond the scope of the original question to potentially help people who are stumbling on this from Google.
I find that what I often want is something that will generate sequential, unique strings in a certain character set (such as only using letters), so I've updated this answer to include a class that will do that here:
class StringIdGenerator {
constructor(chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
this._chars = chars;
this._nextId = [0];
}
next() {
const r = [];
for (const char of this._nextId) {
r.unshift(this._chars[char]);
}
this._increment();
return r.join('');
}
_increment() {
for (let i = 0; i < this._nextId.length; i++) {
const val = ++this._nextId[i];
if (val >= this._chars.length) {
this._nextId[i] = 0;
} else {
return;
}
}
this._nextId.push(0);
}
*[Symbol.iterator]() {
while (true) {
yield this.next();
}
}
}
Usage:
const ids = new StringIdGenerator();
ids.next(); // 'a'
ids.next(); // 'b'
ids.next(); // 'c'
// ...
ids.next(); // 'z'
ids.next(); // 'A'
ids.next(); // 'B'
// ...
ids.next(); // 'Z'
ids.next(); // 'aa'
ids.next(); // 'ab'
ids.next(); // 'ac'
Related Topics
PHP Include Best Practices Question
Prevent Direct Url Access to PHP File
What Does Using a Single Pipe '|' in a Function Argument Do
How to Get All Class Names Inside a Particular Namespace
New Csrf Token Per Request or Not
PHP Flush That Works... Even in Nginx
Manipulate a Url String by Adding Get Parameters
Symfony 2 Entitymanager Injection in Service
How to Force Laravel Project to Use Https for All Routes
How to Send 500 Internal Server Error Error from a PHP Script
How to Solve Time Out in PHPmyadmin
When Should I Use Stdclass and When Should I Use an Array in PHP Oo Code
How to Preview an Image Before and After Upload
Using the PHP Http_Accept_Language Server Variable
How to Prevent Multiple Logins in PHP Website
Android JSON Httpclient to Send Data to PHP Server with Httpresponse