【问题标题】:Concatenating Multiple Ints To Form A Larger Int连接多个 Int 以形成更大的 Int
【发布时间】:2012-11-20 00:36:29
【问题描述】:

我还有一个深夜的脑残问题。这可能很简单,但您知道在 8 小时以上的编程之后到达最后期限的情况。 :)

这是我的问题..

我有一个长度为 10 的布尔数组,它在逻辑上被分成单独的部分来保存 4 个不同的整数位数组(作为布尔值)。这是目标数组:

bool[] myArray = new bool[10]; 

这是我要插入的 4 个整数:

int value1 = 3;  // 2 bits, myArray[0-1], 11
int value2 = 12; // 4 bits, myArray[2-5], 1100
int value3 = 2;  // 2 bits, myArray[6-7], 10
int value4 = 1;  // 2 bits, myArray[8-9], 01

myArray 最终应该如下所示(注意第一个元素是位置 0):

{(T,T),(T,T,F,F),(T,F),(F,T)}

那么最终我想做的就是将 myArray 转换为 int 值:

0x1111001001 = 969

也许有更好的方法来做到这一点而不必使用布尔值?因此,让我在更一般的意义上重新表述我的问题:

我如何连接 N 个 int 值到一个 target int 中?

谢谢!

【问题讨论】:

  • 不是答案,但我认为更适合您的工具是 BitArray
  • 我不明白为什么value41)贡献了两个位,01。我认为它应该只给 one 位?如果每个 int 值根据其大小贡献 0 到 31 位,那么编码可能会很有趣。
  • @Jeppe 即使 value4 为 1,它也需要 2 位,因为它可以是 0 到 3。在我的示例中,我只使用了值 1。
  • @JanTacci 在这种情况下,我下面的回答对你来说不是正确的。对于我的回答,not 对位长度2;4;2;2 进行硬编码。相反,它总是采用尽可能短的位长。因此它不会像您需要的那样返回固定长度的位模式 (10=2+4+2+2)。

标签: c# arrays int concatenation


【解决方案1】:

这里尝试编写代码来连接整数的二进制表示,其中二进制表示中没有前导零。

static int Concat(int high, int low)
{
  // find location i of most significant bit of "low"
  int i;
  for (i = 31; i > -1; --i)
    if ((low & (1 << i)) != 0)
      break;

  if (i == 31)
    return low;
  return low & (high << (i + 1));
}

static int ConcatMany(IEnumerable<int> values)
{
  return values.Aggregate(Concat);
}

应该这样使用:

int concatOfTwoNumbers = Concat(3, 12);

var list = new List<int> { 3, 12, 2, 1, };
int concatOfList = ConcatMany(list);

当然,如果串联中的位超过 32 位,则最高有效位“下降”到左侧。要使用 64 位整数,请将 highlow 更改为 long,并将 31 更改为 63

【讨论】:

  • @JanTacci 我意识到我的答案不是你想要的。请参阅我对您原始问题的新评论。但是即使只是对您的问题的误解,解决“我的”问题也很有趣。还要注意我的“串联”,您无法从“总和”中重建单个值,因为一旦执行串联,就无法判断各个“部分”(值)之间的“边界”在哪里。
【解决方案2】:

通常,将多个数字的位组合成一个的常用方法是这样(以您的值和位长度为例):

var result = value1 | (value2 << 2) | (value3 << 6) | (value4 << 8);

但是,您在问题末尾打印的数字是从背面到前面的数字。如果这就是你想要的,那就是:

var result = value4 | (value3 << 2) | (value2 << 4) | (value1 << 8);

当然,这假设代码知道每个值的所需位长。如果您在编译时不知道位长,那么您必须在运行时跟踪它,否则像 1 这样的单个 int 不会告诉您的代码从中使用多少位。

【讨论】:

  • 我确实知道目标中每个元素所需的位长度!
  • 不,你的答案很清楚。我说了什么其他的意思吗?
  • @JanTacci:谢谢。 :) 不,没关系,我只是误读了你的评论 :)
  • @JanTacci 但这并不能解决我理解的问题。对于每个int 值,取其二进制表示,删除前导零,然后与下一项连接。
  • @JeppeStigNielsen: value4 在他的示例中,有一个他想要保留的前导零。
猜你喜欢
  • 1970-01-01
  • 2012-09-29
  • 2016-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多