【问题标题】:Need to fasten my Java code需要固定我的 Java 代码
【发布时间】: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 我没有把字符串变成数字。
  • 我不确定从StringBigInteger 的转换有多复杂,但BigInteger.toString()O(digits²)。最多有1000000 数字,这是令人望而却步的。你需要的是一个数字数组。这些可以方便地成为chars。然后使用char[]。回文不是算术属性,而是数字序列(即字符串表示)的属性。变大很容易转化为数字序列的条件。
  • 感谢您的建议。我不得不使用 BigInteger,因为有些数字的长度可以是 1000000 位。现在我明白了如何使用 char[] 数组来做到这一点。

标签: java performance palindrome


【解决方案1】:

BigInteger 用于精确计算,但速度较慢。 int 或 long 在这里会更好。

还有很多与 String 之间的转换,也很慢。

还有一些缓慢的字符串操作...

所以我建议使用 int 或 long 以及 Integer 或 Long 的静态辅助方法 来操纵数字的原始位。

这应该会使您的程序发挥最佳性能。

【讨论】:

  • 数字最多可以有1000000 位数,不适用于long
【解决方案2】:

如果不评论您的代码(其他人已解决),您不应该相信您听到的关于 Java 性能缓慢的所有消息。您必须非常努力地想出一种算法来解决竞争问题,该算法将在 C++ 的时间限制下运行,但在 Java 中则不行。导致速度缓慢的是您选择的算法,而不是 Java。

【讨论】:

  • 我会记住这一点。如果我对我只是模糊地意识到的问题一无所知,我深表歉意。
猜你喜欢
  • 2011-07-24
  • 1970-01-01
  • 2015-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多