简单排序(java)

package test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
//import java.util.Scanner;
/**
 * Notice:
 * <BR> 1. 仅限使用以下package:
 *        java.lang.*, java.io.*, java.math.*, java.text.*, java.util.*
 * <BR> 2. 请勿变更 package名,类名,test()定义。 
 *
 */
public class ProgramTest {
    /**
     * 请在此方法内完成代码,但可以增加自己的私有方法。
     * 数据文件inputFile的内容格式为一行一条数据,每条数据有2个字段用逗号分隔,第1个字段为排序用的Key,第二个字段为value。
     * 换行符为'\n'。
     * 数据内容举例如下:
     * abe,xmflsflmfmlsmfs
     * abc,xmlmxlkmffhf
     * 8fj3l,xxjfluu313ooo11
     * 
     * 注意点: 1.本次的测试数据内容都是ASCII字符,无中文汉字.所以不必考虑encoding。
     *        2.本次的测试数据中,key的最大长度8,value的最大长度32。
     * 

     * 排序以key的升序,使用String.compareTo()来比较key的大小。最后排序完成的数据写入outputFile。
     * @param inputFile 输入文件
     * @param outputFile 输出文件
     * @param tempFile 临时文件。处理的数据量大的时候,可能会需要用到临时文件。
     * @throws Exception
     */
    
    public static void test(File inputFile, File outputFile, File tempFile) throws Exception {
        //TODO ====================== YOUR CODE HERE ======================
        ProgramTest pt = new ProgramTest();
        List<Item> l = new ArrayList<Item>();
        
        //读输入文件
        //Scanner sc = new Scanner(inputFile);
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(inputFile));
            String str = null;
            // 一次读入一行,直到读入null为文件结束
            while ((str = reader.readLine()) != null) 
                l.add(pt.new Item(str.split(",")));
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }
//        
//        while(sc.hasNext())
//            l.add(pt.new Item(sc.next().split(",")));    
//        sc.close();
//        
        pt.items = l.toArray(new Item[l.size()]);
        
        //归并排序
        pt.mergeSort(0, l.size());
        
        //输出文件
        FileOutputStream out = new FileOutputStream(outputFile);
//        pt.print("");
        for(Item item : pt.items)
            out.write(item.toByte());
        out.close();
        
//        pt.print("排序前:");
//        pt.mergeSort(0, l.size());
//        pt.print("排序后:");
    }
        
    //TODO ====================== YOUR CODE HERE (You can add private method if need) ======================
    /**
     * 打印内存值
     * @param str 提示信息
     */
    private void print(String str){
        System.out.println(str);
        for(Item item : items)
            System.out.println(item.getKey() + "," + item.getValue());
    }
    
    /**
     * 存储每行数据的数据结构
     * @author kdping
     *
     */
    private class Item{
        private String key;
        private String value;
        Item(String[] arr){
            key = arr[0];    value = arr[1];
        }
        public String getValue() {
            return value;
        }
        public void setValue(String value) {
            this.value = value;
        }
        public String getKey() {
            return key;
        }
        public void setKey(String key) {
            this.key = key;
        }
        public int compareTo(Item item){
            return this.key.compareTo(item.key);
        }
        public byte[] toByte(){
            return (key+","+value).getBytes(); 
        }
    }
    
    private Item[] items;
    
    /**
     * 归并两个有序序列,items[start,mid),items[mid,end)
     * @param start  
     * @param end   
     */
    private void merge(int start, int end){
        int n = end - start;    int mid = (n >> 1) + start;
        int k1 = start, k2 = mid, i = 0;
        Item[] titems = new Item[n + 1];
        while(k1<mid && k2<end){
            if(items[k1].compareTo(items[k2]) < 0)
                titems[i++] = items[k1++];    
            else titems[i++] = items[k2++];
        }
        while(k1 < mid) titems[i++] = items[k1++];
        while(k2 < end) titems[i++] = items[k2++];
        for(i = 0; i < n; i++) items[start++] = titems[i];
    }
    /**
     * 对items(start,end]进行归并排序
     * @param start
     * @param end
     */
    private void mergeSort(int start, int end){
        int n = end - start;
        int mid = (n >> 1) + start;
        if(n < 2) return;
        mergeSort(start, mid);
        mergeSort(mid, end);
        merge(start, end);
    }
    
    
    /** 
     * 测试函数
     * @param args
     */
//    public static void main(String[] args) {
//        // TODO Auto-generated method stub
//        File inputFile = new File("D:\\Download\\javatest\\javatest\\data\\in.txt");
//        File outputFile = new File("D:\\Download\\javatest\\javatest\\data\\out.txt");
//        File tmpFile = new File("D:\\Download\\javatest\\javatest\\data\\itdm.txt");
//        try {
//            
//            test(inputFile, outputFile, tmpFile);
//        } catch (Exception e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }
//    }
    
    //=================================================================

}
...

一道面试题:http://zhaopin.e-pointchina.com/zhaopintest/techtest_test_java.html?testId=zhaopin_java&qSetId=zhaopin_java_sort&qId=zhaopin_java_sort1

题目见代码,原来用Scanner类似乎会报访问权限不足。

结果超时,50万的数据,应该是时间花在磁盘IO上的原因。

posted @ 2016-09-05 22:59  Ramanujan  阅读(344)  评论(0编辑  收藏  举报