CCF20190904-4推荐系统Java实现的IO优化

2019-12-12  本文已影响0人  华雨欣

最近在准备CCF,做到这道题的时候半天看不懂题,没办法去学习了大佬的思路(CSDN日沉云起),自己按照他给的思路自己用Java实现了一个,上传之后结果超时60分,实在想不出怎么优化,在论坛找到了一个输入输出加速优化的方法,特记录下来。

这是优化原地址。https://bbs.csdn.net/topics/395020645


IO优化

// 输出优化
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

这一步主要是输出优化,加快输出的速度,不过在过程中调用 out.print() 并不会输出,而是写到缓冲区,须要在全部完成刷新缓冲区,便会将所有数据输出出来。

out.flush();

接下来是输入优化,在主类中嵌入一个输入器 InputReader 类,主要使用BufferReader逐行读取数据,并实现 nextInt() 等方法,其中Buffer读到的整行字符串用StringTokenizer类对象来存储,方便于分割。整个过程相当于将原有的输入类进行再封装,实现一个自己的输入器,代码如下:

static class InputReader {

    private static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    private static StringTokenizer tokenizer = null;

    static String next() {

        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return tokenizer.nextToken();
    }

    static int nextInt() {
        return Integer.parseInt(next());
    }

    static long nextLong() {
        return Long.parseLong(next());
    }
}

通过这两个IO优化之后原本运行超时(超过5s),直接100分3s左右通过了,由衷感谢两位大佬。

完整代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeSet;
import java.util.Vector;
//ccf测试题

class Commodity implements Comparable<Commodity> {
    long id;// 编号
    long score;// 分数

    public Commodity(long id, long score) {
        // TODO Auto-generated constructor stub
        this.id = id;
        this.score = score;
    }

    @Override
    public int compareTo(Commodity o) {
        // TODO Auto-generated method stub
        if (this.score != o.score) {
            if (this.score < o.score) {
                return 1;
            } else {
                return -1;
            }
        } else {
            if (this.id < o.id) {
                return -1;
            } else if (this.id == o.id) {
                return 0;
            } else {
                return 1;
            }
        }
    }

}

public class Main {
    // 输出优化
    static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) {

        final long mul = (long) 1e9;
        int m = InputReader.nextInt(), n = InputReader.nextInt();
        TreeSet<Commodity> set = new TreeSet<Commodity>();
        HashMap<Long, Commodity> map = new HashMap();// 通过id找到对应id的类对象

        for (int i = 0; i < n; i++) {
            long id = InputReader.nextInt();
            long score = InputReader.nextInt();
            for (int j = 0; j < m; j++) {
                long a = j * mul + id;
                Commodity temp = new Commodity(a, score);
                set.add(temp);
                map.put(a, temp);
            }
        }
        int opNum = InputReader.nextInt();// 操作数目
        for (int i = 0; i < opNum; i++) {
            int num = InputReader.nextInt();// 符号
            if (num == 1) {// 添加商品
                int type = InputReader.nextInt();// type类商品
                long id = InputReader.nextLong();
                long score = InputReader.nextLong();
                long a = type * mul + id;
                Commodity temp = new Commodity(a, score);
                set.add(temp);
                map.put(a, temp);

            } else if (num == 2) {// 删除商品
                int type = InputReader.nextInt();// type类商品
                long id = InputReader.nextLong();
                long a = type * mul + id;
                set.remove(map.get(a));
                map.remove(a);
            } else if (num == 3) {// 挑选商品
                Vector<Integer> k = new Vector<Integer>();
                int K = InputReader.nextInt();
                for (int j = 0; j < m; j++) {// 存储k_i的值
                    k.add(InputReader.nextInt());
                }
                Vector<Long>[] ans = new Vector[m];
                // 遍历set集合
                for (int index = 0; index < m; index++) {
                    ans[index] = new Vector<Long>();
                }
                for (Commodity a : set) {
                    int type = (int) (a.id / mul);
                    long com = a.id % mul;
                    if (k.get(type) == 0) {
                        continue;
                    }
                    ans[type].add(com);
                    k.set(type, k.get(type) - 1);
                    K--;
                    if (K == 0)
                        break;
                }

                // 输出
                for (int j = 0; j < m; j++) {
                    if (ans[j].size() == 0) {
                        out.print(-1);
                    } else {
                        for (int z = 0; z < ans[j].size(); z++) {
                            out.print(ans[j].get(z) + " ");
                        }
                    }
                    out.print('\n');
                }

            } else {
                System.out.println("输入有误!非法操作!");
                System.exit(1);
            }
        }
        // 全部计算结束后刷新缓冲区来输出数据
        out.flush();
        out.close();
    }

    // 输入优化
    static class InputReader {
        private static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        private static StringTokenizer tokenizer = null;

        static String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return tokenizer.nextToken();
        }

        static int nextInt() {
            return Integer.parseInt(next());
        }

        static long nextLong() {
            return Long.parseLong(next());
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读