60.RGB色值转换为整数值[字节青训营-中等题]

170 阅读6分钟

1.问题

问题描述

小M需要一个函数,用于将RGB颜色值转换为相应的十六进制整数值。RGB色值以字符串的形式给出,如"rgb(192, 192, 192)",需要转换为对应的整数值。


测试样例

样例1:

输入:rgb = "rgb(192, 192, 192)"

输出:12632256

样例2:

输入:rgb = "rgb(100, 0, 252)"

输出:6553852

样例3:

输入:rgb = "rgb(33, 44, 55)"

输出:2174007

样例4:

输入:rgb = "rgb(255, 255, 255)"

输出:16777215

样例5:

输入:rgb = "rgb(0, 0, 0)"

输出:0

2.思路

提取出三个数字,转换成十六进制,拼接起来,再转成十进制输出

样例1:

输入:rgb = "rgb(192, 192, 192)"

输出:12632256

  1. 提取 RGB 值

    • 从字符串 "rgb(192, 192, 192)" 中提取出 192192 和 192
  2. 转换为十六进制

    • 192 转换为十六进制是 C0
    • 192 转换为十六进制是 C0
    • 192 转换为十六进制是 C0
  3. 组合十六进制字符串

    • 将 C0C0 和 C0 组合成一个完整的十六进制字符串 C0C0C0
  4. 转换为整数

    • 将十六进制字符串 C0C0C0 转换为整数 12632256

3.代码

十进制转十六进制

int x = 26 ;
string out;
stringstream ss;
ss << std::hex <<x;
ss >> out ;
transform(out.begin(), out.end(), out.begin(), ::toupper);
cout << out <<endl;
 
输出:1A

十六进制转十进制

#include <sstream>
 
int x;
stringstream ss;
ss << std::hex << "1A";  //std::oct(八进制)、std::dec(十进制)
ss >> x;
cout << x<<endl;
 
输出:26

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;

int solution(std::string rgb) {
    // Please write your code here
    //通过切片除去前面的"rgb("和后面的")"
    string subStr = rgb.substr(4, rgb.size() - 5);
    //cout << subStr << endl;
    stringstream rgbValues;
    string value;
    // 将 subStr 转换为 istringstream 对象
    istringstream iss(subStr);
    while(getline(iss, value, ',')){
        stringstream ss;
        ss << hex << stoi(value);
        rgbValues << ss.str();
    }
    stringstream result;
    int x;
    result << hex << rgbValues.str();
    result >> x;
    return x;
}

int main() {
    //  You can add more test cases here
    std::cout << (solution("rgb(192, 192, 192)") == 12632256) << std::endl;
    std::cout << (solution("rgb(100, 0, 252)") == 6553852) << std::endl;
    std::cout << (solution("rgb(33, 44, 55)") == 2174007) << std::endl;
    return 0;
}

通过 stringstream 将 RGB 数值转换为十六进制字符串后,再通过 result << hex << rgbValues.str() 转换回整数,这里不需要进行两次转换,直接使用 RGB 数值的位运算即可。

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;

int solution(std::string rgb) {
    // Please write your code here
    //通过切片除去前面的"rgb("和后面的")"
    string subStr = rgb.substr(4, rgb.size() - 5);
    //cout << subStr << endl;
    // 将 subStr 转换为 istringstream 对象
    istringstream iss(subStr);
    vector<int> colors;
    string value;
    while(getline(iss, value, ',')){
        colors.push_back(stoi(value));
    }
    int hexColor = (colors[0] << 16 | colors[1] << 8 | colors[2]);
    return hexColor;
}

int main() {
    //  You can add more test cases here
    std::cout << (solution("rgb(192, 192, 192)") == 12632256) << std::endl;
    std::cout << (solution("rgb(100, 0, 252)") == 6553852) << std::endl;
    std::cout << (solution("rgb(33, 44, 55)") == 2174007) << std::endl;
    return 0;
}

image.png 代码部分解释:

1.

<sstream> 是 C++ 标准库中的一个头文件,它提供了用于字符串流操作的类和函数。字符串流允许你像处理文件流一样处理字符串,这在处理字符串时非常有用。

主要类和函数

  1. std::istringstream:用于从字符串中读取数据,类似于从文件中读取数据。
  2. std::ostringstream:用于将数据写入字符串,类似于将数据写入文件。
  3. std::stringstream:结合了 std::istringstream 和 std::ostringstream 的功能,既可以读取也可以写入字符串。

2.istringstream iss(subStr);

是 C++ 中使用 <sstream> 头文件中的 std::istringstream 类来创建一个字符串流对象的语句。

3.getline(iss, value, ',') **

这是一个函数调用,用于从字符串流 iss 中读取数据,直到遇到指定的分隔符 , 。读取的数据会被存储在 value 变量中。

4. stoi

stoi 是 C++ 标准库中的一个函数,"string to integer" 的缩写,用于将字符串转换为整数。它是 std::stoi 的缩写,定义在 <string> 头文件中。

5.int hexColor = (colors[0] << 16) | (colors[1] << 8) | colors[2];

位运算过程

假设我们有 RGB 颜色 (192, 192, 192),那么:

  • 红色分量 colors[0] = 192

    • 192 的二进制表示是 11000000(8 位)。
    • 192 左移 16 位,得到:192 << 16,即 11000000 00000000 00000000,表示红色部分占据了最高的 8 位。
  • 绿色分量 colors[1] = 192

    • 192 的二进制表示是 11000000(8 位)。
    • 192 左移 8 位,得到:192 << 8,即 00000000 11000000 00000000,表示绿色部分占据了中间的 8 位。
  • 蓝色分量 colors[2] = 192

    • 192 的二进制表示是 11000000(8 位)。
    • 不需要左移,直接使用 colors[2] 的值 192,即 00000000 00000000 11000000,表示蓝色部分占据了最低的 8 位。

按位或运算

这三个数的按位或运算结果就是将三个分量拼接在一起,形成一个 24 位的整数:

(192 << 16)  -->  11000000 00000000 00000000
(192 << 8)   -->  00000000 11000000 00000000
colors[2]     -->  00000000 00000000 11000000

然后,执行按位或(|)操作:

11000000 00000000 00000000  (红色)
| 00000000 11000000 00000000  (绿色)
| 00000000 00000000 11000000  (蓝色)
------------------------------
  11000000 11000000 11000000

这时,结果就是 11000000 11000000 11000000,即 0xC0C0C0(十六进制表示)。

其实无需转成十六进制,而是需要11000000 11000000 11000000这样的排列即可。

4.参考资料

C++中二进制、字符串、十六进制、十进制之间的转换_ss << std::hex <<-CSDN博客

C++ 字符串 | 菜鸟教程