当前位置: 首页 > article >正文

用C++‘数1’这道题,带你彻底搞懂整数位分离的循环技巧(附避坑点)

用C‘数1’这道题带你彻底搞懂整数位分离的循环技巧附避坑点在编程学习的道路上整数位分离是一个看似简单却暗藏玄机的基础操作。许多初学者在解决统计数字中1的个数这类问题时往往能写出大致正确的代码却对背后的原理和潜在陷阱一知半解。今天我们就以C为例深入剖析这个在算法题中频繁出现的核心编程模式。1. 理解整数位分离的基本原理整数位分离简单来说就是将一个整数的每一位数字单独提取出来的过程。在C中这通常通过两个关键操作实现% 10取模运算和/ 10整数除法。让我们先看一个最简单的实现while (number ! 0) { int digit number % 10; // 获取当前最后一位数字 number / 10; // 去掉已经处理的最后一位 // 对digit进行处理... }这个看似简单的循环结构却包含了几个需要深入理解的要点取模运算的特性number % 10总是返回number的个位数无论number是正数还是负数整数除法的截断行为/ 10会直接丢弃小数部分相当于向下取整循环终止条件当number变为0时表示所有位数都已处理完毕注意对于负数% 10的结果也是负数。如果处理需要考虑负号的情况需要先取绝对值。2. 从数1问题看位分离的实际应用让我们通过具体的统计数字中1的个数问题看看位分离技巧如何应用。题目要求给定一个正整数n统计从1到n的所有整数中数字1出现的总次数。2.1 暴力解法逐个数字检查最直观的方法是遍历1到n的每个数字分离其每一位并统计1的个数int countDigitOne(int n) { int count 0; for (int i 1; i n; i) { int num i; while (num ! 0) { if (num % 10 1) { count; } num / 10; } } return count; }虽然这种方法简单易懂但它的时间复杂度是O(n*log n)当n很大时效率不高。不过它完美展示了位分离的基本应用。2.2 位分离中的常见错误初学者在使用位分离技巧时常犯以下几个错误忽略负数情况直接对负数进行位分离会导致错误结果int num -123; while (num ! 0) { int digit num % 10; // digit可能是负数 num / 10; // ... }修改原始数据有时我们需要保留原始数字却意外修改了它int original n; while (n ! 0) { // 这会改变n的值 // ... } // 之后n已经变为0了循环条件错误使用 0而不是! 0这在处理负数时会提前终止while (n 0) { // 对于负数会直接跳过循环 // ... }3. 位分离技巧的进阶应用掌握了基本的位分离技巧后我们可以将其应用到更多场景中。以下是几个常见的应用示例3.1 数字反转将一个整数反转如123→321-456→-654int reverse(int x) { int rev 0; while (x ! 0) { int digit x % 10; x / 10; // 处理可能的溢出 if (rev INT_MAX/10 || (rev INT_MAX/10 digit 7)) return 0; if (rev INT_MIN/10 || (rev INT_MIN/10 digit -8)) return 0; rev rev * 10 digit; } return rev; }3.2 判断回文数判断一个整数是否是回文数正读反读都相同bool isPalindrome(int x) { if (x 0) return false; // 负数不是回文数 int original x; long reversed 0; // 使用long防止反转时溢出 while (x ! 0) { reversed reversed * 10 x % 10; x / 10; } return original reversed; }3.3 计算数字位数计算一个整数的位数int countDigits(int num) { if (num 0) return 1; // 特殊情况处理 int count 0; while (num ! 0) { count; num / 10; } return count; }4. 性能优化与数学原理虽然位分离技巧在很多情况下足够使用但了解其背后的数学原理可以帮助我们写出更高效的代码。以统计1的个数问题为例我们可以用数学方法优化4.1 数学方法优化通过分析数字每一位上1出现的规律可以得到O(log n)的解法int countDigitOneOptimized(int n) { int count 0; for (long i 1; i n; i * 10) { long divider i * 10; count (n / divider) * i min(max(n % divider - i 1, 0L), i); } return count; }这个算法基于以下观察对于每一位个位、十位、百位等1出现的次数可以通过公式计算得出而不需要逐个数字检查。4.2 位分离与其他算法的结合位分离技巧常与其他算法结合使用。例如在动态规划中处理数字相关问题时// 示例计算小于n的所有数字中不含特定数字的数字个数 int countSpecialNumbers(int n) { string s to_string(n); int len s.length(); vectorvectorint memo(len, vectorint(1 10, -1)); functionint(int, int, bool, bool) dfs [](int pos, int mask, bool is_limit, bool is_num) { if (pos len) return is_num ? 1 : 0; if (!is_limit is_num memo[pos][mask] ! -1) return memo[pos][mask]; int res 0; if (!is_num) res dfs(pos 1, mask, false, false); int up is_limit ? s[pos] - 0 : 9; for (int d is_num ? 0 : 1; d up; d) { if (!(mask (1 d))) { res dfs(pos 1, mask | (1 d), is_limit d up, true); } } if (!is_limit is_num) memo[pos][mask] res; return res; }; return dfs(0, 0, true, false); }在这个例子中我们将数字转换为字符串来处理每一位这实际上也是一种位分离的变体。5. 实际开发中的注意事项在实际项目中使用位分离技巧时还需要考虑以下工程实践问题5.1 边界条件处理INT_MIN的特殊性-2147483648的绝对值比INT_MAX大1直接取负会导致溢出int num -2147483648; // INT_MIN // int abs_num -num; // 这会溢出大数处理当数字可能很大时要考虑使用更大范围的类型long long bigNum 123456789012345LL;5.2 代码可读性与重构将位分离逻辑封装成函数可以提高代码可读性vectorint getDigits(int num) { if (num 0) return {0}; vectorint digits; while (num ! 0) { digits.push_back(num % 10); num / 10; } reverse(digits.begin(), digits.end()); return digits; }5.3 测试用例设计全面的测试用例应该包括0正负数边界值INT_MAX, INT_MIN包含各种数字组合的数全为1的数如111不含1的数如999void testCountDigitOne() { assert(countDigitOne(0) 0); assert(countDigitOne(1) 1); assert(countDigitOne(10) 2); assert(countDigitOne(11) 4); assert(countDigitOne(20) 12); // ... }

相关文章:

用C++‘数1’这道题,带你彻底搞懂整数位分离的循环技巧(附避坑点)

用C‘数1’这道题,带你彻底搞懂整数位分离的循环技巧(附避坑点) 在编程学习的道路上,整数位分离是一个看似简单却暗藏玄机的基础操作。许多初学者在解决"统计数字中1的个数"这类问题时,往往能写出大致正确的…...

Ile-Ser-Bradykinin(T-Kinin) ;ISRPPGFSPFR

一、基础信息多肽名称:Ile-Ser-Bradykinin,别名 T-Kinin(T - 激肽) 三字母序列:Ile-Ser-Arg-Pro-Pro-Gly-Phe-Ser-Pro-Phe-Arg 单字母序列:ISRPPGFSPFR 氨基酸数量:11 aa 结构修饰:线…...

别再只会用Broadside了!手把手教你用Endfire阵列搞定智能音箱的远场拾音

智能音箱远场拾音实战:从Broadside到Endfire的工程进阶指南 当你的智能音箱在厨房油烟机轰鸣时依然能清晰识别"播放爵士乐"指令,或是会议设备在开放式办公室准确捕捉三米外的发言——这背后往往是Endfire阵列的精密调校在发挥作用。作为嵌入式…...

何为可编程控制器?可编程控制器4大内容介绍

可编程控制器在控制中常为使用,因此本文将从4大方面对可编程控制器予以介绍,以增进大家对可编程控制器的了解。这4大方面包括:1.何为可编程控制器?2. 可编程控制器的基本组成,3. 可编程控制器发展史,以及4. 可编程控制…...

从USB3.2到PCIe 5.0:我的高速串行链路阻抗匹配踩坑实录(附Sigrity仿真文件)

从USB3.2到PCIe 5.0:我的高速串行链路阻抗匹配踩坑实录 去年负责一款数据中心加速卡的设计时,我遇到了职业生涯中最棘手的高速信号完整性问题。这块板卡需要同时支持PCIe 5.0 x16和四个USB3.2 Gen2x2接口,当第一批工程样机回来进行信号测试时…...

保姆级教程:用易语言和大漠插件给游戏做字库,实现自动化文字识别(附模块源码)

零基础实战:易语言与大漠插件游戏字库制作全指南 游戏自动化开发中,文字识别是绕不开的核心技术。想象一下,当你的程序能自动读取任务提示、NPC对话或物品名称时,整个自动化流程就拥有了"眼睛"。本文将彻底拆解大漠插件…...

从find到ind2sub:Matlab数据筛选后操作的完整工作流(以R2023b为例)

从find到ind2sub:Matlab数据筛选后操作的完整工作流(以R2023b为例) 在数据分析与科学计算领域,Matlab作为一款强大的工具,其矩阵操作能力尤为突出。面对大型矩阵或高维数组时,如何高效地定位并处理特定条件…...

ChatGPT写论文被判AI怎么办?降AI率完整应对攻略+工具推荐!

ChatGPT写论文被判AI怎么办?降AI率完整应对攻略工具推荐! ChatGPT 是 2022 年起最早被广泛使用的大模型,现在依然是不少留学生、研究生写英文论文/中文论文的首选。但它写出来的论文在 AIGC 检测平台(Turnitin、知网英文模块、维普…...

【运算篇】算术与逻辑律令(3):比特的手术刀,镜像翻转与空间缝合

在 4-bit 的逻辑地牢里,如果说算术指令提供了“肌肉”,逻辑指令开启了“感官”,那么接下来我们要聊的,则是这台机器最细腻的形态手术。如果说 AND/OR 是在判定“存在”,那么 NOT 和移位指令(SHL/SHR&#x…...

暗黑破坏神2存档编辑器:d2s-editor网页版深度体验指南

暗黑破坏神2存档编辑器:d2s-editor网页版深度体验指南 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor 想要自由定制暗黑破坏神2的角色成长路径,却苦于找不到合适的工具?d2s-editor作为一款基于…...

突破音频平台限制:基于Go+Qt5的喜马拉雅下载器技术解析

突破音频平台限制:基于GoQt5的喜马拉雅下载器技术解析 【免费下载链接】xmly-downloader-qt5 喜马拉雅FM专辑下载器. 支持VIP与付费专辑. 使用GoQt5编写(Not Qt Binding). 项目地址: https://gitcode.com/gh_mirrors/xm/xmly-downloader-qt5 在数字化学习与娱…...

开源工具any2card:任意格式内容智能转换结构化卡片实战指南

1. 项目概述:从“任意格式”到“卡片”的智能转换革命最近在折腾个人知识库和内容管理时,我遇到了一个老生常谈但又无比棘手的问题:信息格式的碎片化。我的资料散落在各处,有PDF论文、网页文章、TXT笔记、甚至是一些图片里的文字。…...

新手也能看懂的SQL注入绕过实战:以BUUCTF的BabySQL靶场为例,手把手教你双写绕过

从零破解BabySQL:双写绕过的艺术与科学 当你第一次接触CTF比赛中的SQL注入题目时,那种既兴奋又困惑的感觉一定记忆犹新。面对BabySQL这样的靶场,新手常会遇到一个典型困境:明明知道应该用union select来获取数据,却发现…...

ROS机器人开发:用tf_monitor和tf_echo快速诊断你的坐标转换问题(附真实案例)

ROS机器人坐标转换问题诊断实战:从工具使用到思维升级 当机器人的激光雷达数据与地图匹配出现偏移,或者机械臂末端执行器总是偏离目标位置几厘米时,有经验的开发者会第一时间检查坐标转换系统。ROS中的tf库虽然强大,但一旦出现问题…...

【STM32H7实战】HRTIM高分辨率定时器在数字电源与电机控制中的高级应用与HAL库配置

1. HRTIM高分辨率定时器概述 HRTIM(High-Resolution Timer)是STM32H7系列中一个强大的定时器外设,专为数字电源转换、电机控制等高性能实时控制场景设计。相比普通定时器,它的分辨率高达184ps(在400MHz主频下&#xff…...

告别卡顿与臃肿:两种高效获取MATLAB Online账号的实战指南

1. 为什么你需要MATLAB Online? 如果你正在读这篇文章,大概率是因为你的电脑跑不动桌面版MATLAB了。我完全理解这种痛苦——当年我的老笔记本打开MATLAB要三分钟,运行个简单脚本风扇就狂转,更别提安装时那令人绝望的20GB硬盘占用…...

详解51单片机智能小车避障核心:超声波、漫反射与红外传感器的实战选型与调试

1. 智能小车避障传感器的核心选择 做智能小车最让人头疼的就是避障功能了。我当年第一次做51单片机小车时,光选传感器就折腾了好几个星期。市面上常见的避障传感器主要有三种:超声波模块、漫反射光电管和红外传感器。每种传感器都有自己的脾气&#xff…...

C#上位机开发入门:手把手教你用PowerPMAC SDK实现第一个通讯Demo

C#上位机开发入门:从零构建PowerPMAC通讯Demo的实战指南 引言 当你第一次打开PowerPMAC开发套件时,面对密密麻麻的库文件和数百页的技术手册,是否感到无从下手?作为工业自动化领域的核心控制器,PowerPMAC与上位机的通讯…...

如何5分钟搞定GitHub界面中文化:新手必看的浏览器插件终极指南

如何5分钟搞定GitHub界面中文化:新手必看的浏览器插件终极指南 【免费下载链接】github-chinese GitHub 汉化插件,GitHub 中文化界面。 (GitHub Translation To Chinese) 项目地址: https://gitcode.com/gh_mirrors/gi/github-chinese 还在为GitH…...

告别手动拼报文!用MQTT.fx和OneNet平台快速调试你的ESP8266物联网设备

用MQTT.fx与OneNet构建高效物联网调试工作流 调试物联网设备时,你是否厌倦了反复修改代码、烧录固件、查看串口日志的循环?当ESP8266与OneNet平台通信异常时,传统调试方式往往让我们陷入二进制报文的泥潭。本文将介绍如何通过MQTT.fx这款图形…...

BurstGPT:大语言模型驱动高性能计算,实现自然语言科学仿真

1. 项目概述:当大语言模型遇上高性能计算最近在AI和HPC(高性能计算)的交叉领域,一个名为BurstGPT的项目引起了我的注意。乍一看这个标题,你可能会觉得有点“缝合怪”的味道——Burst通常指代计算资源的突发式使用或高性…...

从MATLAB验证到RTL实现:一个完整华莱士树乘法器的设计、仿真与调试实战

从MATLAB验证到RTL实现:一个完整华莱士树乘法器的设计、仿真与调试实战 在数字信号处理、图形渲染和密码学等高性能计算领域,乘法器的效率往往成为系统瓶颈。传统阵列乘法器虽然结构规整,但随着位宽增加,其线性增长的延迟特性难以…...

如何一次性解决Windows系统“应用程序无法启动“的终极指南

如何一次性解决Windows系统"应用程序无法启动"的终极指南 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载…...

BlueArchive-Cursors:开源鼠标主题的技术实现与扩展应用指南

BlueArchive-Cursors:开源鼠标主题的技术实现与扩展应用指南 【免费下载链接】BlueArchive-Cursors Custom mouse cursor theme based on the school RPG Blue Archive. 项目地址: https://gitcode.com/gh_mirrors/bl/BlueArchive-Cursors BlueArchive-Curso…...

如何快速掌控Windows浏览器自由:3步掌握EdgeRemover终极系统优化工具

如何快速掌控Windows浏览器自由:3步掌握EdgeRemover终极系统优化工具 【免费下载链接】EdgeRemover A PowerShell script that correctly uninstalls or reinstalls Microsoft Edge on Windows 10 & 11. 项目地址: https://gitcode.com/gh_mirrors/ed/EdgeRem…...

Docker Hub命令行工具hub-tool:镜像仓库自动化管理的终极利器

1. 项目概述:一个被低估的Docker Hub命令行利器 如果你日常工作中需要和Docker Hub打交道,无论是管理个人镜像、处理团队仓库,还是需要自动化镜像的推送、拉取和清理,那么你很可能已经受够了在浏览器和命令行之间反复横跳的繁琐。…...

Cesium三维地形剖切与开挖:从原理到可复用组件封装

1. 为什么需要地形剖切与开挖功能? 在三维地理信息系统中,地形剖切与开挖是最常用的分析功能之一。想象一下,你正在规划一条地下隧道,或者需要分析某处地质构造,这时候如果能把地表"切开"查看内部情况&#…...

从结构设计认识组合梁结构

从结构设计认识组合梁结构 概念:由两种不同材料结合或不同工序结合而成的梁称为组合梁,亦称联合梁。 今天咱们从《钢标》第十四章来认识组合梁,本文只适合不直接承受动力荷载的组合梁结构设计。 (一)基本规定...

php artisan serve 在window上执行报错的问题

今天偶发想学习一下Laravel 当执行 php artisan serve 结果一直没法起来 报错信息如下所示: 当前php 环境为 8.2.9 php -v解决办法: php -S localhost:9999 -t public...

D2DX终极指南:让《暗黑破坏神2》在现代PC上重获新生的Glide封装器

D2DX终极指南:让《暗黑破坏神2》在现代PC上重获新生的Glide封装器 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx …...