You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rabin Karp算法Java代码报错:double转int可能丢失精度,求解决

解决Rabin-Karp实现中的"possible lossy conversion from double to int"错误

错误根源很明确:Math.pow()返回的是double类型,你直接把它赋值给int变量(比如while循环里的int p= Math.pow(10,n);)或者参与整数运算时,Java会因为double转int可能丢失精度而报错。而且用浮点运算计算哈希值本身就不靠谱,容易出现精度偏差,导致哈希匹配错误。

修复方案:用整数运算替代Math.pow

既然要计算的是10的整数次幂,完全可以用整数循环相乘实现,避免浮点类型的引入。

修改后的完整代码:

import java.util.Scanner;

public class Main {
    static boolean rabinKarp(String text, String pattern) {
        int pLength = pattern.length();
        int textLength = text.length();
        
        // 处理模式串比文本长的边界情况
        if (pLength > textLength) {
            return false;
        }
        
        int res = 0, curr = 0;
        int power = 1;
        
        // 计算10^(pLength-1)的整数幂
        for (int j = 1; j < pLength; j++) {
            power *= 10;
        }
        
        // 计算模式串的哈希值res,以及文本前pLength个字符的哈希值curr
        for (int i = 0; i < pLength; i++) {
            res += (pattern.charAt(i) - 'a' + 1) * power;
            curr += (text.charAt(i) - 'a' + 1) * power;
            if (power > 1) {
                power /= 10;
            }
        }
        
        if (res == curr) {
            return true;
        }
        
        // 重新计算最高次幂,用于滑动窗口更新哈希
        power = 1;
        for (int j = 1; j < pLength; j++) {
            power *= 10;
        }
        
        int i = pLength;
        while (i < textLength) {
            // 滑动窗口更新哈希:移除左边字符的贡献,加入右边新字符的贡献
            curr = (curr - (text.charAt(i - pLength) - 'a' + 1) * power) * 10 + (text.charAt(i) - 'a' + 1);
            if (res == curr) {
                return true;
            }
            i++;
        }
        return false;    
    }
    
   public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String text = "abcbab";
        String pattern = "bab";
        System.out.println(rabinKarp(text, pattern));
    }
}

关键修改点:

  • 提前用整数循环计算10的幂次power,完全替代Math.pow(),避免浮点类型转换
  • 滑动窗口的哈希更新逻辑保持整数运算,确保精度和正确性
  • 增加了模式串长度大于文本长度的边界判断,避免数组越界

另外,如果你非要用Math.pow(不推荐),可以显式强制转换,但要注意当幂次较大时,double的精度不足以准确表示整数,会导致哈希值错误。比如把int p= Math.pow(10,n);改成int p= (int)Math.pow(10,n);,但这种方法只适合短模式串,长串会出问题,所以还是优先用整数运算的方案。

内容的提问来源于stack exchange,提问作者Coding Enthusiast

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 21:45:29