C++求1到n中1出现的次数以及数的二进制表示中1的个数

C++求1到n中1出现的次数

题目描述

给定一个整数 n,求出从 1 到 n 中数字 1 出现的次数。

示例 1

输入: n = 13
输出: 6
解释: 数字 1 出现在以下数字中: 1, 10, 11, 12, 13。

实现思路

本题需要一些数学知识和代码技巧。我们可以分三个部分来考虑:

  1. 设定一个变量 count,用来记录数字 1 出现的次数。
  2. 对于从 1 到 n 的每一个数字,我们需要计算它二进制表示中 1 的个数。具体算法是利用位运算 & 得到一个数的各位值,与值 1 相事实,如果结果是 1,则说明原来的数二进制表示中该位为 1,否则为 0
  3. 累加每个数字二进制表示中 1 的个数,最后就得到了从 1 到 n 中数字 1 出现的次数。

代码实现

以下是 C++ 代码的实现,具体注释已在代码中给出。

class Solution {
public:
    int countDigitOne(int n) {
        int count = 0;
        long long factor = 1;
        int h, l, cur;  // h 为当前处理数位的高位,l 为当前处理数位的低位,cur 为当前处理的数位的值
        while (n / factor != 0) {
            h = n / (factor * 10);
            cur = (n / factor) % 10;  // 当前处理的数位
            l = n - (n / factor) * factor;  // 获取当前处理数位的低位值
            if (cur == 0) {
                count += h * factor;  // 在当前位为 0 时,计算数字 1 出现的次数
            } else if (cur == 1) {
                count += h * factor + l + 1;  // 在当前为为 1 时,计算数字 1 出现的次数
            } else {
                count += (h + 1) * factor;  // 在当前位大于 1 时,计算数字 1 出现的次数
            }
            factor = factor * 10;  // 更新处理的数位
        }
        return count;
    }
};

以上代码的时间复杂度为 $O(\log n)$。

数的二进制表示中1的个数

题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

示例 1

输入: 11
输出: 3
解释: 数字 11 的二进制为 1011,其中有三个 1。

实现思路

对于一个二进制数,如果该数的二进制表示中有 $k$ 个 1,则该数字与数字 $2^{k-1}$ 做与运算后的结果为 0。这是因为 $2^{k-1}$ 的二进制表示中只有一个 1,这个 1 对应到与它相交运算的另一个数的二进制表示中也只会有一个 1。

因此,我们可以利用这个方法来计算一个数的二进制表示中 1 的个数。具体实现思路是,从低位到高位依次判断每一位是否为 1,如果是则计数器加 1,同时将该数与当前所在的位数对应的 $2^n$ 值做与运算,判断是否等于 0,如果相等则结束循环。

代码实现

以下是 C++ 代码的实现,具体注释已在代码中给出。

class Solution {
public:
    int numberOf1(int n) {
        int count = 0;
        unsigned int flag = 1;  // 初始值是 1
        while (flag != 0) {
            if ((n & flag) != 0) {  // 判断当前位是否为 1
                count++;
            }
            flag = flag << 1;  // 更新对应的 $2^n$ 值 
        }
        return count;
    }
};

以上代码的时间复杂度为 $O(\log n)$。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++求1到n中1出现的次数以及数的二进制表示中1的个数 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C++实现简单的通讯录管理系统

    下面我来详细讲解“C++实现简单的通讯录管理系统”的完整攻略。 系统概述 通讯录管理系统是一个简单的信息管理系统。该系统可以实现以下功能: 添加联系人 显示联系人 删除联系人 查找联系人 修改联系人 清空联系人 退出通讯录管理系统 系统实现过程 设计流程 分析需求,确定功能模块 绘制流程图,确定各模块的处理流程 完成代码实现 运行测试 编写代码 首先,我们需…

    C 2023年5月23日
    00
  • C程序 寻找两个整数之间的阿姆斯特朗数字

    C程序 寻找两个整数之间的阿姆斯特朗数字使用攻略 概述 该程序是一个 C 语言的代码,用于寻找两个整数之间的阿姆斯特朗数字。阿姆斯特朗数字指的是一个 n 位数 (n ≥ 3),它的每个数位上的数字的 n 次幂之和恰好等于它本身。例如,1³ + 5³ + 3³ = 153。 程序运行环境 操作系统:Windows或Linux 编程语言:C语言 编译器:GCC编…

    C 2023年5月9日
    00
  • C语言实现歌手比赛系统

    C语言实现歌手比赛系统 系统概述 歌手比赛系统是一款使用C语言实现的命令行程序,旨在为歌手比赛场次提供后台管理功能。该系统可以添加、删除、修改歌手信息,查询歌手列表和评分,并且可以实现对歌手评分的计算和排名。 实现步骤 步骤一:创建数据结构 首先需要定义一个数据结构来存储歌手的信息,数据结构可以用结构体来进行描述。以下是一个示例结构体: typedef st…

    C 2023年5月23日
    00
  • C语言处理未初始化指针

    下面我会详细讲解“C语言处理未初始化指针”的完整使用攻略。 1. 什么是未初始化指针 从语言层面上来说,C语言中的指针默认是一个垃圾值或者未初始化的值,即该指针变量中存储的是一个未知的地址,而这个地址是随机的。 在实际编程中,如果程序员不小心对未初始化指针进行操作,就可能会导致错误和不可预见的行为。因此,在使用指针之前,程序员必须显式地对指针进行初始化操作。…

    C 2023年5月9日
    00
  • MySQL中json字段的操作方法

    当MySQL版本大于等于5.7.8时,支持json类型的字段。json是具有可读性和结构的数据格式,MySQL提供了方便的函数和操作符来处理json数据。下面将详细讲解MySQL中json字段的操作方法。 创建json类型的字段 在MySQL中创建json类型的字段,可以使用以下语法: CREATE TABLE table_name ( id INT PRI…

    C 2023年5月23日
    00
  • C++深入讲解类与对象之OOP面向对象编程与封装

    C++深入讲解类与对象之OOP面向对象编程与封装攻略 什么是OOP面向对象编程? OOP,全名是Object-Oriented Programming,中文翻译是面向对象编程,它是一种编程方法论和编程思想,其核心思想是将一组数据结构和处理它们的方法组成对象,以及描述对象间的相互关系,实现数据封装,代码重用和灵活性等特性。 OOP面向对象编程实现了三个基本特性…

    C 2023年5月22日
    00
  • C语言 if-else语句

    下面详细讲解一下C语言中if-else语句的完整使用攻略。 一、if-else语句 if-else语句是C语言中最基本的条件判断语句,用来根据条件来决定执行不同的语句。if语句用于判断条件是否成立,如果成立则执行if后面的语句,否则执行else后面的语句。 语法格式: if (condition) { // 如果条件成立,执行这里的语句 } else { /…

    C 2023年5月9日
    00
  • 深入解读C语言中的符号常量EOF

    关于“深入解读C语言中的符号常量EOF”的完整攻略,我会包含以下内容: 1. 什么是EOF EOF的全称是End Of File (文件结束符),是C语言标准库中定义的一个符号常量,其值为-1。根据C语言标准定义,EOF使用宏定义实现,其定义在stdlib.h或stdio.h头文件中。 EOF是一个特殊的,无格式字符,通常用于标识文件结束的位置。当读取文件时…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部