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