所以我正在做这个练习,只使用String类找到下一个回文。
我有点解决了,但对某事有疑问。
当我输入像123456789这样的字符串时,我得到一个java.lang.StackOverflowError。 当我输入更大的字符串,如9999999999999999999时,我不会得到错误。 我在这个网站做了一些研究,我认为它与我使用的递归回文方法有关。
有什么方法可以改进我的代码,以便处理更大的数字?为什么123456789会出错并且9999999999999999999不会?后者更大。
import java.io.*;
public class mainclass {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(isr);
System.out.println(palindroom(in.readLine()));
}
public static String increment(String str){
String incre="";
if(str.equals("9")){incre = "10";}
else{
switch(str.charAt(str.length()-1)){
case '0': incre = str.substring(0, str.length()-1)+"1";break;
case '1': incre = str.substring(0, str.length()-1)+"2";break;
case '2': incre = str.substring(0, str.length()-1)+"3";break;
case '3': incre = str.substring(0, str.length()-1)+"4";break;
case '4': incre = str.substring(0, str.length()-1)+"5";break;
case '5': incre = str.substring(0, str.length()-1)+"6";break;
case '6': incre = str.substring(0, str.length()-1)+"7";break;
case '7': incre = str.substring(0, str.length()-1)+"8";break;
case '8': incre = str.substring(0, str.length()-1)+"9";break;
case '9': incre = increment(str.substring(0, str.length()-1))+"0";break;
};
}
return incre;
}
public static String palindroom(String str){
String palin=increment(str);
boolean isPalindroom=true;
for(int i=0;i<palin.length();i++){
if(palin.charAt(i)==palin.charAt(palin.length()-i-1)){}
else{isPalindroom=false;}
}
if(isPalindroom){return palin;}
else{return palindroom(increment(str));}
}
}
答案 0 :(得分:4)
因为只有在输入的值不是回文值时递归,并且需要超过10,000次递归才能将123456789递增到回文中。
你的代码有点奇怪,你拿一个字符串,你假设它是一个数字,并使用字符串操作递增它。转换为long(如果Long不够大,则转换为BigInteger)会更简单。
此外,您似乎增加了两次,一次是palindroom
方法的开头,另一次是else
块。
<强>更新强> 从你的评论中,我认为你可能不清楚Stack Overflow Error是什么。因此java调用堆栈是方法的堆栈(即LIFO)。在你的情况下,你的调用栈将是main,palindroom,palindroom,palindroom,palindroom,palindroom等...请注意java只允许调用堆栈的最大大小,如果超过此大小,则会出现堆栈溢出异常。 Java stack overflow error - how to increase the stack size in Eclipse?有一些关于默认值和配置的详细信息。
答案 1 :(得分:0)
我知道你对如何用循环替换你的递归方法有疑问,我已经编写了这个用于练习,所以你可以检查出来:
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(isr);
String numString = in.readLine();
BigInteger num = new BigInteger(numString);
do {
num = num.add(new BigInteger("1"));
} while(pal(num));
System.out.println(num);
}
public static boolean pal(BigInteger num){
String isPal = num.toString();
boolean isPalindroom=false;
for(int ii=0; ii<isPal.length(); ii++){
if(isPal.charAt(ii) != isPal.charAt(isPal.length()-ii-1))
isPalindroom = true;
}
return isPalindroom;
}
答案 2 :(得分:0)
仅作为函数的最后一步发生的递归 - 所谓的“尾递归” - 通常是伪装的循环;你只是用一组新参数重复函数的主体。一个好的优化器通常会将尾递归重写为循环;显然Java并不在你的情况下。
此示例的简单迭代重写示例:
public static String palindroom(String str){
while(true)
{
String palin=increment(str);
boolean isPalindroom=true;
for(int i=0;i<palin.length();i++){
if(palin.charAt(i)==palin.charAt(palin.length()-i-1)){}
else{isPalindroom=false;}
}
if(isPalindroom){return palin;}
else{str=palin;} //increment str, and try again
}
}
这不会解决您的逻辑问题 - 请参阅其他响应 - 但它完全在单个堆栈框架内运行。