04-排序【选择排序】算法学习 【按照时间顺序合并20个1G的日志文件】

 

04-排序【选择排序】算法学习

 

  • 思想:每次从数组中选取最小的元素,依次加入新数组中。
  • 操作:比较
  • 是否稳定排序:
     
  • 是否原地排序:
     
  • 时间复杂度:O(n²)
     
  • 最好时间复杂度:O(n²)
     
  • 最坏时间复杂度:O(n²)
     
  • 平均时间复杂度:O(n²)
     
  • 空间复杂度:O(1)

 

       总结:选择排序顾名思义,每次遍历选择一个最小的元素,思想非常简单。

 

      实现代码略

 

      场景:对30个日志文件,每个文件大小约1G,均是按照时间戳大小顺序排列,现机器内存为2G,如何快速将这些日志文件合并为一个日志文件,并要求合并后的日志文件也是按照时间戳大小排序。

      实现代码(java)含义解释如下:

  1. 
    
    resume(String initDate, int fileCount)方法:用于生成所需的30个日志文件
  2. 
    
    readFile(List<File> fileList)方法:合并日志文件。
  3. 思想:为每个日志文件建立一个引用(指针),按照归并排序的思想读取一条最小的元素,写入合并文件中。
  4. 注意:耗时较长,为了演示,可以修改示例代码日志大小为1M,文件数为30。
package com.cheng2839.test.$sa;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description
 * @Author cheng2839
 * @Date
 * @Version v1.0
 */
public class FileHandleDemo {

    public static final String DIR_FILE = "E:\\0test\\";
    public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    public static final long RAND_MAX = 60 * 1000;

  //生成fileCount个日志文件(每个日志文件为1G),起始日期为:initDate(如:2020-01-01 00:00:00.000)
public static void resume(String initDate, int fileCount) throws ParseException, IOException { while (fileCount > 0) { File file = new File(DIR_FILE, fileCount + ".log"); if (!file.exists()) { file.createNewFile(); } BufferedWriter bw = new BufferedWriter(new FileWriter(file)); long initDateLong = sdf.parse(initDate).getTime(); while (file.length() < 1024 * 1024 * 1024) { initDateLong += (long) (Math.random() * RAND_MAX); bw.write(sdf.format(initDateLong)); bw.newLine(); } bw.flush(); bw.close(); fileCount--; } } public static void main(String[] args) { try { int fileCount = 30; //resume("2020-01-01 00:00:00.000", fileCount); List<File> fileList = new ArrayList<>(); for (int i = 1; i <= fileCount; i++) { fileList.add(new File(DIR_FILE, i + ".log")); } readFile(fileList); } catch (Exception e) { e.printStackTrace(); } }   //按照时间戳(如:2020-01-01 00:00:00.000),将日志文件列表进行合并 public static void readFile(List<File> fileList) throws Exception { BufferedWriter writer = new BufferedWriter(new FileWriter(new File(fileList.get(0).getParent(), "result.log"))); Map<BufferedReader, String> readerMap = new HashMap(); for (File file : fileList) { BufferedReader reader = new BufferedReader(new FileReader(file)); readerMap.put(reader, reader.readLine()); } String line; while ((line = getLine(readerMap)) != null) { writer.write(line); writer.newLine(); } writer.flush(); writer.close(); for (BufferedReader reader : readerMap.keySet()) { reader.close(); } }   //从文件指针集合中,读取一个最小的时间戳日志行 public static String getLine(Map<BufferedReader, String> readerMap) throws Exception { String insertLine = null; BufferedReader insertReader = null; for (BufferedReader br : readerMap.keySet()) { String tmpLine = readerMap.get(br); if (tmpLine == null) continue; if (insertLine == null) { insertLine = tmpLine; insertReader = br; } if (sdf.parse(insertLine).getTime() > sdf.parse(tmpLine).getTime()) { insertLine = tmpLine; insertReader = br; } } if (insertLine != null && insertReader != null) { readerMap.put(insertReader, insertReader.readLine()); } return insertLine; } }

 

posted @ 2021-03-10 15:51  温柔的星空,让你感动  阅读(244)  评论(0编辑  收藏  举报