【個人項目】--微信羣聊抄襲重複檢查--設計思路

這是一個比較奇葩的需求,先說需求:
微信羣聊,每個人會對boss說的話發表一下自己的感悟,需求就是將這些聊天記錄中重複的部分找出來,也就是把抄襲別人感悟的人找出來。

整體設計:使用springboot開發後臺接口,用戶從微信拿到格式化的數據之後,在前端通過ajax發送http請求把聊天數據post到服務端,服務端進行分析之後返回結果。

1.微信羣聊的格式

通過微信羣聊中的“更多”–>“郵件”功能把聊天記錄格式化出來,在“郵件”功能頁面可以把經過格式化的聊天信息【複製】出來,然後上傳我們的系統進行分析。
經過格式化的微信羣聊信息:
微信聊天記錄格式
紅框位置是【換行】,藍圈位置是【空格】。
初步分析:需要注意的是聊天記錄中也可能會人爲添加【換行符】,按照【換行符】截斷記錄會出現問題,這種思路走不通。


2.信息提取–>姓名、時間、聊天內容

把上面的已經格式化的信息進行分析:

姓名 [空格] 時間 [換行符]
[換行符]
聊天 [空格] 聊天 [換行符]
聊天 [空格] [換行符]
[換行符]

很顯然應該用【空行】來分割各個信息,即把整條數據按照【[換行符] [換行符]】進行分割,也就是說用兩個【換行符】進行分割,存儲到數組。
所以數組中的內容就是:[姓名+時間],[聊天內容] 這種存儲方式。
同樣這個地方可以判斷數組的length,如果爲奇數,則數據切割出錯。


3.信息存儲–>對象

實例化一個對象用於存儲一條聊天信息。

//微信消息實體類
public class WxMsg {
    private int id; //數據庫記錄id
    private String name;    //言論者
    private String timed;   //發表言論時間
    private String msg; //發表的言論
    private int ischeck;    //是否已經被檢查
    private String islike;  //和哪條記錄相似

    public WxMsg() {
        ischeck=0;
        islike=null;
    }

    get&set()

 }

接下來就是把數組中的內容放到對象中,然後把對象存到一個List中。


4.數據轉移:數組–>list

數組中,偶數位元素表示[姓名+時間],顯然要分割提取出姓名、時間。由於姓名的格式存在多樣性,所以應該從時間入手。經過考慮,決定把【姓名+時間】這個字符串從尾部截取5個字符,剩下的字符串去空格,經過這樣操作就可分析出姓名、時間:
【趙 旭東 19:46】–> 【趙旭東】、【19:46】

List<WxMsg> wxMsgList = new ArrayList<WxMsg>();//用於存儲微信信息實體的集合
        //按照\n\n分割字符串存進數組  [姓名 時間]  [聊天信息]
        String[] wxmsg_arr=wxmsgstr.split("\n\n");
        if (wxmsg_arr.length%2 == 1){
            System.out.println("格式錯誤:"+wxmsg_arr[wxmsg_arr.length-1]);
            return "error";
        }
        //else
        System.out.println("共解析出的聊天記錄條數:"+wxmsg_arr.length/2);
        //將數組中的信息提取到對象中並存儲
        for(int i=0; i<wxmsg_arr.length;i=i+2){
            WxMsg wxMsg = new WxMsg();
            //取出時間
            wxMsg.setTimed(wxmsg_arr[i].substring(wxmsg_arr[i].length()-5));
            //取出姓名
            wxMsg.setName(wxmsg_arr[i].substring(0,wxmsg_arr[i].length()-6));
            //存聊天內容
            wxMsg.setMsg(wxmsg_arr[i+1]);
            System.out.println("數據轉移arr-list:"+wxMsg.toString());
            wxMsgList.add(wxMsg);
        }

將每條記錄都存到對象中,然後存儲到list中,那麼list中的數據就是:老的聊天信息在前面,新的聊天信息在後面。
list.get(i); —> i越大,信息越新


5.重複度檢查

這是這個系統的核心,也是後期繼續優化的重點位置,目前沒有采用任何高級算法,只是先實現這個檢查功能。

  • 第一步:這也是第一層循環,從後向前遍歷List(i=max –> i=0)。至於爲什麼要從後向前遍歷?一定要先檢查最後一個人說的,檢查的是看當前【被檢查人】和前面的聊天記錄是否重複,第一個發表的人當然不需要檢查。
  • 第二步:從list中取出當前對象的一個【聊天記錄】,把這個【聊天記錄】按照各種標點符合進行分割,分割成若干句話,存到數組msg[]中。
  • 第三步:第二層循環,循環遍歷存儲當前對象聊天記錄的數組msg[],接下來就是判斷數組中存放的每一句話和list中其他對象的[聊天記錄]是否相似。
  • 第四步:第三層循環,遍歷存放對象的list(i=this-1 –> i=0),從【當前對象的位置-1】開始遍歷,一直遍歷到【開頭】,當然這裏遍歷的方向無所謂,重點是要覆蓋當前對象位置之前的記錄。在這層循環中需要判斷上層的msg[i]這句話和那個對象的[聊天記錄相似],如果相似,就進行記錄。
//分析查重
        /*
        j:當前在被查的人   z:當前被查的人的第幾句話   y:被比對的人()
         */
        System.out.println("分析查重測試");
        //從新到老把聊天記錄遍歷一遍(最老的數據當然不需要檢查)
        for(int j=wxMsgList.size()-1;j>0;j--){
            //切分這個人的聊天信息
            String[] per_msg = wxMsgList.get(0).getMsg().split("[、,。;?!,.;?\\n]");
            //用上面的分析方法,遇上標點加換行會產生空數據
            //遍歷這些聊天數據
            for(int z=0;z<per_msg.length;z++){
                //每句聊天記錄去匹配比他老的聊天信息
                for(int y=j-1;y>=0;y--){
                    if("".equals(per_msg[z])){
                        //聊天記錄是空的,不匹配
                    }else {
                        int rs = wxMsgList.get(y).getMsg().indexOf(per_msg[z]);
                        if(rs==-1){
                        }else {
                            analysestr = analysestr +
                                    wxMsgList.get(j).getName()+"在時間:"+wxMsgList.get(j).getTimed()
                                    +"說的第"+(z+2)+"句(大約)抄襲"+wxMsgList.get(y).getName()
                                    +"在時間:"+wxMsgList.get(y).getTimed()
                                    +"說的第"+rs+"個字往後 <br /> <br />";
                            System.out.println(analysestr);
                        }
                    }
                }
            }
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章