数字魔法的加一操作 | 豆包MarsCode AI刷题

173 阅读4分钟

思路: 一开始我是用int来接收这个结果,并根据【算法基础】大数取余的三种方法-CSDN博客中提到的a*b%c=(a%c)*(b%c)的规律,在每次循环时对齐取余确保不超出int的范围,但是后来发现它是对结果取余,因为这道题的计算是每个数都各自加一和进位,所以过程取余和结果取余是不一样的。所以我们只能用binginteger和stringbulider来进行处理:

import java.math.BigInteger;

public class 数字魔法的加一操作 {
    public static int solution(int n, int k, String num_str) {

        StringBuilder sb, reverse_num;
        BigInteger mid = null;
        String str=num_str;
        for (int i = 0; i <k ; i++) {
            mid= BigInteger.valueOf(0);
            //拿到字符串先反转
            sb=new StringBuilder(str).reverse();
            reverse_num=new StringBuilder();
            //进位操作
            for (int j = 0; j < sb.length(); j++) {
                if(sb.charAt(j)!='9'){
                    char ch=(char)(sb.charAt(j)+1);
                    reverse_num.append(ch);
                }else{
                    reverse_num.append("01");
                }
            }
            //进位后的字符串
            str=reverse_num.reverse().toString();
            //解析成数字,会超过int,所以用long
            /*mid=Integer.parseInt(str);
            *//*for (int j = 0; j < str.length(); j++) {
                mid=mid*10+(int)(str.charAt(j)-48);
            }*//*
            //求余
            mid%=1000000007;

            System.out.println(mid);
            //再转换成字符串
            reverse_num=new StringBuilder(String.valueOf(mid));
            str=reverse_num.toString();*/

            // 解析成数字,用 BigInteger
            mid = new BigInteger(str);


            System.out.println(mid);
            // 再转换成字符串
            reverse_num = new StringBuilder(mid.toString());
            str = reverse_num.toString();

        }

        // 求余
        mid = mid.mod(BigInteger.valueOf(1000000007));
        System.out.println(mid);
        return mid.intValue();
    }

    public static void main(String[] args) {
        // You can add more test cases here
        //System.out.println(solution(3, 1, "798") == 8109);
        //System.out.println(solution(3, 3, "798") == 103221);
        System.out.println(solution(7,8,"7878978")==576416214);
    }
}
//TODO:其实我的解法没错,是这道题的结果是对最终的字符串数字取模,和正常计算不一样不能运用数学定理,在计算的过程中取模会导致结果字符串不同!

以下是具体步骤描述:

  1. 初始化对象:首先,代码初始化了两个StringBuilder对象sbreverse_num,用于字符串的反转和构建新的字符串。同时,还初始化了一个BigInteger对象mid,用于处理可能超过int范围的大数。
  2. 循环加一操作:代码进入一个循环,该循环将执行k次。在每次循环中,执行以下操作:
    • 字符串反转:将输入的字符串num_str反转,以便从最低位开始处理加一操作。
    • 字符判断与进位:遍历反转后的字符串中的每个字符,如果字符不是'9',则将其ASCII码值加一,然后转换为字符并追加到reverse_num中。如果字符是'9',则追加"01"到reverse_num中,以实现进位。
    • 再次反转字符串:将处理后的字符串再次反转,得到进位后的正确顺序字符串。
  3. 大数处理:由于进位后的字符串可能表示一个非常大的数字,超出了int类型的范围,因此使用BigInteger来解析这个字符串。
  4. 打印中间结果:在每次循环结束后,打印当前的中间结果mid,以便跟踪程序的执行过程。
  5. 字符串转换:将BigInteger对象mid转换回字符串,以便在下一次循环中继续进行加一操作。
  6. 最终模运算:在所有循环结束后,对最终的mid进行模运算,使用BigInteger.valueOf(1000000007)作为模数,这是为了避免结果过大,同时也是题目要求的操作。
  7. 打印并返回结果:打印最终结果,并将mid转换为int类型返回。这里假设最终结果在int范围内,但在实际应用中可能需要根据具体情况调整。
  8. 测试用例:在main方法中,提供了几个测试用例来验证solution方法的结果。这些测试用例帮助确保代码的正确性。
  9. 注意事项:代码的注释指出,由于题目要求对最终的字符串数字取模,因此在计算过程中不能简单地在每一步都进行取模运算,因为这会导致最终的结果字符串与预期不同。这一点是解题的关键,也是实现时需要注意的细节。