反转一个字节的算法

介绍一种高效的8位字节反转算法,通过并行计算实现快速反转。该算法分为三步,首先2位一组交换,接着4位一组交换,最后8位一组交换,巧妙地完成字节级别的反转。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

反转函数:

unsigned  char  reverse8( unsigned  char  c )
{
    c 
= ( c & 0x55 ) << 1 | ( c & 0xAA ) >> 1;
    c 
= ( c & 0x33 ) << 2 | ( c & 0xCC ) >> 2;
    c 
= ( c & 0x0F ) << 4 | ( c & 0xF0 ) >> 4;
    
return c;
}

它的算法是这样的:首先是2位2位为一组,交换前一半和后一半。再4位4位为一组,交换前一半和后一半。再8位为一组,交换前一半和后一半。
可能还有点说不清楚。我举个例子。
将1 2 3 4 5 6 7 8 反转。
(1)2个2个为一组,交换前一半和后一半, 变成:
  2 1 4 3 6 5 8 7
(2)4个4个为一组,交换前一半和后一半, 变成:
  4 3 2 1 8 7 6 5
(3)8个8个为一组,交换前一半和后一半,变成:
  8 7 6 5 4 3 2 1
反转成功。
这样的算法本来很是简单,很容易用数学归纳法证明其正确。这函数, 巧妙就巧妙在作了并行计算,分组,它一次就计算完了。

先看第一个语句。c = ( c & 0x55) << 1 | ( c & 0xAA ) >> 1; 
0x55其实就是01010101, 0xAA就是10101010
假设 c=abcdefgh
c & 0x55 = 0b0d0f0h,    c & 0xAA = a0c0e0g0
跟着,前者左移一位, b0d0f0h0, 后者右移一位, 0a0c0e0g, 再一个|运算,就两位两位交换了位置。
想象一下,你有一个长纸条,分成一格一格,每格写一个字,假如你将纸条每隔一格剪一个小洞,滑一格,覆盖在原来的纸条上,你就会看到两个两个字交换了位置。
(注: |运算可以换成+运算,想一想为什么)

转载自:http://blog.chinaunix.net/u/25096/showart_362366.html

 

### 字节跳动公司面试中的算法题解析 #### 单链表反转问题及其变种 字节跳动公司在面试过程中经常考察候选人对于数据结构的理解以及实际编程能力。其中,单链表的操作是一个常见的考点之一。具体来说,有一类问题是要求从链表的尾部开始分组并进行操作[^2]。 这类问题的核心挑战在于单向链表无法直接反向访问节点。因此,解决方法通常涉及递归或者栈辅助实现倒序处理逻辑[^4]。下面通过具体的例子说明如何应对这一类型的题目: 假设我们需要设计一个函数 `reverseKGroup` 来完成以下功能: 输入为一个单链表头指针 `head` 和整数 `k` ,输出一个新的链表头指针表示经过修改后的列表形式——即每连续 k 个结点作为一个子序列被翻转;如果最后剩余不足 k 的部分保持原样不变。 以下是 Python 实现版本的一个可能解法: ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def reverseList(head: ListNode) -> ListNode: prev = None current = head while current is not None: temp_next = current.next current.next = prev prev = current current = temp_next return prev def reverseKGroup(head: ListNode, k: int) -> ListNode: count = 0 cur = head # Check if there are at least k nodes remaining. while cur and count < k: cur = cur.next count += 1 if count == k: reversedHead = reverseList(head) # Recursively call on the rest of the list after reversing first group. head.next = reverseKGroup(cur, k) return reversedHead else: return head ``` 上述代码片段展示了基于递归方式解决问题的方法论。它先判断当前是否有足够的长度来进行一次完整的 K 组交换动作,如果有,则执行局部逆转过程,并继续对后续链条应用相同策略直到结束条件满足为止。 另外值得注意的是,在准备此类技术岗位笔试或现场考核环节时,除了掌握基础理论外还需要注重实战演练效果提升效率[^3]。 #### 动态规划经典案例分析 除开针对特定数据结构的设计之外,动态规划也是另一项备受关注的能力领域。比如最长公共子串(LCS)计算就是非常典型的代表作之一[^5]: 设字符串A长度为m,B长度为n,定义二维数组dp[m+1][n+1],初始化全零边界值;接着按照状态转移关系逐步填充其余位置数值直至最终求得目标结果. 其核心思想可以总结如下两条规则用于更新每一个单元格内的最大匹配数量记录: - 当前字符相等时继承左上角相邻区域已积累成果加一; - 否则取上方或者左侧较大者延续路径追踪方向标记; 此方法时间复杂度O(m*n),空间消耗同样如此但在某些场景下允许进一步优化减少内存占用量级至线性级别即可满足需求标准.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值