判断一个超大整数(字符串表示)是否为 2 的幂

酷晨吖_3908

酷晨吖_3908

2026-03-23

998人浏览

原创

判断一个超大整数(字符串表示)是否为 2 的幂

本文介绍如何在 java 中高效判断一个可能超过 long 范围的正整数(以字符串形式给出)是否为 2 的幂,避免类型溢出与高开销转换,提供两种纯字符串模拟算法及优化思路。

本文介绍如何在 java 中高效判断一个可能超过 long 范围的正整数(以字符串形式给出)是否为 2 的幂,避免类型溢出与高开销转换,提供两种纯字符串模拟算法及优化思路。

在处理大整数问题时,若输入数字长度可达 21 位(即可能远超 Long.MAX_VALUE ≈ 9.2×10¹⁸),直接使用 Long.parseLong() 或 BigInteger(题目明确禁用)将导致运行时异常或编译失败。此时必须基于字符串实现数学逻辑——而判断“是否为 2 的幂”这一问题,核心在于:所有 2 的正整数幂在十进制下均唯一对应某个特定值,且其二进制表示仅含单个 1;但本题无法转二进制(字符串太长),故需反向构造 + 字符串比较。

✅ 推荐解法:正向倍增模拟(字符串乘 2)

不尝试对输入做除法(易因多次 parseInt 溢出或抛 NumberFormatException),而是从 "1" 开始,不断将其乘以 2(字符串模拟),直到结果 ≥ 输入字符串为止。若某次结果恰好等于输入,则返回 1;否则返回 0。

该方法时间复杂度为 O(k × n),其中 k 是目标幂次(最多约 70,因 2⁷⁰ ≈ 1.2×10²¹),n 是当前数字位数,整体高效可控。

public static int power(String s) {
    // 去除前导零(如 "00128" → "128"),确保格式规范
    s = s.replaceFirst("^0+", "");
    if (s.isEmpty() || s.equals("0")) return 0;
    if (s.equals("1")) return 1; // 2^0 = 1

    String p = "1";
    int pLen = 1;
    int sLen = s.length();

    // 循环条件:当前幂 p 的位数更少,或位数相同但字典序更小
    while (pLen = 0; i--) {
            int digit = (p.charAt(i) - '0') * 2 + carry;
            doubled.setCharAt(i + 1, (char) ('0' + digit % 10));
            carry = digit / 10;
        }
        doubled.setCharAt(0, (char) ('0' + carry));

        // 去除前导零(若最高位无进位,则截掉)
        p = carry == 0 ? doubled.substring(1) : doubled.toString();
        pLen = p.length();
    }

    return p.equals(s) ? 1 : 0;
}

? 关键细节说明:

  • 使用 StringBuilder 避免频繁字符串拼接;
  • replaceFirst("^0+", "") 处理非法前导零输入(健壮性必备);
  • 比较采用 String.compareTo():当两字符串等长时,字典序等价于数值大小序(因均为纯数字);
  • 进位处理保证了多位乘法的正确性(如 "49" × 2 = "98","50" × 2 = "100")。

⚙️ 进阶优化:原地缓冲区(节省内存)

若对空间敏感(如嵌入式或高频调用场景),可复用单个 StringBuffer,将当前幂值右对齐存储,动态维护有效起始索引:

public static int power(String s) {
    s = s.replaceFirst("^0+", "");
    if (s.isEmpty() || s.equals("0")) return 0;
    if (s.equals("1")) return 1;

    int len = s.length();
    StringBuffer buf = new StringBuffer(len);
    buf.setLength(len);
    int start = len - 1; // 当前数字在buf中最右一位的位置
    buf.setCharAt(start, '1');

    while (start > 0 || buf.charAt(0) = start; i--) {
            int digit = (buf.charAt(i) - '0') * 2 + carry;
            buf.setCharAt(i, (char) ('0' + digit % 10));
            carry = digit / 10;
        }
        if (carry > 0) {
            start--;
            if (start <p>此版本避免创建中间字符串,显著降低 GC 压力,适合大规模批量校验。</p><h3>? 注意事项与边界处理</h3>
  • ✅ 必须处理前导零:"0001"、"0" 等非法/边缘输入;
  • ✅ 显式排除 "0":0 不是任何正整数幂(2ⁿ > 0, ∀n∈ℕ);
  • ✅ 快速特判 "1":对应 2⁰,避免空循环;
  • ⚠️ 不可依赖 Integer.parseInt() 或 Long.parseLong():题目明确输入可超 64 位,强制字符串处理;
  • ? 备选方案(预计算查表):若输入长度 ≤ 21,共仅 67 个合法 2 的幂(2⁰ 到 2⁶⁶),可静态初始化 Set 存储全部,实现 O(1) 查询:
private static final Set<string> POWERS_OF_TWO = Set.of(
    "1", "2", "4", "8", "16", "32", "64", "128", /* ... up to "73786976294838206464" */
);
// then: return POWERS_OF_TWO.contains(s.replaceAll("^0+", ""));</string>

该方案极致简洁,适用于测试数据固定、内存充裕的场景。

综上,字符串倍增法兼具正确性、可读性与工程实用性,是解决超大数 2 的幂判定问题的标准范式。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

10797

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

7902

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

6872

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1164

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

948

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1396

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2849

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20131

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1255

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.8万人学习