【问题标题】:How Do you reset a bit value in a string?如何重置字符串中的位值?
【发布时间】:2011-09-30 07:29:24
【问题描述】:

在最近的采访中,我收到了这样一个问题:

Given a string value, find out its 127th bit and reset it, do this in C language Reset means if that particular bit is 0 change to 1 and vice versa

我没有找到任何算法,但我想知道如何用C 语言解决这个问题。

编辑:

从少数人那里得到答案后,我尝试了这个:

#include<stdio.h>
void main()
{
    char *str="anto";
    str[15] ^= 0x80;
    printf("%s",str);
}

我得到的输出为:anto。现在我突然想到,改变一点不会改变输出?

【问题讨论】:

  • 稍微定义“重置”? (设置为 0?)
  • @Mysticial:你说得对,我已经编辑了我的问题。
  • 请给出一个之前和之后的示例,说明您期望它的行为方式,因为位编号有些随意,在这种情况下,“字符串”的含义并不完全清楚。
  • 在您的示例中,第 127 位已超过 4 个字符。
  • 我认为重置意味着将 1 更改为 0 并且 0 仍然是 0

标签: c bit-manipulation


【解决方案1】:

切换字符串中的任何位:

#include <limits.h>

void flip_bit(char *x, int bit_no) {
  (x + bit_no/CHAR_BIT) ^= 1 << bit_no%CHAR_BIT;
}

说明: 查找 bit_no:th 位分两步完成:

首先需要的整数字节数(整数除法): (x + bit_no/CHAR_BIT)

然后剩下的比特数一样多。这是通过将 1 移动 bit_no%CHAR_BIT 位(余数)。

最后使用 xor 运算符 (^) 切换位。

【讨论】:

  • 似乎是一个非常难的算法!你能解释一下flip_bit函数里面的那一行吗?
【解决方案2】:

假设char为8位,字节序为小端序:

char *str = ...;

str[15] ^= 0x80;

这将翻转第 127 位。

编辑:

如果 bit-endian 是 big-endian,则使用 0x01 代替。

答案还取决于位的编号方式。如果我们从 0 开始编号,则使用 0x80。如果我们从 1 开始索引,那么我们使用0x40。 (0x010x02 用于大端)

编辑 2: 这是一般情况:(假设相同)

char *str = ...;
int bit = 127;

int index = bit / 8;   //  Get the index
int chbit = bit % 8;   //  Get which bit in the char

int mask = 1 << chbit; //  Build the mask

str[index] ^= mask;    //  XOR to flip the bit.

【讨论】:

  • ^= 我猜这是XOR。但是你能详细解释一下吗?我对 C 很陌生。我可以找到第一行在做什么,但不是第二行。
  • 对于每个位,如果位相同,XOR 运算符将返回 0,如果位不同,则返回 1。因此,如果您对 1 进行异或运算,您将翻转位。
  • 是的,这里的字节序有点模棱两可。如果字节序错误,则使用0x01
  • 请注意“第 127 位”!=“第 127 位”。第一位是位 0,第二位是位 1,依此类推,所以第 N 位是位 N-1。
  • +1 用于指定你的逻辑与小端...如果可能的话也写为大端..!!!
【解决方案3】:

您要问的第一个问题是 toggle 而不是 reset 好的

稍微切换一下

XOR 运算符 (^) 可用于切换位。

 number ^= 1 << x; 

这将切换位 x。 有关此类想法的更多信息read this

现在您知道字符串是字符数,1 个字符的大小是 1 个字节,所以现在您想切换哪个位,而不是 X,并用字符串代替数字。

【讨论】:

    【解决方案4】:

    您必须创建一个位掩码,对于第 n 位,位掩码将是:

    char *bitmask = 2^(n-1);
    

    并翻转位 xor 字符串和位掩码:

    string ^= bitmask;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-24
      • 2018-09-02
      • 2022-01-18
      • 2021-01-18
      • 2014-10-07
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      相关资源
      最近更新 更多