【问题标题】:Best way to merge hex strings in c++? [heavily edited]在 C++ 中合并十六进制字符串的最佳方法? [大量编辑]
【发布时间】:2010-12-06 22:45:44
【问题描述】:

我有两个带有掩码的十六进制字符串,我想将它们合并成一个字符串值/掩码对。字符串可能有重叠的字节,但在应用掩码后,没有重叠位应该与该位的值相矛盾,即 value1 = 0x0A mask1 = 0xFE 和 value2 = 0x0B, mask2 = 0x0F 基本上表示生成的合并必须具有上半字节全为 0,下半字节必须为 01011

我已经使用直接 c 完成了这项工作,将字符串转换为字节数组并将 memcpy'ing 转换为缓冲区作为原型。它已经过测试,似乎可以工作。但是,它丑陋且难以阅读,并且不会针对与特定位要求相矛盾的情况抛出异常。我考虑过使用位集,但是还有另一种可能不需要转换开销的方法吗?性能会很好,但并不重要。


编辑:更多细节,虽然写这篇文章让我意识到我把一个简单的问题弄得太难了。但是,无论如何,它就在这里。

我收到了大量输入,这些输入是对混合内容文档的二进制搜索。文档被分成页面,页面由 api 提供,一次提供一个页面。每个页面都需要使用提供的搜索词进行搜索。

在请求页面之前,我拥有所有搜索词。输入是表示十六进制数字的字符串(这就是我所说的十六进制字符串)以及一个掩码,用于指示输入十六进制字符串中的重要位。由于我预先获得了所有输入,因此我想改进对返回的每个页面的搜索。我想预处理将这些十六进制字符串合并在一起。为了使问题更有趣,每个字符串在它们必须出现的页面中都有一个可选的偏移量,并且缺少偏移量表示该字符串可以出现在请求的页面中的任何位置。所以,是这样的:

class Input {
  public:
    int input_id;
    std::string value;
    std::string mask;
    bool offset_present;
    unsigned int offset;
};

如果给定的 Input 对象具有offset_present = false,则分配给 offset 的任何值都将被忽略。如果 offset_present 为 false,那么它显然不能与其他输入合并。

为了使问题更有趣,我想报告一个输出,该输出提供有关所找到内容的信息(找到的 input_id、偏移量在哪里等)。合并一些输入(但不是其他输入)使这变得更加困难。

我曾考虑定义一个 CompositeInput 类,并且正在考虑将底层合并作为一个位集,但进一步阅读有关位集的内容让我意识到这并不是我真正的想法。我的经验不足使我放弃了复合的想法,并开始使用蛮力。当找到输入时,我必须跳过有关其他输入类型的一些详细信息,以及为输出收集的附加信息(例如,页码、段落号)。这是一个示例输出类:

class Output {
  public:
    Output();
    int id_result;
    unsigned int offset_result;
};

如果我合并 N 个十六进制字符串,我希望生成其中的 N 个,对用户隐藏任何合并细节。

【问题讨论】:

  • 请展开示例,显示值(十六进制和二进制)、您如何“合并”以及结果如何。

标签: c++ string bit-manipulation composite bitset


【解决方案1】:

我不知道十六进制字符串是什么...但除此之外它应该是这样的:

 outcome = (value1 & mask1) | (value2 & mask2);

【讨论】:

    【解决方案2】:

    听起来像 |、& 和 ~ 会起作用吗?

    【讨论】:

      【解决方案3】:
      const size_t prefix = 2; // "0x"
      const size_t bytes  = 2;
      const char* value1 = "0x0A";
      const char* mask1  = "0xFE";
      const char* value2 = "0x0B";
      const char* mask2  = "0x0F";
      char output[prefix + bytes + 1] = "0x";
      
      uint8_t char2int[] = { /*zeroes until index '0'*/ 0,1,2,3,4,5,6,7,8,9 /*...*/ 10,11,12,13,14,15 };
      char int2char[] = { '0', /*...*/ 'F' };
      
      for (size_t ii = prefix; ii != prefix + bytes; ++ii)
      {
          uint8_t result1 = char2int[value1[ii]] & char2int[mask1[ii]];
          uint8_t result2 = char2int[value2[ii]] & char2int[mask2[ii]];
          if (result1 & result2)
              throw invalid_argument("conflicting bits");
          output[ii] = int2char[result1 | result2];
      }
      

      【讨论】:

        猜你喜欢
        • 2018-08-02
        • 2018-03-05
        • 2011-04-06
        • 2010-09-16
        • 2021-12-26
        • 2010-11-21
        • 2018-08-28
        • 2019-04-04
        • 2010-09-27
        相关资源
        最近更新 更多