问题:有一个连续文件,其中保存了40亿个数字,其中有重复的数字,要求在不到1MB内存空间的前提下,寻找出现两次以上的数字。
原理:
将这些数字读出来取其二进制编码,如:
0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100
遍历这些串,首先取第一位,如果是0,存入文件1,如果是1,存入文件2;然后以文件1为输入,取第二位,判断第二位的数字再次进行分类。这样递归分析完所有的文件,重复的数字会被归并到一个文件中,单独出现的数字会保存到一个单独的文件中。
以下是java代码实现,以16位长度为例:
先制造数据:
import java.io.IOException; public class ProduceNumber { private static int LENGZTH=16; /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { for (int i = 0; i <= 65535; i++) { String s = Integer.toBinaryString(i); int l = s.length(); if (s.length() < LENGZTH) { for (int j = 0; j < LENGZTH - l; j++) { s = "0" + s; } } s+=" "; if (i % 500 == 0) { for (int j = 0; j < 3; j++) { PhoneNumber.toFile("d:\data\2.txt", s); } }else{ PhoneNumber.toFile("d:\data\2.txt", s); } } // PhoneNumber.toFile("", ""); } }
进行处理:
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.Stack; public class Split { private static int LENGZTH = 16; private static Stack stack; public static void main(String[] args) throws Exception { split("d:\data\2.txt", 0); } public static void split(String file, int i) throws Exception { if (i >= LENGZTH) { File f = new File(file); // System.out.println(f.length()); if (f.length() == 18) { f.delete(); } return; } String file1 = "d:\data\" + "A_" + getFileName(); Thread.sleep(10); String file2 = "d:\data\" + "B_" + getFileName(); BufferedReader reader = new BufferedReader(new FileReader(file)); String line = reader.readLine(); int add = 0; while (line != null) { add++; if (i < LENGZTH) { char c = line.charAt(i); line += " "; if (c == '0') { PhoneNumber.toFile(file1, line); } else { PhoneNumber.toFile(file2, line); } line = reader.readLine(); } } reader.close(); delete(file); // System.out.println(add); if (add == 1) { return; } split(file1, i + 1); split(file2, i + 1); } private static void delete(String file) { File f = new File(file); f.delete(); } private static String getFileName() { return System.currentTimeMillis() + ".txt"; } }