【原创】40亿个数字,找出其中出现过两次的字符

问题:有一个连续文件,其中保存了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+="\r\n";
   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 += "\r\n";
                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";
    }
}

 

 

 

 

posted on 2013-12-27 17:00  迷途@书童  阅读(584)  评论(0编辑  收藏  举报

导航