企业可以做哪些网站有哪些内容吗,提交网站入口,提供北京国互网网站建设,小型网站设计及建设论文范本一、任务名#xff1a;
开发最小目录工具
二、任务描述
开发工具#xff0c;从桶清单文件中列举出所有最小目录#xff0c;并列举出每一个最小目录中包含的文件总数与文件总量。 最小目录的解释#xff1a;
有以下几个目录
a/b/1.txt
a/b/2/txt
a/3.txt
a/b/c/
则…一、任务名
开发最小目录工具
二、任务描述
开发工具从桶清单文件中列举出所有最小目录并列举出每一个最小目录中包含的文件总数与文件总量。 最小目录的解释
有以下几个目录
a/b/1.txt
a/b/2/txt
a/3.txt
a/b/c/
则最小目录有
a/b
a/
最小目录包含的对象数为
a/b2
a/:1三、开发思路
这个工作实际上属于目录解析的范畴与目录解析相关的问题可以通过前缀树来解决
1前缀树节点开发
有树要先有节点每一级目录可以视为一个节点。 这个节点包含接下来要去往的目录节点而这种目录节点可能有很多个我们必须能快速通过目录名来查找节点因此选则HashMap将目录名作为Key目录节点作为value,nextsHashMapKey,Node。 又因为每一个目录节点均有可能称为最小目录那么我们遍历节点的时候应该能够拿出节点中的文件数和文件总大小故这两个属性也要设置 最后你不能只知道下面的名字而不知道自己的名字所以每个节点也应该有自己的Name 因此Node的构建为PrefixTreeNode
import java.util.HashMap;/*** author sq* date 2023/8/28* Description ${}*/
public class PrefixTreeNode {String Name;//该节点名称long file_num 0l;//该节点叶子结点个数long file_size 0l;//该节点叶子接地点总大小HashMapString, PrefixTreeNode nexts null; //该节点的子节点列表public PrefixTreeNode() {}public String getName() {return Name;}public void setName(String name) {Name name;}public long getFile_num() {return file_num;}public void setFile_num(long file_num) {this.file_num file_num;}public long getFile_size() {return file_size;}public void setFile_size(long file_size) {this.file_size file_size;}public HashMapString, PrefixTreeNode getNexts() {return nexts;}public void setNexts(HashMapString, PrefixTreeNode nexts) {this.nexts nexts;}public PrefixTreeNode(String name, HashMapString, PrefixTreeNode nexts) {Name name;this.nexts nexts;}
}
2前缀树开发
前缀树其实只需要有一个节点然后写出构建函数和遍历函数基本上就可以使用了 ①前缀树的构建是将输入的目录字符串通过/进行分解得到字符串数组。 在分解之前就可以判断一下是不是最小目录如果最后不是以/结尾那么到文件所在的目录就是最小目录。文件不用加入前缀树。
②前缀树的遍历就是树的正常遍历用DFS(Depth First Search)比较容易做遍历每一个节点如果有文件数和文件大小就输出没有就去下一层直到没有下一层
前缀树的代码如下所示
/*** author sq* date 2023/8/28* Description ${}*/import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;public class PrefixTree {PrefixTreeNode root null;long sum_num 0l;long sum_size 0l;//构建前缀树public PrefixTree() {}public PrefixTree(PrefixTreeNode root) {this.root root;}public PrefixTreeNode getRoot() {return root;}public void setRoot(PrefixTreeNode root) {this.root root;}public long getSum_num() {return sum_num;}public void setSum_num(long sum_num) {this.sum_num sum_num;}public long getSum_size() {return sum_size;}public void setSum_size(long sum_size) {this.sum_size sum_size;}//构建前缀树函数public void InsertToPrefixTree(String filePath, long fileSize, PrefixTreeNode root) throws UnsupportedEncodingException {//0. size如果为0 则为目录可优化的点//1.对filePath进行URL解码String decodedFilePath URLDecoder.decode(filePath, UTF-8);//2.识别filePath是否以“/”结尾如果是说明该路径仅为目录没有文件对象。boolean contains_file_flag false;if (!decodedFilePath.endsWith(/)) {contains_file_flag true;}//3.将目录进行拆分String[] split decodedFilePath.split(/);//“/”//4.对split数组进行遍历构建前缀树PrefixTreeNode head root;if (split.length 1 contains_file_flag true) {//当该函数为文件节点时不加入目录的前缀树,但对当前节点的file_num与file_size进行修改head.file_num;head.file_size fileSize;return;}//5.如果是目录则安好一般情况处理for (int i 0; i split.length; i) {if (head.nexts null) {//初始化一个hashmaphead.nexts new HashMap();}if (!head.nexts.containsKey(split[i])) {//若前缀树中不存在该节点加入该节点PrefixTreeNode newNode new PrefixTreeNode();head.nexts.put(split[i], newNode);}//获取下一个节点对该节点进行一些操作//将该节点名称进行设置head.nexts.get(split[i]).Name split[i];//判断该目录的下一个节点是不是文件对象如果是则该节点为一个最小目录if (i 1 split.length - 1 contains_file_flag true) {head.nexts.get(split[i]).file_num;head.nexts.get(split[i]).file_size fileSize;break;//不需要加入叶子节点}//去遍历下一个节点head head.nexts.get(split[i]);}}//遍历前缀树函数public void TraversePrefixTreeWriteToFile(PrefixTreeNode root, StringBuffer Name, FileWriter writer) throws IOException {//遍历节点的nextsif (root.nexts null) {//如果该目录下没有nexts则直接返回return;}HashMapString, PrefixTreeNode nexts root.nexts;for (String s : nexts.keySet()) {StringBuffer directoryName new StringBuffer(Name);if (!String.valueOf(directoryName).equals()) {directoryName.append(/);}directoryName.append(s);//1.如果该目录下包含文件则输出该目录上级所有目录并输出该目录下filenum file_sizeif (nexts.get(s).file_num ! 0) {//2.将结果写入文件,去掉最开头的/writer.write(directoryName , nexts.get(s).file_num , String.valueOf(nexts.get(s).file_size));writer.write(\n);System.out.println(directoryName , nexts.get(s).file_num , String.valueOf(nexts.get(s).file_size));}//3.以该节点为根节点进行遍历TraversePrefixTreeWriteToFile(nexts.get(s), directoryName, writer);}}public void TraversePrefixTree(PrefixTreeNode root, StringBuffer Name) {//遍历节点的nextsif (root.nexts null) {//如果该目录下没有nexts则直接返回return;}HashMapString, PrefixTreeNode nexts root.nexts;for (String s : nexts.keySet()) {StringBuffer directoryName new StringBuffer(Name);if (!String.valueOf(directoryName).equals()) {directoryName.append(/);}directoryName.append(s);//1.如果该目录下包含文件则输出该目录上级所有目录并输出该目录下filenum file_sizeif (nexts.get(s).file_num ! 0) {//2.将结果写入文件,去掉最开头的/System.out.println(directoryName / 目录包含 String.valueOf(nexts.get(s).file_num) 个文件总大小 String.valueOf((double) nexts.get(s).file_size / 1024) MB);}//3.以该节点为根节点进行遍历TraversePrefixTree(nexts.get(s), directoryName);}}public void TraversePrefixTreeValid(PrefixTreeNode root, StringBuffer Name) throws IOException {//遍历节点的nextsif (root.nexts null) {//如果该目录下没有nexts则直接返回return;}HashMapString, PrefixTreeNode nexts root.nexts;for (String s : nexts.keySet()) {StringBuffer directoryName new StringBuffer(Name);if (!String.valueOf(directoryName).equals()) {directoryName.append(/);}directoryName.append(s);//1.如果该目录下包含文件则输出该目录上级所有目录并输出该目录下filenum file_sizeif (nexts.get(s).file_num ! 0) {//2.将结果写入文件,去掉最开头的/sum_num nexts.get(s).file_num;sum_size nexts.get(s).file_size;System.out.println(directoryName / 目录包含 String.valueOf(nexts.get(s).file_num) 个文件总大小 String.valueOf((double) nexts.get(s).file_size / 1024) MB);}//3.以该节点为根节点进行遍历TraversePrefixTreeValid(nexts.get(s), directoryName);}}}
3对所构建的前缀树进行测试
从csv文件中读取每一行的目录名和文件大小按行调用前缀树的构建。总体代码如下
import com.obs.prefixTree.PrefixTree;
import com.obs.prefixTree.PrefixTreeNode;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;/*** author sq* date 2023/8/28* Description ${}*/
public class PrefixTreeBuilderfromCsvTest {public static void main(String[] args) throws IOException {//获取要处理的桶清单文件以及要写入的文件String csvFile 0000018A3A73BC14454759A9F377424D_1.csv;String fileName result.csv;//1.初始化前缀树//1.1创建一颗只有根节点的树PrefixTree treenew PrefixTree(new PrefixTreeNode(,null));//2.按行遍历csv文件String line ;String csvSplitBy ,;boolean header_flag true;int key_index -1;int size_index -1;int bucket_index-1;try (BufferedReader br new BufferedReader(new FileReader(csvFile))) {while ((line br.readLine()) ! null) {String[] data line.split(csvSplitBy);if (header_flag) {for (int i0;idata.length;i) {if(data[i].equals(Bucket)){bucket_indexi;}if(data[i].equals(Key)){key_indexi;}if(data[i].equals(Size)){size_indexi;}}header_flag false;continue;}tree.getRoot().setName(data[bucket_index]);//如果不是第一行,则按照正常数据处理构造前缀树tree.InsertToPrefixTree(data[key_index],Long.parseLong(data[size_index]),tree.getRoot());}} catch (IOException e) {e.printStackTrace();}//3.遍历前缀树FileWriter writer new FileWriter(fileName);//3.1加入表头writer.write(Directory , FileNumber,FileSize); // 写入内容writer.write(\n); // 换行//3.2记录根节点对象数对象大小//3.2.1写入到文件writer.write(tree.getRoot().getName() , tree.getRoot().getFile_num(),tree.getRoot().getFile_size()); // 写入内容writer.write(\n); // 换行//3.2.2输出到控制台System.out.println(tree.getRoot().getName() , tree.getRoot().getFile_num(),tree.getRoot().getFile_size());//3.3 遍历前缀树写入文件tree.TraversePrefixTreeWriteToFile(tree.getRoot(), new StringBuffer(tree.getRoot().getName()), writer);//4.关闭写入流writer.close();}}
最后想说一下树的构建和遍历都不要死记硬背隶属与递归的问题都可以使用自然智慧在尝试中得到普遍逻辑。