大文件排序求频率TOP问题

  • 问题:
有一个1G大小的一个文件,里面每一行是一个词,
词的大小不超过16字节,内存限制大小是10M。返回频数最高的100个词。
  • 该类型问题分析(分而治之)
1、找出一种分类方式(找到散列方式或散列函数);
2、特殊情况考虑,防止分类后单类文件过大问题;
3、对分类的文件进行归并。
  • 本题解决思路(分而治之):
1、分类方式(尽可能保证相同类型在一个文件中):
按照26个英文字母及字母长度分类;
例:文件名:a4,b5,c8....
字母小于4个为一组,大于等于4小于等于5为一组,大于5为一组,工三组。
最多产生文件个数:26乘以378个。
2、假设一个文件多大;首先按长度再次分割,
再按第二、三.....个英文字母再次分割;假设都相同,单词相同。
3、结果(归并)。


代码下载地址

  • Java代码(未优化代码):
package com.wqq.study.demo.service.bigdata;

import java.io.*;
import java.util.*;

/**
 * @ClassName: BigData
 * @Description:
 *
 *
 * java内存大小计算器
 * //计算指定对象及其引用树上的所有对象的综合大小,单位字节
 * long RamUsageEstimator.sizeOf(Object obj)
 * //计算指定对象本身在堆空间的大小,单位字节
 * long RamUsageEstimator.shallowSizeOf(Object obj)
 * //计算指定对象及其引用树上的所有对象的综合大小,返回可读的结果,如:2KB
 * String RamUsageEstimator.humanSizeOf(Object obj)
 * <dependency>
 *             <groupId>org.apache.lucene</groupId>
 *             <artifactId>lucene-core</artifactId>
 *             <version>4.0.0</version>
 *         </dependency>
 * @Author: wqq
 * @create: 2019/10/28
 **/
public class BigData2 {
    /**
     * 大文件位置
     */
    public  static  String BIG_FILE_NAME="C:\\Users\\wqq\\Desktop\\bigdata\\bigdata.txt";
    public  static  String SORT_FILE_NAME="C:\\Users\\wqq\\Desktop\\bigdata\\bigdatasort.txt";

    /**
     * 100
     */
    public  static  Integer LIMIT=100;

    /**
     * 换行符
     */
    public static String LINE_SEPARATOR="\r\n";


    public static void main(String[] args) throws  Exception{
        BigData2 bigData=new BigData2();
        //生成大文件
        //bigData.StringBufferDemo();
        List<Map.Entry<String,Integer>> return100=separateFile();
        System.out.println("return100:"+return100.size());
    }

