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 语言过程中,实现一些小型项目可以帮助我们更好的熟悉和巩固所学的知识。这里介绍一种用 C 语言实现学生信息管理系统的方法,使用单链表来管理学生详细信息,包括编号、姓名、年龄、性别、专业等。本文将讲解该项目的完整攻略。 步骤 步骤1:设计结构体 首先,在程序中需要设计一个结构体来储存学生详细信息。可以考虑在…

    C 2023年5月23日
    00
  • 使用C/C++读写.mat文件的方法详解

    使用C/C++读写.mat文件的方法详解 什么是.mat文件 .mat文件是一种MATLAB的数据格式,即它是MATLAB的数据文件。MATLAB(矩阵实验室)是美国MathWorks公司出品的商业数学软件。它主要用于算法开发、数据可视化、数据分析以及数值计算的统一性处理等。其数据的保存格式是以.mat文件格式进行保存的。 .mat文件的特点 .mat文件因…

    C 2023年5月23日
    00
  • 解析c++中参数对象与局部对象的析构顺序的详解

    解析C++中参数对象与局部对象的析构顺序的详解 在C++中,当一个函数使用参数对象时,我们需要关注参数对象与局部对象的析构顺序。这个问题可能会导致一些意外的问题,尤其是在使用对象的拷贝构造函数时。本文将详细讲解这个问题。 问题背景 在C++中,传递给函数参数的对象是在局部作用域内声明的,这些对象在函数结束时会被销毁。同时,当这些对象被传递到另一个对象的拷贝构…

    C 2023年5月22日
    00
  • C语言结构体版学生成绩管理系统

    下面就结构体版学生成绩管理系统的完整攻略进行详细讲解,包括操作流程、代码实现和两个实例说明。 操作流程 首先要定义一个结构体,用于存储学生成绩相关的信息,比如学号、姓名、数学成绩、语文成绩、英语成绩等。 接着,需要定义一个数组,用于存储这些结构体,数组的长度可以自行设定。 然后,编写函数实现添加学生、查询学生、修改学生、删除学生、显示全部学生成绩等基本操作。…

    C 2023年5月23日
    00
  • C++的类型转换详细介绍

    C++的类型转换详细介绍 什么是类型转换? 在程序开发中,我们常常需要在不同的数据类型之间进行转化,以方便数据的处理和使用。C++提供了多种类型转换方式,这些方式叫做类型转换。 隐式类型转换 隐式类型转换是指,当程序需要的数据类型和给出的数据类型不一致时,系统会自动将数据类型进行转换。例如: int a = 10; double b = 3.14; // 自…

    C 2023年5月23日
    00
  • C++德州扑克的核心规则算法

    C++德州扑克的核心规则算法 C++德州扑克的核心规则算法主要包括底牌牌型的判断、公共牌牌型的判断、牌的大小比较等,下面将具体介绍这些算法的实现方法。 底牌牌型的判断 底牌牌型的判断是德州扑克中最基本的规则之一,其判断方法如下: 先根据底牌的花色和点数进行分类,将相同花色的牌和相同点数的牌分开。 判断是否存在对子、三条、四条等牌型,如果存在,则底牌的牌型为该…

    C 2023年5月23日
    00
  • C++中的运算符和表达式

    让我来给大家详细讲解一下C++中的运算符和表达式。 运算符 在编程中,我们需要使用各种运算符对数据进行各种操作,C++提供了以下几种运算符: 算术运算符 算术运算符用于基本的算术操作,如加减乘除和取模。具体如下: 运算符 描述 + 加法 – 减法 * 乘法 / 除法 % 取模(求余数) 示例代码如下: #include <iostream> in…

    C 2023年5月24日
    00
  • C语言 二叉查找树性质详解及实例代码

    C语言二叉查找树性质详解及实例代码 什么是二叉查找树? 二叉查找树,也称二叉搜索树,它是一种基于对比的动态数据结构。它的定义如下: 每个节点都包含一个键值,且键值唯一; 每个节点的左子树只包含小于当前节点的节点; 每个节点的右子树只包含大于当前节点的节点; 左右子树都是二叉搜索树; 二叉查找树的性质 二叉查找树的性质体现在它的增、删、查等操作中,具体有以下几…

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