Given a string A and another string B. Find whether any permutation of B exists as a substring of A.
For example,
if A = "encyclopedia"
if B="dep" then return true as ped is a permutation of dep and ped is a substring of A.
My solution->
if length(A)=n and length(B)=m
I did this in 0((n-m+1)*m) by sorting B and then checking A
with window size of m each time.
I need to find a better and a faster solution.
There is a simpler solution to this problem.
Here: n = A.size (), m = B.size ()
The idea is to use hashing.
First we hash the characters of string B.
Suppose: B = "dep"
hash_B ['d'] = 1;
hash_B ['e'] = 1;
hash_B ['p'] = 1;
Now we run a loop over the string 'A' for each window of size 'm'.
Suppose: A = "encyclopedia"
First window of size 'm' will have characters {e, n, c}. We will hash them now.
win ['e'] = 1
win ['n'] = 1
win ['c'] = 1
Now we check if the frequency of each character from both the arrays (hash_B [] and win []) are same. Note: Maximum size of hash_B [] or win [] is 26, hence the complexity would be O(26 * N) ~ O(N).
If they are not same we shift our window.
After shifting the window we decrease the count of win ['e'] by 1 and increase the count of win ['y'] by 1.
win ['n'] = 1
win ['c'] = 1
win ['y'] = 1
During the seventh shift, the status of your win array is:
win ['p'] = 1;
win ['e'] = 1;
win ['d'] = 1;
which is same as the hash_B array. So, Print "SUCCESS" and exit.
If I only have to worry about ASCII characters, it can be done in O(n) time with O(1) space. My code also prints the permutations out, but can be easily modified to simply return true at the first instance instead. The main part of the code is located in the printAllPermutations() method. Here is my solution:
Some Background
This is a solution that I came up with, it is somewhat similar to the idea behind the Rabin Karp Algorithm. Before I understanding the algorithm, I will explain the math behind it as follows:
Let S = {A_1, ..., A_n} be a multiset list of size N that contains only prime numbers. Let the sum of the numbers in S equal some integer Q. Then S is the only possible entirely prime multiset of size N, whose elements can sum to Q.
Because of this, we know we can map every character to a prime number. I propose a map as follows:
1 -> 1st prime
2 -> 2nd prime
3 -> 3rd prime
...
n -> nth prime
If we do this (which we can because ASCII only has 256 possible characters), then it becomes very easy for us to find each permutation in the larger string B.
The Algorithm:
We will do the following:
1: calculate the sum of the primes mapped to by each of the characters in A, let's call it smallHash.
2: create 2 indices (righti and lefti). righti is initialized to zero, and lefti is initialzed to the size of A.
ex: | |
v v
"abcdabcd"
^ ^
| |
3: Create a variable currHash, and initialize it to the sum of the corresponding prime numbers mapped to by each of the characters in B, between (inclusive) righti, and lefti - 1.
4: Iterate both righti and lefti by 1, each time updating currHash by subtracting the prime mapped from the character that is no longer in the range (lefti - 1) and adding the prime corresponding to the character just added to the range (righti)
5: Each time currHash is equal to smallHash, the characters in the range must be a permutation. So we print them out.
6: Continue until we have reached the end of B. (When righti is equal to the length of B)
This solution runs in O(n) time complexity and O(1) space.
The Actual Code:
public class FindPermutationsInString {
//This is an array containing the first 256 prime numbers
static int primes[] =
{
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583,
1597, 1601, 1607, 1609, 1613, 1619
};
public static void main(String[] args) {
String big = "abcdabcd";
String small = "abcd";
printAllPermutations(big, small);
}
static void printAllPermutations(String big, String small) {
// If the big one is smaller than the small one,
// there can't be any permutations, so return
if (big.length() < small.length()) return;
// Initialize smallHash to be the sum of the primes
// corresponding to each of the characters in small.
int smallHash = primeHash(small, 0, small.length());
// Initialize righti and lefti.
int lefti = 0, righti = small.length();
// Initialize smallHash to be the sum of the primes
// corresponding to each of the characters in big.
int currentHash = primeHash(small, 0, righti);
while (righti <= big.length()) {
// If the current section of big is a permutation
// of small, print it out.
if (currentHash == smallHash)
System.out.println(big.substring(lefti, righti));
// Subtract the corresponding prime value in position
// lefti. Then increment lefti
currentHash -= primeHash(big.charAt(lefti++));
if (righti < big.length()) // To prevent index out of bounds
// Add the corresponding prime value in position righti.
currentHash += primeHash(big.charAt(righti));
//Increment righti.
righti++;
}
}
// Gets the sum of all the nth primes corresponding
// to n being each of the characters in str, starting
// from position start, and ending at position end - 1.
static int primeHash(String str, int start, int end) {
int value = 0;
for (int i = start; i < end; i++) {
value += primeHash(str.charAt(i));
}
return value;
}
// Get's the n-th prime, where n is the ASCII value of chr
static int primeHash(Character chr) {
return primes[chr];
}
}
Keep in mind, however, that this solution only works when the characters can only be ASCII characters. If we are talking about unicode, we start getting into prime numbers that exceed the maximum size of an int, or even a double. Also, I'm not sure that there are 1,114,112 known primes.
Building a little on the algorithm presented by j_random_hacker in comments, it is possible to find the match in O(|A|+|B|), as follows: (Note: throughout, we use |A| to mean "the length of A".)
Create an integer array count whose domain is the size of the alphabet, initialized to all 0s.
Set distance to 0
For each character Bi in B:
Decrement count[Bi].
If the previous count of count[Bi] was 0, also increment distance.
For each character Ai in A:
Increment count[Ai]
If i is greater than |B| decrement count[Ai-|B|].
For each of the two count values modified, if the previous value was 0, then increment distance and if the new value is 0 then decrement distance.
If the result is that distance is 0 then a match has been found.
Note: The algorithm presented by j_random_hacker is also O(|A|+|B]) because the cost of comparing freqA with freqB is O(|alphabet|), which is a constant. However, the above algorithm reduces the comparison cost to a small constant. In addition, it is theoretically possible to make this work even if the alphabet is not a constant size by using the standard trick for uninitialized arrays.
This answer proposes a fixed implementation of the idea proposed by #Ephraim in his own answer.
The original answer confuses the multiplication property of a given set of primes with addition. The fixed statement would be:
Let S = {A_1, ..., A_n} be a multiset list of size N that contains only prime numbers. Let the product of the numbers in S equal some integer Q. Then S is the only possible entirely prime multiset of size N, whose elements can multiply to Q.
In order to avoid numerical overflows, the implementation uses infinite precision arithmetic based on the C++ library libgmpxx.
Under the assumption that the comparison between two numbers is in O(1), then the solution is in O(|A| + |B|). The previous assumption might actually not be the case for inputs where |B| is large enough. When |B| > |A| the function returns in O(1).
Example:
#include <iostream>
#include <string>
#include <gmpxx.h>
static int primes[] =
{
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583,
1597, 1601, 1607, 1609, 1613, 1619
};
mpz_class prime_hash(std::string const &str, size_t start, size_t end)
{
mpz_class hash(1);
for (size_t i = start; i < end; ++i) {
hash *= primes[(size_t) str.at(i)];
}
return hash;
}
void print_all_permutations(std::string const &big, std::string const &small)
{
const size_t big_len = big.length();
const size_t small_len = small.length();
if (small_len <= 0 || big_len < small_len) {
// no possible permutation!
return;
}
// O(small_len)
mpz_class small_hash = prime_hash(small, 0, small_len);
mpz_class curr_hash = prime_hash(big, 0, small_len);
// O(big_len)
size_t left_idx = 0;
do {
if (curr_hash == small_hash) {
std::cout << "Permutation `" << big.substr(left_idx, small_len)
<< "' of `" << small
<< "' at index " << left_idx
<< " of `" << big
<< "'." << std::endl;
}
curr_hash /= primes[(size_t) big.at(left_idx)];
if (left_idx + small_len < big_len) {
curr_hash *= primes[(size_t) big.at(left_idx + small_len)];
}
++left_idx;
} while (left_idx + small_len < big_len);
}
int main(int argc, char *argv[])
{
// #user2826957's input
print_all_permutations("encyclopedia", "dep");
// #Ephraim's input
print_all_permutations("abcdabcd", "abcd");
// #Sam's input
print_all_permutations("cbabadcbbabbc", "abbc");
// #butt0s input
print_all_permutations("", "");
print_all_permutations("", "a");
print_all_permutations("a", "");
print_all_permutations("a", "a");
return 0;
}
The example is compiled with:
~$ g++ permstr.cpp -lgmpxx -lgmp -o run
~$ ./run
Permutation `ped' of `dep' at index 7 of `encyclopedia'.
Permutation `abcd' of `abcd' at index 0 of `abcdabcd'.
Permutation `bcda' of `abcd' at index 1 of `abcdabcd'.
Permutation `cdab' of `abcd' at index 2 of `abcdabcd'.
Permutation `dabc' of `abcd' at index 3 of `abcdabcd'.
Permutation `cbab' of `abbc' at index 0 of `cbabadcbbabbc'.
Permutation `cbba' of `abbc' at index 6 of `cbabadcbbabbc'.
Permutation `a' of `a' at index 0 of `a'.
My approach is first give yourself a big example such as
a: abbc
b: cbabadcbbabbc
Then literally go through and underline each permutation
a: abbc
b: cbabadcbbabbc
'__'
'__'
'__'
Therefore
For i-> b.len:
sub = b.substring(i,i+len)
isPermuted ?
Here is code in java
class Test {
public static boolean isPermuted(int [] asciiA, String subB){
int [] asciiB = new int[26];
for(int i=0; i < subB.length();i++){
asciiB[subB.charAt(i) - 'a']++;
}
for(int i=0; i < 26;i++){
if(asciiA[i] != asciiB[i])
return false;
}
return true;
}
public static void main(String args[]){
String a = "abbc";
String b = "cbabadcbbabbc";
int len = a.length();
int [] asciiA = new int[26];
for(int i=0;i<a.length();i++){
asciiA[a.charAt(i) - 'a']++;
}
int lastSeenIndex=0;
for(int i=0;i<b.length()-len+1;i++){
String sub = b.substring(i,i+len);
System.out.printf("%s,%s\n",sub,isPermuted(asciiA,sub));
} }
}
The below function will return true if the String B is a permuted substring of String A.
public boolean isPermutedSubstring(String B, String A){
int[] arr = new int[26];
for(int i = 0 ; i < A.length();++i){
arr[A.charAt(i) - 'a']++;
}
for(int j=0; j < B.length();++j){
if(--arr[B.charAt(j)-'a']<0) return false;
}
return true;
}
The idea is clear in above talkings. An implementation with O(n) time complexity is below.
#include <stdio.h>
#include <string.h>
const char *a = "dep";
const char *b = "encyclopediaped";
int cnt_a[26];
int cnt_b[26];
int main(void)
{
const int len_a = strlen(a);
const int len_b = strlen(b);
for (int i = 0; i < len_a; i++) {
cnt_a[a[i]-'a']++;
cnt_b[b[i]-'a']++;
}
int i;
for (i = 0; i < len_b-len_a; i++) {
if (memcmp(cnt_a, cnt_b, sizeof(cnt_a)) == 0)
printf("%d\n", i);
cnt_b[b[i]-'a']--;
cnt_b[b[i+len_a]-'a']++;
}
if (memcmp(cnt_a, cnt_b, sizeof(cnt_a)) == 0)
printf("%d\n", i);
return 0;
}
Here's a solution that's pretty much rici's answer.
https://wandbox.org/permlink/PdzyFvv8yDf3t69l
It allocates a little more than 1k stack memory for the frequency table. O(|A| + |B|), no heap allocations.
#include <string>
bool is_permuted_substring(std::string_view input_string,
std::string_view search_string) {
if (search_string.empty()) {
return true;
}
if (search_string.length() > input_string.length()) {
return false;
}
int character_frequencies[256]{};
auto distance = search_string.length();
for (auto c : search_string) {
character_frequencies[(uint8_t)c]++;
}
for (auto i = 0u; i < input_string.length(); ++i) {
auto& cur_frequency = character_frequencies[(uint8_t)input_string[i]];
if (cur_frequency > 0) distance--;
cur_frequency--;
if (i >= search_string.length()) {
auto& prev_frequency = ++character_frequencies[(
uint8_t)input_string[i - search_string.length()]];
if (prev_frequency > 0) {
distance++;
}
}
if (!distance) return true;
}
return false;
}
int main() {
auto test = [](std::string_view input, std::string_view search,
auto expected) {
auto result = is_permuted_substring(input, search);
printf("%s: is_permuted_substring(\"%.*s\", \"%.*s\") => %s\n",
result == expected ? "PASS" : "FAIL", (int)input.length(),
input.data(), (int)search.length(), search.data(),
result ? "T" : "F");
};
test("", "", true);
test("", "a", false);
test("a", "a", true);
test("ab", "ab", true);
test("ab", "ba", true);
test("aba", "aa", false);
test("baa", "aa", true);
test("aacbba", "aab", false);
test("encyclopedia", "dep", true);
test("encyclopedia", "dop", false);
constexpr char negative_input[]{-1, -2, -3, 0};
constexpr char negative_search[]{-3, -2, 0};
test(negative_input, negative_search, true);
return 0;
}
I am late to this party...
The question is also discussed in the book named Cracking the Coding Interview, 6th Edition on page number 70. The auther says there is a possiblity of finding all permutations using O(n) time complexity (linear) but she doesnt write the algorithm so I thought I should give it a go.
Here is the C# solution just in case if someone was looking...
Also, I think (not 100% sure) it finds the count of permutations using O(n) time complexity.
public int PermutationOfPatternInString(string text, string pattern)
{
int matchCount = 0;
Dictionary<char, int> charCount = new Dictionary<char, int>();
int patLen = pattern.Length;
foreach (char c in pattern)
{
if (charCount.ContainsKey(c))
{
charCount[c]++;
}
else
{
charCount.Add(c, 1);
}
}
var subStringCharCount = new Dictionary<char, int>();
// loop through each character in the given text (string)....
for (int i = 0; i <= text.Length - patLen; i++)
{
// check if current char and current + length of pattern-th char are in the pattern.
if (charCount.ContainsKey(text[i]) && charCount.ContainsKey(text[i + patLen - 1]))
{
string subString = text.Substring(i, patLen);
int j = 0;
for (; j < patLen; j++)
{
// there is no point going on if this subString doesnt contain chars that are in pattern...
if (charCount.ContainsKey(subString[j]))
{
if (subStringCharCount.ContainsKey(subString[j]))
{
subStringCharCount[subString[j]]++;
}
else
{
subStringCharCount.Add(subString[j], 1);
}
}
else
{
// if any of the chars dont appear in the subString that we are looking for
// break this loop and continue...
break;
}
}
int x = 0;
// this will be true only when we have current subString's permutation count
// matched with pattern's.
// we need this because the char count could be different
if (subStringCharCount.Count == charCount.Count)
{
for (; x < patLen; x++)
{
if (subStringCharCount[subString[x]] != charCount[subString[x]])
{
// if any count dont match then we break from this loop and continue...
break;
}
}
}
if (x == patLen)
{
// this means we have found a permutation of pattern in the text...
// increment the counter.
matchCount++;
}
subStringCharCount.Clear(); // clear the count map.
}
}
return matchCount;
}
and here is the unit test method...
[TestCase("encyclopedia", "dep", 1)]
[TestCase("cbabadcbbabbcbabaabccbabc", "abbc", 7)]
[TestCase("xyabxxbcbaxeabbxebbca", "abbc", 2)]
public void PermutationOfStringInText(string text, string pattern, int expectedAnswer)
{
int answer = runner.PermutationOfPatternInString(text, pattern);
Assert.AreEqual(expectedAnswer, answer);
}
Taking O(TEXT.length) runtime complexity.
Some of these solutions will not work when average of calculated
text value matches average of calculated pattern value. Ex - uw and
vv. Though they are not matching, some solutions above still returns
TRUE.
public static void main(String[] args) {
String pattern = "dep";
String text = "encyclopedia";
System.out.println(isPermutationAvailable(pattern, text));
}
public static boolean isPermutationAvailable(String pattern, String text) {
if (pattern.length() > text.length()) {
return false;
}
int[] patternMap = new int[26];
int[] textMap = new int[26];
for (int i = 0; i < pattern.length(); i++) {
patternMap[pattern.charAt(i) - 'a']++;
textMap[text.charAt(i) - 'a']++;
}
int count = 0;
for (int i = 0; i < 26; i++) {
if (patternMap[i] == textMap[i]) {
count++;
}
}
for (int i = 0; i < text.length() - pattern.length(); i++) {
int r = text.charAt(i + pattern.length()) - 'a';
int l = text.charAt(i) - 'a';
if (count == 26) {
return true;
}
textMap[r]++;
if (textMap[r] == patternMap[r]) {
count++;
}
else if (textMap[r] == patternMap[r] + 1) {
count--;
}
textMap[l]--;
if (textMap[l] == patternMap[l]) {
count++;
}
else if (textMap[l] == patternMap[l] - 1) {
count--;
}
}
return count == 26;
}
Based on checking the longer string with a window size of short one. Since permutation only changes the position of a character, sorted string will always be the same.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main ()
{
string shortone = "abbc";
string longone ="cbabadcbbabbcbabaabccbabc";
int s_length = shortone.length ();
int l_length = longone.length ();
string sub_string;
string unsorted_substring; // only for printing
// sort the short one
sort (shortone.begin (), shortone.end ());
if (l_length > s_length)
{
for (int i = 0; i <= l_length - s_length; i++){
sub_string = "";
//Move the window
sub_string = longone.substr (i, s_length);
unsorted_substring=sub_string;
// sort the substring window
sort (sub_string.begin (), sub_string.end ());
if (shortone == sub_string)
{
cout << "substring is :" << unsorted_substring << '\t' <<
"match found at the position: " << i << endl;
}
}
}
return 0;
}
What is the most efficient way to do this?
In python:
def hex_to_rgb(value):
"""Return (red, green, blue) for the color given as #rrggbb."""
value = value.lstrip('#')
lv = len(value)
return tuple(int(value[i:i + lv // 3], 16) for i in range(0, lv, lv // 3))
def rgb_to_hex(red, green, blue):
"""Return color as #rrggbb for the given color values."""
return '#%02x%02x%02x' % (red, green, blue)
hex_to_rgb("#ffffff") #==> (255, 255, 255)
hex_to_rgb("#ffffffffffff") #==> (65535, 65535, 65535)
rgb_to_hex(255, 255, 255) #==> '#ffffff'
rgb_to_hex(65535, 65535, 65535) #==> '#ffffffffffff'
In python conversion between hex and 'rgb' is also included in the plotting package matplotlib. Namely
import matplotlib.colors as colors
Then
colors.hex2color('#ffffff') #==> (1.0, 1.0, 1.0)
colors.rgb2hex((1.0, 1.0, 1.0)) #==> '#ffffff'
The caveat is that rgb values in colors are assumed to be between 0.0 and 1.0. If you want to go between 0 and 255 you need to do a small conversion. Specifically,
def hex_to_rgb(hex_string):
rgb = colors.hex2color(hex_string)
return tuple([int(255*x) for x in rgb])
def rgb_to_hex(rgb_tuple):
return colors.rgb2hex([1.0*x/255 for x in rgb_tuple])
The other note is that colors.hex2color only accepts valid hex color strings.
just real quick:
int r = ( hexcolor >> 16 ) & 0xFF;
int g = ( hexcolor >> 8 ) & 0xFF;
int b = hexcolor & 0xFF;
int hexcolor = (r << 16) + (g << 8) + b;
Real answer: Depends on what kind of hexadecimal color value you are looking for (e.g. 565, 555, 888, 8888, etc), the amount of alpha bits, the actual color distribution (rgb vs bgr...) and a ton of other variables.
Here's a generic algorithm for most RGB values using C++ templates (straight from ScummVM).
template<class T>
uint32 RGBToColor(uint8 r, uint8 g, uint8 b) {
return T::kAlphaMask |
(((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
(((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
(((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
}
Here's a sample color struct for 565 (the standard format for 16 bit colors):
template<>
struct ColorMasks<565> {
enum {
highBits = 0xF7DEF7DE,
lowBits = 0x08210821,
qhighBits = 0xE79CE79C,
qlowBits = 0x18631863,
kBytesPerPixel = 2,
kAlphaBits = 0,
kRedBits = 5,
kGreenBits = 6,
kBlueBits = 5,
kAlphaShift = kRedBits+kGreenBits+kBlueBits,
kRedShift = kGreenBits+kBlueBits,
kGreenShift = kBlueBits,
kBlueShift = 0,
kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
kRedMask = ((1 << kRedBits) - 1) << kRedShift,
kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
kBlueMask = ((1 << kBlueBits) - 1) << kBlueShift,
kRedBlueMask = kRedMask | kBlueMask
};
};
Modifying Jeremy's python answer to handle short CSS rgb values like 0, #999, and #fff (which browsers would render as black, medium grey, and white):
def hex_to_rgb(value):
value = value.lstrip('#')
lv = len(value)
if lv == 1:
v = int(value, 16)*17
return v, v, v
if lv == 3:
return tuple(int(value[i:i+1], 16)*17 for i in range(0, 3))
return tuple(int(value[i:i+lv/3], 16) for i in range(0, lv, lv/3))
You need only convert a value hex (in parts) to decimal and vice-versa. Also need considered, what value in hex may contains 6 or 3 characters (without character '#').
Implementation on the Python 3.5
"""Utils for working with colors."""
import textwrap
def rgb_to_hex(value1, value2, value3):
"""
Convert RGB value (as three numbers each ranges from 0 to 255) to hex format.
>>> rgb_to_hex(235, 244, 66)
'#EBF442'
>>> rgb_to_hex(56, 28, 26)
'#381C1A'
>>> rgb_to_hex(255, 255, 255)
'#FFFFFF'
>>> rgb_to_hex(0, 0, 0)
'#000000'
>>> rgb_to_hex(203, 244, 66)
'#CBF442'
>>> rgb_to_hex(53, 17, 8)
'#351108'
"""
for value in (value1, value2, value3):
if not 0 <= value <= 255:
raise ValueError('Value each slider must be ranges from 0 to 255')
return '#{0:02X}{1:02X}{2:02X}'.format(value1, value2, value3)
def hex_to_rgb(value):
"""
Convert color`s value in hex format to RGB format.
>>> hex_to_rgb('fff')
(255, 255, 255)
>>> hex_to_rgb('ffffff')
(255, 255, 255)
>>> hex_to_rgb('#EBF442')
(235, 244, 66)
>>> hex_to_rgb('#000000')
(0, 0, 0)
>>> hex_to_rgb('#000')
(0, 0, 0)
>>> hex_to_rgb('#54433f')
(84, 67, 63)
>>> hex_to_rgb('#f7efed')
(247, 239, 237)
>>> hex_to_rgb('#191616')
(25, 22, 22)
"""
if value[0] == '#':
value = value[1:]
len_value = len(value)
if len_value not in [3, 6]:
raise ValueError('Incorect a value hex {}'.format(value))
if len_value == 3:
value = ''.join(i * 2 for i in value)
return tuple(int(i, 16) for i in textwrap.wrap(value, 2))
if __name__ == '__main__':
import doctest
doctest.testmod()
Implementation on the JavaScript (adapted to the NodeJS with a support ES6)
const assert = require('assert');
/**
* Return a color`s value in the hex format by passed the RGB format.
* #param {integer} value1 An value in ranges from 0 to 255
* #param {integer} value2 An value in ranges from 0 to 255
* #param {integer} value3 An value in ranges from 0 to 255
* #return {string} A color`s value in the hex format
*/
const RGBtoHex = (value1, value2, value3) => {
const values = [value1, value2, value3];
let result = '#';
for (let i = 0; i < 3; i += 1) {
// validation input
if (values[i] < 0 || values[i] > 255) throw new Error('An each value of RGB format must be ranges from 0 to 255');
// append to result values as hex with at least width 2
result += (('0' + values[i].toString(16)).slice(-2));
}
return result.toUpperCase();
};
/**
* Convert a value from the hex format to RGB and return as an array
* #param {int} value A color`s value in the hex format
* #return {array} Array values of the RGB format
*/
const hexToRGB = (value) => {
let val = value;
val = (value[0] === '#') ? value.slice(1) : value;
if ([3, 6].indexOf(val.length) === -1) throw new Error(`Incorect a value of the hex format: ${value}`);
if (val.length === 3) val = val.split('').map(item => item.repeat(2)).join('');
return val.match(/.{2}/g).map(item => parseInt(`0x${item}`, 16));
};
assert.deepEqual(hexToRGB('fff'), [255, 255, 255]);
assert.deepEqual(hexToRGB('#fff'), [255, 255, 255]);
assert.deepEqual(hexToRGB('#000000'), [0, 0, 0]);
assert.deepEqual(hexToRGB('000000'), [0, 0, 0]);
assert.deepEqual(hexToRGB('#d7dee8'), [215, 222, 232]);
assert.deepEqual(hexToRGB('#1E2F49'), [30, 47, 73]);
assert.deepEqual(hexToRGB('#030914'), [3, 9, 20]);
assert.equal(RGBtoHex(255, 255, 255), '#FFFFFF');
assert.equal(RGBtoHex(0, 0, 0), '#000000');
assert.equal(RGBtoHex(96, 102, 112), '#606670');
assert.equal(RGBtoHex(199, 204, 214), '#C7CCD6');
assert.equal(RGBtoHex(22, 99, 224), '#1663E0');
assert.equal(RGBtoHex(0, 8, 20), '#000814');
module.exports.RGBtoHex = RGBtoHex;
module.exports.hexToRGB = hexToRGB;
Implementation on the C (intended for the C11 standart)
// a type for a struct of RGB color
typedef struct _ColorRGB {
unsigned short int red;
unsigned short int green;
unsigned short int blue;
} colorRGB_t;
/*
Convert a color`s value from the hex format to the RGB.
Return -1 if a passed value in the hex format is not correct, otherwise - return 0;
*/
static int
convertColorHexToRGB(const char originValue[], colorRGB_t *colorRGB) {
// a full value of color in hex format must constains 6 charapters
char completedValue[6];
size_t lenOriginValue;
size_t lenCompletedValue;
// an intermediary variable for keeping value in the hex format
char hexSingleValue[3];
// a temp pointer to char, need only to the strtol()
char *ptr;
// a variable for keeping a converted number in the hex to the decimal format
long int number;
// validation input
lenOriginValue = strlen(originValue);
if (lenOriginValue > 7 || lenOriginValue < 3) return -1;
// copy value without sign '#', if found as first in the string
(originValue[0] == '#') ? strcpy(completedValue, originValue + 1) : strcpy(completedValue, originValue);
lenCompletedValue = strlen(completedValue);
// if the value has only 3 charapters, dublicate an each after itself
// but if not full version of the hex name of a color (6 charapters), return -1
if (lenCompletedValue == 3) {
completedValue[5] = completedValue[2];
completedValue[4] = completedValue[2];
completedValue[3] = completedValue[1];
completedValue[2] = completedValue[1];
completedValue[1] = completedValue[0];
} else if (lenCompletedValue != 6) return -1;
// convert string, by parts, to decimal values and keep it in a struct
sprintf(hexSingleValue, "%c%c", completedValue[0], completedValue[1]);
number = strtol(hexSingleValue, &ptr, 16);
colorRGB->red = number;
sprintf(hexSingleValue, "%c%c", completedValue[2], completedValue[3]);
number = strtol(hexSingleValue, &ptr, 16);
colorRGB->green = number;
sprintf(hexSingleValue, "%c%c", completedValue[4], completedValue[5]);
number = strtol(hexSingleValue, &ptr, 16);
colorRGB->blue = number;
return 0;
}
/*
Convert a color`s value from the RGB format to the hex
*/
static int
convertColorRGBToHex(const colorRGB_t *colorRGB, char value[8]) {
sprintf(value, "#%02X%02X%02X", colorRGB->red, colorRGB->green, colorRGB->blue);
return 0;
}
/*
Forming a string representation data in an instance of the structure colorRGB_t
*/
static int
getRGBasString(const colorRGB_t *colorRGB, char str[18]) {
sprintf(str, "rgb(%d, %d, %d)", colorRGB->red, colorRGB->green, colorRGB->blue);
return 0;
}
int main (int argv, char **argc)
{
char str[18];
char hex[8];
colorRGB_t *colorRGB_;
colorRGB_ = (colorRGB_t *)malloc(sizeof(colorRGB_));
convertColorHexToRGB("fff", colorRGB_);
getRGBasString(colorRGB_, str);
printf("Hex 'fff' to RGB %s\n", str);
convertColorRGBToHex(colorRGB_, hex);
printf("RGB %s to hex '%s'\n", str, hex);
convertColorHexToRGB("000000", colorRGB_);
getRGBasString(colorRGB_, str);
printf("Hex '000000' to RGB %s\n", str);
convertColorRGBToHex(colorRGB_, hex);
printf("RGB %s to hex '%s'\n", str, hex);
convertColorHexToRGB("#000000", colorRGB_);
getRGBasString(colorRGB_, str);
printf("Hex '#000000' to RGB %s\n", str);
convertColorRGBToHex(colorRGB_, hex);
printf("RGB %s to hex '%s'\n", str, hex);
convertColorHexToRGB("#FFF", colorRGB_);
getRGBasString(colorRGB_, str);
printf("Hex '#FFF' to RGB %s\n", str);
convertColorRGBToHex(colorRGB_, hex);
printf("RGB %s to hex '%s'\n", str, hex);
free(colorRGB_);
}
A result after compilation (I am used the GCC)
Hex 'fff' to RGB rgb(255, 255, 255)
RGB rgb(255, 255, 255) to hex '#FFFFFF'
Hex '000000' to RGB rgb(0, 0, 0)
RGB rgb(0, 0, 0) to hex '#000000'
Hex '#000000' to RGB rgb(0, 0, 0)
RGB rgb(0, 0, 0) to hex '#000000'
Hex '#FFF' to RGB rgb(255, 255, 255)
RGB rgb(255, 255, 255) to hex '#FFFFFF'
A hex value is just RGB numbers represented in hexadecimal. So you just have to take each pair of hex digits and convert them to decimal.
Example:
#FF6400 = RGB(0xFF, 0x64, 0x00) = RGB(255, 100, 0)
#!/usr/bin/env python
import re
import sys
def hex_to_rgb(value):
value = value.lstrip('#')
lv = len(value)
return tuple(int(value[i:i+lv/3], 16) for i in range(0, lv, lv/3))
def rgb_to_hex(rgb):
rgb = eval(rgb)
r = rgb[0]
g = rgb[1]
b = rgb[2]
return '#%02X%02X%02X' % (r,g,b)
def main():
color = raw_input("HEX [#FFFFFF] or RGB [255, 255, 255] value (no value quits program): ")
while color:
if re.search('\#[a-fA-F0-9][a-fA-F0-9][a-fA-F0-9][a-fA-F0-9][a-fA-F0-9][a-fA-F0-9]', color):
converted = hex_to_rgb(color)
print converted
elif re.search('[0-9]{1,3}, [0-9]{1,3}, [0-9]{1,3}', color):
converted = rgb_to_hex(color)
print converted
elif color == '':
sys.exit(0)
else:
print 'You didn\'t enter a valid value!'
color = raw_input("HEX [#FFFFFF] or RGB [255, 255, 255] value (no value quits program): ")
if __name__ == '__main__':
main()
This is a fragment of code I created for my own use in c++11.
you can send hex values or strings:
void Color::SetColor(string color) {
// try catch will be necessary if your string is not sanitized before calling this function.
SetColor(std::stoul(color, nullptr, 16));
}
void Color::SetColor(uint32_t number) {
B = number & 0xFF;
number>>= 8;
G = number & 0xFF;
number>>= 8;
R = number & 0xFF;
}
// ex:
SetColor("ffffff");
SetColor(0xFFFFFF);
Very Simple and Short implementation:
color_in_hex = 'FF00EE64' # Green Color
print('RGB =', tuple(int(color_in_hex[i:i+2], 16) for i in (0, 2, 4)))