    /**
     * 大文件分片排序
     * @return
     */
    private static List<Map.Entry<String,Integer>> separateFile() {
        Set<String> fileNameList = new TreeSet<>();
        Map<String,FileWriter > map = new HashMap<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(BIG_FILE_NAME))) {
            String line="";
            while ((line = reader.readLine()) != null) {
                line=line.toLowerCase();
                int len=line.length();
                String fileTemp = proFileName(line);
                if(map.containsKey(fileTemp)){
                    FileWriter tmpWriterTemp= map.get(fileTemp);
                    tmpWriterTemp.write(line+LINE_SEPARATOR);
                }else {
                    try {
                        FileWriter tmpWriter = new FileWriter(fileTemp);
                        map.put(fileTemp,tmpWriter);
                        tmpWriter.write(line+LINE_SEPARATOR);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
                fileNameList.add(fileTemp);
            }
            //统计出现频率最高的词汇
             return getSort(fileNameList);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //文件输入流关闭
            for (String reader : map.keySet()) {
                try {
                    map.get(reader).close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     *  生成散列文件名,自己优化
     * @param line 读取文件每行
     * @return
     */
    private static String proFileName(String line) {
        int len=line.length();
        StringBuffer stringBuffer=new StringBuffer();
        stringBuffer.append("C:\\Users\\wqq\\Desktop\\bigdata\\");
        if(len<4){
            if(len>0){
                stringBuffer.append("temp"+line.substring(0,1)+"3");
            }else{
                stringBuffer.append("temp"+"3");
            }
        }else if(3<len &&len<5){
            stringBuffer.append("temp"+line.substring(0,1)+"4");
        }else if(4<len &&len<6){
            stringBuffer.append("temp"+line.substring(0,1)+"5");
        }else{
            stringBuffer.append("temp"+line.substring(0,1)+"6");
        }
        stringBuffer.append(".txt");
        return stringBuffer.toString();
    }


    /**
     * 排序 注意:特殊情况自己来补充,比如取前100的时候,120的单词频率和100一样,自己优化
     * @param fileNameList
     * @return
     * @throws Exception
     */
    public static List<Map.Entry<String,Integer>> getSort(Set<String> fileNameList) throws Exception{
        List<Map.Entry<String,Integer>> entrysReturn=new ArrayList<>();
        for(String fileNameSet:fileNameList){
            Map<String,Integer> countMap=new HashMap<>();
            try (BufferedReader readerSet = new BufferedReader(new FileReader(fileNameSet))) {
                String lineSet="";
                while ((lineSet = readerSet.readLine()) != null) {
                    if(countMap.containsKey(lineSet)){
                        int value=countMap.get(lineSet);
                        value++;
                        countMap.put(lineSet,value);
                    }else {
                        countMap.put(lineSet,1);
                    }
                }
            }
            List<Map.Entry<String,Integer>> entrys=new ArrayList<>(countMap.entrySet());
            Collections.sort(entrys, new Comparator<Map.Entry<String, Integer>>() {
                // 升序排序
                public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                    return o2.getValue().compareTo(o1.getValue());
                }
            });
            if(entrys.size()>LIMIT){
                entrysReturn.addAll(entrys.subList(0,LIMIT));
            }else{
                entrysReturn.addAll(entrys);
            }
        }
        Collections.sort(entrysReturn, new Comparator<Map.Entry<String, Integer>>() {
            // 升序排序
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        if(entrysReturn.size()>LIMIT){
            return entrysReturn.subList(0,LIMIT);
        }else{
            return entrysReturn;
        }
    }




    /*生成数据方法start*/

    /**
     * 随机获取长度为12~20的大小写字母混杂的“单词”
     */
    private String randomWord() {
        // 12~20长度,包含12及20
        int length = 2 + (int) (Math.random() * 5);
        String word = "";
        for (int i = 0; i < length; i++) {
            word += (char) randomChar();
        }
        return word;
    }
    /**
     * 随机获取'a'~'z' 和 'A'~ 'Z'中的任一字符
     *
     * 'A'~ 'Z'对应ASCII值:65~90
     *
     * 'a'~'z'对应ASCII值:97~122
     *
     * @return
     */
    private byte randomChar() {
        // 0<= Math.random()< 1
        int flag = (int) (Math.random() * 2);// 0小写字母1大写字母
        byte resultBt;
        if (flag == 0) {
            byte bt = (byte) (Math.random() * 26);// 0 <= bt < 26
            resultBt = (byte) (65 + bt);
        } else {
            byte bt = (byte) (Math.random() * 26);// 0 <= bt < 26
            resultBt = (byte) (97 + bt);
        }
        return resultBt;
    }
    public void StringBufferDemo() throws IOException{
        File file=new File("C:\\Users\\wqq\\Desktop\\bigdata\\bigdata.txt");
        if(!file.exists())
            file.createNewFile();
        FileOutputStream out=new FileOutputStream(file,true);
        BigData2 bigData=new BigData2();;
        for(int i=0;i<100000000;i++){
            StringBuffer sb=new StringBuffer();
            sb.append(bigData.randomWord());
            sb.append("\r\n");
            out.write(sb.toString().getBytes("utf-8"));
        }
        out.close();
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本程序采用最新的topapi 2.0编写的。 1.网站首页可通过后台管理自动更新,使首页不再静止不变,从而加快百度快照的更新和提高百度页面的收录。 2.支持API商品数据缓存,全面提高网页访问速度,更重要的是减少API调用次数,从而避免因API每分钟调用频率过高导致无法获取商品数据的问题。 3:全面支持中文淘宝昵称,从而使淘宝昵称为中文的淘宝客也能使用API程序。 4:彻底摒弃convert.php商品分类文件,全面采用api获取商品分类信息(页面左侧商品分类、搜索下拉框分类以及子分类),从而避免个别分类因为id变更无法获取商品数据的问题 5.商品列表页面和搜索页面的商品展示增加卖家信誉图标信息。 6:商品列表页面和搜索页面增加价格区间排序(1~100元 100~200元 200~500元 500~1000元 1000~2000元 2000~5000元 5000元以上),而且过滤掉超高价格或超低价格等无用商品。 7:商品详细页面顶部增加与该商品相关的分类链接,(智能获取该商品的分类从而显示与之相关的分类链接)宝贝详情屏蔽了卖家设置的相关商品超级链接。 8:智能屏蔽违规内容的分类商品(不但不显示违规分类名称,而且也不会采集违规分类商品数据),并将其统一转换成女装分类商品 。 9:页面顶部增加频道推广的单独页面。 10:可以配置Pid、AppKey、AppSecret、网站标题、网站关键字、网站描述等参数,从而免去多个页面重复修改,从而成为你真正属于自己的网站。 整个网站CSS设置精细,没有冗余内容,全面兼容IE6、IE7、火狐等浏览器。 ========================================================================================================= 关于config.php文件的说明和修改方式。 <?php $userpid = 'mm_xxxxxxxx_0_0'; //替换成你自己的淘宝pid,用于首页主题推广 $userpiddp = xxxxxxx; //替换成你自己的淘宝pid中间纯数字部分,用于首页店铺推广 $usernick = iconv("GBK","UTF-8","xxxx"); //将muted1替换成你自己的淘宝昵称,汉字也同样支持 $Taoapi_Config = Taoapi_Config::Init(); $Taoapi_Config->setTestMode(false) ->setAppKey(123456789) //替换成你自己的AppKey ->setAppSecret(xxxxxxxxxxxxxxxxxxxx); //替换成你自己的AppSecret $Taoapi = new Taoapi; $Taoapi->Cache->setCacheTime(24); //缓存时间设置单位为小时(设置为0表示关闭缓存功能) ?> ========================================================================================================= 【缓存文件清空】和【首页商品更新】说明: 1:后台管理页面:admin.php 2:点击【Delete.php链接】即可清空所有已生成的缓存文件。 3:点击【更新首页商品】按钮即可完成首页商品更新。 (请将下拉框里的所有分类都选择一次并更新才可以将首页商品完全更新,需要注意的是每个分类你只需要选择一页即可,他的意思是你抓取哪一页的内容放到首页,前期很多朋友理解错误) 备注:列表页商品、搜索页商品以及商品详细页均可通过AppKey自动实时采集商品数据,无需数据库。 来源:数位板价格—http://www.pconcar.com
店盟淘宝客程序 11.2 TOP/API2.0是一套基于淘宝开放平台提供的API开发出来的淘宝客推广程序,又称淘宝客网站、淘客程序、淘客源码,目前通过这套API版淘宝客程序可以按各种排序方式获取淘宝客商品列表、店铺商品列表及商品参数信息,方便易用、轻松建立淘宝客推广网站,进行淘宝客商品及店铺的推广。 本程序无商业版永久开源免费,有什么问题及建议可以去淘宝客推广高手交流QQ群:48392299(公益群广告止步) 后台地址/admin 后台帐号:admin 后台密码:adminadmin 【最近更新】 1.增加了自动301跳转设置,选中的话,将自动把所有绑定的域名跳转到主域名。该功能在后台高级设置里。 2.优化网站目录结构。 data目录为网站配置文件保存目录。以后备份网站只需要备份data目录。 3.增加热门关键自定义功能 4.增加商品随机显示页数设置范围设置功能 5.修正了后台注销、搜索等几处BUG 【特色功能】 特有的商品随机调用功能会增加搜索引擎收录量以及用户体验,其它淘客站千万页收录用的就是它。 热门搜索位置显示多少个关键,以及是否每次刷新页面随机显示,随机会增加以及加速搜索引擎收录量。 S8跳转功能:当商品已下架,点击"立刻购买",可跳转到S8设置搜索,防止客户流失。 App Key轮换功能:当一个App Key超频则自动切换到下一个App Key。有效解决因API调用频率不够而无法调取到商品数据的情况。 彻底屏蔽淘宝客连接和淘宝图片标志,百度不会因为是淘宝客站点而K掉。 后台整站佣金范围和信誉范围自定义。 强大的缓存功能可以有效的节约API调用次数和访问速度。 支持伪静态功能。 【基本功能】 站点配置 网站名称、网站域名、站长联系信息、备案信息、统计代码等基本信息 淘客配置 淘宝账号、淘客PID、App Key、App Secret设置,支持App Key轮换功能 高级参数 网站的一些高级功能开启关闭及设置 热门搜索 后台可以对网站的热门搜索关键字进行自定义 热门导航 后台可以对网站的热门导航进行管理 网站导航 后台可以对网站的导航栏进行管理 首页配置 首页的幻灯图片、特价、品牌推荐、热门活动等都可以后台设置 站点优化 可自定义页面标题、关键字及描述,利于SEO 风格模板 采用了模板技术,可以通过后台打造属于自己的个性模板。 广告管理 后台可以对网站的广告位进行管理 友情链接 后台可以对网站的友情链接进行管理 文件前缀 此功能为一些喜欢自定义文件名前缀的用户所设计 【运行环境】 运行环境:PHP环境(无需数据库支持) 开启伪静态功能需要服务器支持伪静态(rewrite)组件。 空间大小:开启缓存需要300M-1000M空间,不开启缓存100M空间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值