这是道easy啊,我居然写了半天,主要原因api不够熟。
下面是我第一遍代码, 我自己也感觉实在难看。
public String similarRGB(String color) {
char[] array = color.substring(1).toLowerCase().toCharArray();
int[] intArray = new int[3];
for (int i = 0; i < 3; i++) {
char c1 = array[2 * i];
char c0 = array[2 * i + 1];
int n0 = (c0 - '0' <= 9 && c0 - '0' >= 0) ? c0 - '0' : c0 - 'a' + 10;
int n1 = (c1 - '0' <= 9 && c1 - '0' >= 0) ? c1 - '0' : c1 - 'a' + 10;
intArray[i] = n1 * 16 + n0;
}
for (int i = 0; i < 3; i++) {
int n = intArray[i];
List<Integer> candidates = new ArrayList<>();
if (n / 16 <= 15) {
candidates.add((n / 16 + 1) * 17);
}
if (n / 16 > 0) {
candidates.add((n / 16 - 1) * 17);
}
candidates.add(17 * (n / 16));
intArray[i] = candidates.get(0);
for (int j = 1; j < candidates.size(); j++) {
int b = candidates.get(j);
if ((b - n) * (b - n) < (intArray[i] - n) * ( intArray[i] - n) ) {
intArray[i] = b;
}
}
}
String ans = "#";
for (int n : intArray) {
n %= 16;
char x = n < 10 ? (char) (n + '0') : (char) (n + 'a' - 10);
ans += x;
ans += x;
}
return ans;
}
下面谈谈怎么改进.
- 有一个api叫Integer.parseInt("1e", 16), 16进制的,这样可以省去好多行。
- 第二段我枚举了三种情况,最高位和它相同的,小1的,大1的。看了答案发现其实我们做的事情是把数字round到最近的17位进制的数。这个逻辑就很简单了,我表示非常佩服。
3。有个api叫String.format("%02x", 17 *n) 也是非常给力。
改进后的如下,和答案差不多,当然是从答案学来的。
public String similarRGB(String color) {
String ans = "#";
for (int i = 0; i < 3; i++) {
int n = Integer.parseInt(color.substring(2 * i + 1, 2 * i +3), 16);
n = n / 17 + (n % 17 <= 8 ? 0 : 1 );
ans += String.format("%02x", 17 * n);
}
return ans;
}