UVa在线判断#458超出时限

时间:2014-06-27 15:15:19

标签: java performance algorithm

我正在尝试解决UVa problem 458 - decoder并且我想出了以下算法,该算法为我提供了样本输入数据的正确输出,但运行时间比允许的长。

    public class Decoder {

    public void decoder() {
        Scanner sc = new Scanner(System.in);

        while (sc.hasNext()) {

            String line = sc.nextLine();

            for (int i = 0; i < line.length(); i++) {

                if(line.charAt(i)>=32 && line.charAt(i)<=126)
                System.out.print((char) (line.charAt(i) - 7));

            }
            System.out.println();
        }
    }

}

我所研究的内容

我已经阅读了forums并且大多数解决方案非常相似,我一直在研究是否有办法避免 for 循环正在通过字符串运行打印出新的char。但是这个循环是不可避免的,这个算法的时间复杂度总是n ^ 2。

问题还提到只更改ASCII可打印值,这就是为什么我设置条件来检查它是否大于或等于32和126.根据Wikipedia这是可打印值的范围。< / p>

http://ideone.com/XkByW9

2 个答案:

答案 0 :(得分:4)

  1. 避免将流解码为字符。如果您只需要支持ASCII,则可以使用字节。

  2. 以大块读取和写入数据,以避免功能/系统调用开销。

  3. 避免不必要的分配。目前,您正在为每一行分配新的字符串。

  4. 请勿将输入拆分为多行以避免非常小的行显示性能不佳。

  5. 示例:

    public static void main(String[] args) throws IOException {
        byte[] buffer = new byte[2048];
        while (true) {
            int len = System.in.read(buffer);
            if (len <= 0) {
                break;
            }
            for (int i = 0; i < len; i++) {
                ...
            }
            System.out.write(buffer, 0, len);
        }
    }
    

    它将像处理二进制文件一样处理输入。对于每次迭代,它将最多2048个字节读入缓冲区,处理它们并将它们写入标准输出。当达到EOF并且read返回-1时,程序将结束。 2048通常是一个很好的缓冲区大小,但你可能想尝试不同的大小,看看哪个最好。

答案 1 :(得分:1)

永远不要将Scanner用于长输入。扫描程序比其他读取Java输入的方式慢得令人难以置信,例如BufferedReader。这个UVa问题看起来像一个有很长输入的问题。