连接字节值的超快速方法

发布于 2024-11-26 14:13:25 字数 458 浏览 0 评论 0原文

给定 3 个不同的字节,例如 x = 64、y = 90、z = 240,我希望将它们连接成像 6490240 这样的字符串。如果这有效,那就太好了,但事实并非如此:

 string xx = (string)x + (string)y + (string)z;

我正在 C++ 中工作,并会使用 8 位表示将字节串联为 24 位字符串。

它需要超快,因为我在大量数据上使用这种方法,而且令人沮丧的是,它们并不是一种仅仅说将此字节视为字符串的方法。

非常感谢您的帮助

澄清一下,我特别使用 3 个字节的原因是因为原始数据与 RGB 值有关,这些值通过指针读取,并且当然以字节形式存储在内存中。

我想要一种真正独立处理每种颜色的方法,这样如果您愿意,您可以将其视为哈希函数。因此,需要任何能够在不发生冲突的情况下实现这一点的快速表示。这是我能想到的避免任何碰撞的唯一方法。

Given 3 different bytes such as say x = 64, y = 90, z = 240 I am looking to concatenate them into say a string like 6490240. It would be lovely if this worked but it doesn't:

 string xx = (string)x + (string)y + (string)z;

I am working in C++, and would settle for a concatenation of the bytes as a 24 bit string using their 8-bit representations.

It needs to be ultra fast because I am using this method on a lot of data, and it seems frustratingly like their isn't a way to just say treat this byte as if it were a string.

Many thanks for your help

To clarify, the reason why I'm particular about using 3 bytes is because the original data pertains to RGB values which are read via pointers and are stored of course as bytes in memory.

I want a way really to treat each color independently so you can think of this as a hashing function if you like. So any fast representation that does it without collisions is desired. This is the only way I can think of to avoid any collisions at all.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一片旧的回忆 2024-12-03 14:13:25

您是否考虑过将颜色元素打包到一个整数的三个字节中?

uint32_t full_color = (x << 16) | uint32_t full_color = (x << 16) | (y << 8) | (y << 8) | z;

Did you consider instead just packing the color elements into three bytes of an integer?

uint32_t full_color = (x << 16) | (y << 8) | z;

时光瘦了 2024-12-03 14:13:25

将数字转换为字符串的最简单方法是使用 ostringstream

#include <sstream>
#include <string>
std::ostringstream os;
os << x << y << z;
std::string str = os.str();   // 6490240

您甚至可以使用操纵器以十六进制或八进制执行此操作:

os << std::hex << x << y << z;

更新

既然您已经澄清了您真正想要做什么,我已经更新了我的答案。您希望将 RGB 值视为三个字节,并以某种方式将它们用作键。最好使用 long int,而不是字符串来完成。您仍然可以很容易地将 int 字符串化,以便打印到屏幕上。

unsigned long rgb = 0;
byte* b = reinterpret_cast<byte*>(&rgb);
b[0] = x;
b[1] = y;
b[2] = z;
// rgb is now the bytes { 0, x, y, z }

然后你可以使用long int rgb作为你的密钥,非常有效。每当您想打印出来时,您仍然可以这样做:

std::cout << std::hex << rgb;

根据系统的字节顺序,您可能需要调整您设置的 long int 的哪些字节。我的示例覆盖字节 0-2,但您可能想要写入字节 1-3。您可能希望将顺序写为 z, y, x 而不是 x, y, z。这种细节取决于平台。尽管如果您从不想打印 RGB 值,而只是想将其视为散列,那么您无需担心写入哪些字节或以什么顺序。

Easiest way to turn numbers into a string is to use ostringstream

#include <sstream>
#include <string>
std::ostringstream os;
os << x << y << z;
std::string str = os.str();   // 6490240

You can even make use of manipulators to do this in hex or octal:

os << std::hex << x << y << z;

Update

Since you've clarified what you really want to do, I've updated my answer. You're looking to take RGB values as three bytes, and use them as a key somehow. This would be best done with a long int, not as a string. You can still stringify the int quite easily, for printing to the screen.

unsigned long rgb = 0;
byte* b = reinterpret_cast<byte*>(&rgb);
b[0] = x;
b[1] = y;
b[2] = z;
// rgb is now the bytes { 0, x, y, z }

Then you can use the long int rgb as your key, very efficiently. Whenever you want to print it out, you can still do that:

std::cout << std::hex << rgb;

Depending on the endian-ness of your system, you may need to play around with which bytes of the long int you set. My example overwrites bytes 0-2, but you might want to write bytes 1-3. And you might want to write the order as z, y, x instead of x, y, z. That kind of detail is platform dependent. Although if you never want to print the RGB value, but simply want to consider it as a hash, then you don't need to worry about which bytes you write or in what order.

辞旧 2024-12-03 14:13:25

尝试 sprintf(xx,"%d%d%d",x,y,z);

try sprintf(xx,"%d%d%d",x,y,z);

倥絔 2024-12-03 14:13:25

使用 3 个字符的字符数组作为 24 位表示形式,并将每个字符分配为输入值之一的值。

Use a 3 character character array as your 24 bit representation, and assign each char the value of one of your input values.

猥琐帝 2024-12-03 14:13:25

将 3 个字节转换为位并将结果存储在数组中可以轻松完成,如下所示:

void bytes2bits(unsigned char x, unsigned char y, unsigned char z, char * res)
{
    res += 24; *res-- = 0;
    unsigned xyz = (x<<16)+(y<<8)+z;
    for (size_t l = 0 ; l < 24 ; l++){
        *res-- = '0'+(xyz & 1); xyz >>= 1;
    }

}

但是,如果您正在寻找一种以明确且紧凑的方式存储三个字节值的方法,您可能应该选择十六进制。 (二进制表示的每组四位与 0 到 9 之间的数字或 A 到 F 之间的字母匹配)。它的编码和解码非常简单,并且也适合人类可读的输出。

如果您不需要打印结果,只需将这些值组合为单个整数并将其用作建议的键,Mark 无疑是最快和最简单的解决方案。假设您的本机整数在目标系统上为 32 位或更多,只需执行以下操作:

unsigned int key = (x<< 16)|(y<<8)|z;

如果需要,您可以轻松地从 key 获取初始值:

unsigned char x = (key >> 16) & 0xFF;
unsigned char y = (key >> 8) & 0xFF;
unsigned char z = key & 0xFF;

Converting 3 bytes to bits and storing the result in an array can be done easily as below:

void bytes2bits(unsigned char x, unsigned char y, unsigned char z, char * res)
{
    res += 24; *res-- = 0;
    unsigned xyz = (x<<16)+(y<<8)+z;
    for (size_t l = 0 ; l < 24 ; l++){
        *res-- = '0'+(xyz & 1); xyz >>= 1;
    }

}

However, if you are looking for a way to store three bytes values in a non ambiguous and compact way, you should probably settle for hexadecimal. (each group of four bits of the binary representation match a digit between 0 to 9 or a letter between A to F). It's ultra simple and ultra simple to encode and decode and also fit a human readable output.

If you never need to printout the result, just combining the values as a single integer and use it as a key as proposed Mark is certainly the fastest and the simplest solution. Assuming your native integer is 32 bits or more on the target system, just do:

unsigned int key = (x<< 16)|(y<<8)|z;

You can as easily get back the initial values from key if needed:

unsigned char x = (key >> 16) & 0xFF;
unsigned char y = (key >> 8) & 0xFF;
unsigned char z = key & 0xFF;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文