目录

预备知识

左移运算(<<)

位运算 

一、从最朴素的方法开始

二、如果只关心“有没有出现过”,不关心“次数”,还能不能更省?

三、有没有一种更“紧凑”的方式表示26个开关?

四、用一个整数的每一位表示一个字母是否出现


预备知识

左移运算(<<

x << n

表示:把整数 x 的二进制表示整体向左移动 n 位

举例说明:

我们来观察下面的例子(以 int 为例,32 位):

int x = 1;00000000 00000000 00000000 00000001

现在我们做左移操作:

int y = x << 3;

意思是把 1 向左移动 3位,得到的新值是 8

为什么?看图:

x = 00000000 00000000 00000000 00000001   // 原始值是 1
y = 00000000 00000000 00000000 00001000   // 变成了 8

1 × 2^3 = 8

✅ 左移 n 位 就相当于 乘以 2ⁿ

左移的“位图”意义

我们现在不把整数当作“数”,而当作一排开关/位

int mask = 1 << i;  // 表示第 i 位是 1,其余是 0
imask(二进制)十进制
000000000 00000000 000000011
100000000 00000000 000000102
200000000 00000000 000001004
300000000 00000000 000010008
2500000010 00000000 0000000033554432
mask = 1 << ('c' - 'a');  // 表示字符 'c' 的那一位

 所以就能精准地表示:字母 'c' 这个字符的“标志位”是否应该置 1


位运算 

ORing(按位或)

把某一位设置为 1(“合并标记”)

💡 场景:

想要记录:这个字符 已经出现过了

我们通过:

bitmask = bitmask | mask;

示例:

bitmask = 00000000 00000000 00000000 00000101
mask    = 00000000 00000000 00000000 00000100  // 想设置第2位bitmask | mask = 00000000 00000000 00000000 00000101

注意:已经是 1 的位不会被改动;为 0 的位被“点亮”

快写法(更常见):

bitmask |= mask;

完全等价于 bitmask = bitmask | mask

ANDing(按位与)

检查某一位是否是 1(“掩码检查”)

💡 场景:

想要判断:这个字符是否 已经出现过

通过:

if ((bitmask & mask) > 0)// 第 i 位是 1,说明已经出现

示例:

bitmask = 00000000 00000000 00000000 00000101  // 第0位和第2位是1
mask    = 00000000 00000000 00000000 00000100  // 想查第2位bitmask & mask = 00000000 00000000 00000000 00000100  // 非0 → 出现过

如果该位是 0,则结果为全 0

技术总结:“一个整数的每一位代表一个状态,我们用按位或 | 来点亮,用按位与 & 来检测。”


一、从最朴素的方法开始

问题目标

给定一个小写字母字符串,比如:"programming"

我们想找出:哪些字母 出现过不止一次(如:r, g, m

我们第一时间想到的,是记录每个字母出现的次数:

  • 可以用数组 int count[26] 来记录每个字母是否出现

  • 索引通过 'c' - 'a' 映射到 0~25(参考:数据结构:找出字符串中重复的字符(Finding Duplicates in a String)——使用哈希表 -CSDN博客

这很好用,但我们接着问:

二、如果只关心“有没有出现过”,不关心“次数”,还能不能更省?

我们回顾需求:

  • 我不在乎你出现了几次

  • 我只想知道你是不是已经来过一次

  • 如果再次遇到你,我就说你是重复字符

于是我们意识到:

我不需要记录次数,只需要记录「有没有来过」

那我需要 26 个“是否来过”的记录

想法:

bool seen[26] = {false};
  • 'a' 来了 → seen[0] = true

  • 'g' 来了 → seen[6] = true

  • 再次遇到 'g',发现 seen[6] == true → 它是重复的!

 这已经是一个优化:我们只用 26 个 bit(布尔量),不记录次数了。

三、有没有一种更“紧凑”的方式表示26个开关?

我们再想进一步优化空间:

如果我们有一个可以表示「26个状态」的结构,我们就能把 seen[26] 合并成一个东西。

你也许会联想到:

  • 一个 bool 变量本质上需要 1 字节(8位)

  • 26 个 bool 实际上占用了 26 字节 ≈ 208 bits,但其实我们只需要 26 个 bit 就够了!

于是我们问:

❓ 有没有什么东西,能存储多个“是/否”状态?

想一想数字的二进制!

例子:

int x = 0;  // 二进制:00000000 00000000 00000000 00000000

这不就是 32 个“是/否”开关吗?每一位只能是 0 或 1!

我们现在重新定义:

一个 int 类型(32位),我们只用前 26 位,每一位表示一个字母是否已经出现过:

  • 变量 int checker = 0;

  • 每当字符 ch 出现时,我们设法标记它的“位置 i”为 1

  • 如果下一次这个位置已是 1 → 它是重复的!

我们用 1 << i 来构造这个“单个字母对应的位置”

字母位位置说明
'a'0bit 0 表示 a 是否出现
'b'1bit 1 表示 b 是否出现
'c'2bit 2 表示 c 是否出现
.........
'z'25bit 25 表示 z 是否出现

所以我们的问题变成了:

  • 有一个整型变量 int bitmask = 0;,代表 26 个字母的状态

  • 每个小写字母 'a''z',分别映射到第 0 位到第 25 位

  • 我想对某个字母做两件事:

    1. 检测它是否已经出现(对应的位是不是 1)

    2. 标记它出现过(把对应的位设为 1)


四、用一个整数的每一位表示一个字母是否出现

第一步:确定某个字符应该对应哪一位(位置)

我们先要知道:'c' 应该对应 bitmask 的哪一位?

用以下方式:

int pos = ch - 'a';  // 'a' = 0, 'b' = 1, ..., 'z' = 25
字符ASCII'ch' - 'a'位位置
'a'970第 0 位
'c'992第 2 位
'z'12225第 25 位

第二步:构造一个“掩码”来访问这一位

我们的问题是:“如何选中第 pos 位?”

我们用左移操作构造:

int mask = 1 << pos;

含义是:

  • 1 << pos 就是一个整数,只有第 pos 位是 1,其他全是 0

posmask(二进制)十进制
000000000 00000000 000000011
200000000 00000000 000001004
500000000 00000000 0010000032

第三步:判断该字符是否出现过(读位)

此时我们就可以“检测”:

if ((bitmask & mask) != 0) {// 字符 ch 已经出现过了
}

解释:

  • bitmask & mask

    • 如果该位是 1,结果就是 mask 本身(非 0)

    • 如果该位是 0,结果是 0

所以我们通过这个判断该字符是否出现。

 第四步:标记该字符出现(写位)

如果该位还没有被设置,我们就“标记”它出现过:

bitmask = bitmask | mask;
//或者简写为:
bitmask |= mask;

这会把原来的 bitmask 中的第 pos 位设为 1,其他位保持不变。 

第五步:代码实现 
1. 忽略非小写字母字符:

    if (ch < 'a' || ch > 'z')continue;

2. 把当前字符映射为位索引:

int i = ch - 'a';  // 假设是小写字母

 3. 构造一个掩码,代表“我要检查的位”:

int mask = 1 << i;  // 只把第 i 位设置为 1

4. 检查是否已经来过:

if ((checker & mask) > 0) {// 说明这位之前已经是 1,重复了
}

5. 否则,设置该位为 1:

checker |= mask;

完整代码实现(只用于小写字母)

#include <iostream>
using namespace std;void findDuplicatesUsingBits(const char str[]) {int checker = 0;cout << "重复字符有:";for (int i = 0; str[i] != '\0'; i++) {char ch = str[i];if (ch < 'a' || ch > 'z')continue;  // 忽略非小写字符int pos = ch - 'a';int mask = 1 << pos;if ((checker & mask) > 0) {cout << ch << " ";} else {checker |= mask;}}cout << endl;
}int main() {const char str[] = "programming";findDuplicatesUsingBits(str);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/90424.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/90424.shtml
英文地址,请注明出处:http://en.pswp.cn/web/90424.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DevOps 完整实现指南:从理论到实践

DevOps 是一种集软件开发&#xff08;Dev&#xff09;与 IT 运维&#xff08;Ops&#xff09;于一体的文化、实践和工具链&#xff0c;旨在通过自动化流程、持续集成/持续交付&#xff08;CI/CD&#xff09;、基础设施即代码&#xff08;IaC&#xff09;和跨团队协作&#xff0…

使用 5 种安全解决方案将 Android 短信导出为PDF

想要将安卓手机短信导出为 PDF 格式&#xff0c;用于法律用途、情感表达或仅仅为了记录&#xff1f;总之&#xff0c;您可以保存安卓手机短信并将其转换为 PDF 格式&#xff0c;确保它们井然有序&#xff0c;方便打印。快来获取解决方案吧&#xff01;第 1 部分&#xff1a;如何…

再谈fpga开发(fpga开发的几个差异)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】学习嵌入式的同学都知道&#xff0c;嵌入式一般分成这几种chip&#xff0c;有51&#xff0c;有stm32 mcu&#xff0c;有soc&#xff0c;有dsp&#…

Kafka运维实战 11 - kafka查看消息的具体内容【实战】

目录kafka 消息查看1. 直接查看日志文件内容步骤&#xff1a;2. 使用 Kafka 工具查看日志主要参数说明常用命令&#xff1a;输出说明&#xff1a;3. 注意事项kafka 消息日志文件详解我们有时候遇到这样的需求&#xff0c;需要查看下kafka消息的内容。 kafka 消息查看 查看 Ka…

【自动化测试】JMeter+Jenkins自动化接口与性能测试环境部署指南

环境准备与基础配置 软硬件环境要求 工具链安装部署 工具链安装部署涉及JDK、JMeter、Jenkins等核心组件,其在Linux与Windows环境下的安装流程存在显著差异,企业级部署需重点关注静默安装、权限控制及数据备份配置。以下从组件安装差异、企业级部署要点及备份配置三方面展开…

三步实现Android系统级集成:预装Google TTS + 默认引擎设置 + 语音包预缓存方案

在定制Android系统时&#xff0c;预装Google TTS引擎并实现开箱即用的语音服务能显著提升用户体验。本文将详解预装APK→设为默认引擎→语音包预缓存的实现方案&#xff0c;适用于ROM开发者或系统定制场景。分步实现方案 预装Google TTS APK 预装APK这里可以采用很多种方式&…

Python基础学习第三课:数据结构与文件操作

以下是Python基础学习第三课的完整内容&#xff0c;重点讲解数据结构&#xff08;列表、字典、元组、集合&#xff09;和文件操作&#xff0c;通过实例演示如何高效管理和操作数据&#xff1a;Python基础学习第三课&#xff1a;数据结构与文件操作一、课程目标1. 掌握四种核心数…

【PHP 流程控制完全指南】

PHP 流程控制完全指南&#x1f9e0; 一、什么是流程控制&#xff1f; 在编程中&#xff0c;流程控制是指控制程序执行顺序的语句。它决定了代码是“从上往下执行”&#xff0c;还是“根据条件跳转”&#xff0c;或者“循环执行某些代码”。 PHP 中的流程控制语句主要包括&#…

Kafka运维实战 05 - kafka 消费者组和重平衡(Rebalance)

目录什么是消费者组&#xff1f;消费者组如何工作&#xff1f;位移&#xff08;Offset&#xff09;消费者组的核心机制&#xff1a;重平衡&#xff08;Rebalance&#xff09;触发条件重平衡影响在消息队列&#xff08;如 Kafka&#xff09;的世界里&#xff0c;消费者组是实现高…

Mysql-UDF提权

UDF&#xff08;User Defined Function&#xff09; 是用户自定义函数&#xff0c;是 MySQL 支持的一种机制&#xff0c;可以通过 C语言写动态链接库&#xff08;.so / .dll&#xff09;&#xff0c;然后让 MySQL 调用这些函数&#xff0c;调用方式与一般系统自带的函数相同&am…

车规级CANFD芯片在汽车车身控制方案中的应用解析

摘要&#xff1a;随着汽车电子技术的不断发展&#xff0c;汽车车身控制系统对信息传输的效率、可靠性及抗干扰能力等要求日益提高。车规级CANFD芯片作为一种先进的通信芯片&#xff0c;凭借其高速率、高可靠性以及强大的抗干扰能力&#xff0c;成为汽车车身控制系统中的关键组件…

docker desktop 访问 https://registry-1.docker.io/v2/ 报错问题解决

win11 docker desktop 配置国内镜像加速器 1、win11管理员运行powershell notepad "$env:APPDATA\Docker\config.json"2、配置以下内容保存 {"registry-mirrors": ["https://hub-mirror.c.163.com","https://docker.mirrors.ustc.edu.cn&qu…

LLaMA-Factory微调教程1:LLaMA-Factory安装及使用

文章目录 环境搭建 LLaMA-Factory 安装教程 模型大小选择 环境搭建 Windows系统 RTX 4060 Ti(16G显存) python 3.10 cuda=12.6 cudnn torch== 2.7.1+cu126 torchvision==0.22.1+cu126 torchaudio== 2.7.1+cu126 PS C:\Users\18098> nvidia-smi Tue Jul 22 01:52:19 2025 +…

Oracle数据库索引性能机制深度解析:从数据结构到企业实践的系统性知识体系

一、数据检索的根本问题与索引产生的必然性 1.1、数据检索的本质挑战 在理解Oracle索引的性能优势之前&#xff0c;必须回到数据检索的根本问题。当面对海量数据时&#xff0c;传统的线性搜索&#xff08;Sequential Search&#xff09;面临着不可调和的性能瓶颈。这种瓶颈源于…

c#面向对象程序设计

一、面向对象与面向过程的核心区别&#xff08;概念铺垫&#xff09;代码背景开篇对比了两种编程范式&#xff1a;面向过程&#xff08;PP&#xff09;&#xff1a;按步骤分解问题&#xff08;如 “输入长→输入宽→计算面积”&#xff09;&#xff1b;面向对象&#xff08;OOP…

Kylin V10 4070安装nvidia驱动+CUDA+docker安装

目录 1.系统版本信息 2.安装nvidia驱动 3.CUDA安装 4.docker离线安装 1.系统版本信息 查看一下系统版本&#xff0c;命令为&#xff1a; cat /etc/kylin-release2.安装nvidia驱动 编辑/usr/lib/modprobe.d/dist-blacklist.conf文件 blacklist nvidiafb加#号注释掉 添加…

首家!数巅AskBI通过中国信通院数据分析智能体专项测试

近日&#xff0c;在中国信息通信研究院组织的数据分析智能体&#xff08;Data Agent&#xff09;专项测试中&#xff0c;数巅生成式分析智能体AskBI顺利完成专项测试的全部内容。《数据智能体技术要求》标准及测试简介中国信通院云计算与大数据研究所依托中国通信标准化协会大数…

一些Avalonia与WPF内容的对应关系和不同用法

UIElement、FrameworkElement和ControlWPFAvaloniaUIElementControlFrameworkElementControlControlTemplatedControl在 WPF 中&#xff0c;通过继承 Control 类来创建新的模板控件&#xff0c;而在 Avalonia 中&#xff0c;从 TemplatedControl 继承。在 WPF 中&#xff0c;通…

【REACT18.x】CRA+TS+ANTD5.X封装自定义的hooks复用业务功能

模拟react中的hooks方法&#xff0c;实现自定义的hooks来封装我们需要重复使用的组件&#xff0c;来优化代码。这种hooks也是利用了react的原生hooks来实现我们需要的特定业务&#xff0c;可以返回任何我们需要的值&#xff0c;也可以不返回值&#xff0c;作为一个副作用方法使…

Vue CSR 到 Nuxt 3 SSR 迁移:技术实现与问题解决实录

1. 迁移动机与技术选型1.1 CSR 架构的局限性 基于 Vue 3 和 Vite 构建的客户端渲染 (CSR) 单页应用 (SPA) 提供了良好的开发体验和用户交互流畅性。但是其核心局限在于&#xff1a;搜索引擎优化 (SEO)&#xff1a;初始 HTML 响应仅包含一个根 div 元素&#xff0c;实际内容由 J…