【发布时间】:2013-05-19 20:42:47
【问题描述】:
我正在尝试解决来自 SPOJ 的问题。但对我来说问题不是算法的实际难度;这是我的 Java 代码的性能,因为它通常会导致超出时间限制的错误。
我听说 Java 在竞赛问题上的表现比 C/C++ 慢而臭名昭著;但是,我现在唯一可以编写的语言是 Java。因此,我正在寻求建议,以使我的代码更整洁、更快。以下是我的解决方案和源问题。
public class NextPalindrome {
public static BigInteger secondHalf(BigInteger b) {
String s = b.toString();
int n = s.length();
if(n==1){
return b;
}
String end = s.substring((n + 1) / 2, n);
BigInteger End = new BigInteger(end);
return End;
}
public static BigInteger reverse(BigInteger b) {
String s = b.toString();
int n = s.length();
String beg = b.toString();
String reversebeg = "";
while (true) {
for (int i = n - 1; i >= 0; i--) {
reversebeg = reversebeg + beg.charAt(i);
}
break;
}
BigInteger reverse = new BigInteger(reversebeg);
return reverse;
}
public static BigInteger firstHalf(BigInteger b) {
String s = b.toString();
int n = s.length();
if(n==1){
return b;
}
String beg = s.substring(0, n / 2);
BigInteger Beg = new BigInteger(beg);
return Beg;
}
public static BigInteger nextPalindrom(BigInteger b) {
String s = b.toString();
int n = s.length();
if(n==1){
if(b.equals(9)){
return BigInteger.valueOf(11);
} else {
return b.add(BigInteger.valueOf(1));
}
}
if (n % 2 == 1&&n>1) {
Character c = s.charAt(n / 2);
String C = c.toString();
BigInteger med = new BigInteger(C);
BigInteger beg = firstHalf(b);
BigInteger end = secondHalf(b);
if (reverse(beg).compareTo(end) <= 0) {
beg.add(BigInteger.valueOf(1));
if (med.compareTo(BigInteger.valueOf(9)) == 0) {
c = '0';
} else {
med = med.add(BigInteger.valueOf(1));
}
}
String temp = beg.toString();
String temp1 = reverse(beg).toString();
C = med.toString();
String result = temp + C;
result = result.concat(temp1);
BigInteger B = new BigInteger(result);
return B;
}
BigInteger beg = firstHalf(b);
BigInteger end = secondHalf(b);
if (reverse(beg).compareTo(end) <= 0) {
beg = beg.add(BigInteger.valueOf(1));
}
String temp = beg.toString();
String temp1 = reverse(beg).toString();
String result = temp.concat(temp1);
BigInteger B = new BigInteger(result);
return B;
}
public static void main(String[] args)throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String s = in.readLine();
int N = Integer.parseInt(s);
for (int i = 0; i < N; i++) {
BigInteger big = new BigInteger(in.readLine());
BigInteger palindrom = nextPalindrom(big);
System.out.println(palindrom);
}
}
}
【问题讨论】:
-
你的问题更符合这个网站的概念:codereview.stackexchange.com
-
我会先不把数字变成字符串。
-
@Blender 我没有把字符串变成数字。
-
我不确定从
String到BigInteger的转换有多复杂,但BigInteger.toString()是O(digits²)。最多有1000000数字,这是令人望而却步的。你需要的是一个数字数组。这些可以方便地成为chars。然后使用char[]。回文不是算术属性,而是数字序列(即字符串表示)的属性。变大很容易转化为数字序列的条件。 -
感谢您的建议。我不得不使用 BigInteger,因为有些数字的长度可以是 1000000 位。现在我明白了如何使用 char[] 数组来做到这一点。
标签: java performance palindrome