• ag亚游集团 2019-02-09
  • 立即下载 知乎日报 每日提供高质量新闻资讯

    说出八个字包含三个成语,不难,我来说 20000 个吧

    图片:编辑一口气瞎说

    有哪些用八个字连续说出来就包含三个成语的例子?

    路路,做点自己感兴趣的事,发现更大的世界。

    ag游戏 www.heshengqui.cn 考虑到自己能想起的成语数量实在有限,所以就把这个问题交给计算机来处理吧。

    首先,很容易就在网上下载到了一个 access 格式的数据库,经检查实际存储了去重后的四字成语两万九千多个。导出为 txt 格式的文件。

    然后打开了 eclipse ,写下了以下代码:

    package com.example.chengyuconnect;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStreamReader;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.sql.DriverManager;
    
    public class ChengyuConnect {
    	static String[] cy = new String[30000];
    	static String[] cy1=new String[30000];
    	static String[] cy2=new String[30000];
    
    	public static void main(String[] args) {
    		getCy();
    		splitCy();	
    		searchCy();
    	}
    	
    	static void getCy() {
    		try {
                File f = new File("F:\\chengyu.txt");
                InputStreamReader reader = new InputStreamReader(new FileInputStream(f),"Unicode"); 
                BufferedReader br = new BufferedReader(reader);
                String line = br.readLine();
                for(int n = 0;line.length()==4;n++) { 
                    cy[n] = line;
                    line = br.readLine();
                }
    		} catch (Exception e) {
                e.printStackTrace();
            } 
    	}
    	
    	static void splitCy() {
    		for(int i = 0;i<cy.length && cy[i+1]!=null ;i++) {
    			cy1[i] = cy[i].substring(0,2);
    			cy2[i] = cy[i].substring(2,4);
    		}
    	}
    	
    	static void searchCy() {
    		for(int i=0;i<cy.length;i++) 
    			for(int j=0;j<cy.length;j++) 
    				if(cy2[i] != null && cy1[j] != null && cy2[i].equals(cy1[j]))
    					for(int k=0;k<cy.length;k++)
    						if(cy2[j] != null && cy1[k] != null && cy2[j].equals(cy1[k]))
    							System.out.println(cy[i]+cy[k]);
    	}
    	
    }
    

    大概的思路是:

    1. 读取 txt 文件里的成语,每次读取一行,将四字成语存储到一个数组里;
    2. 将成语的前两个字和后两个字分开存储到两个数组里;
    3. 根据题意,符合条件的三个成语,需要满足第一个成语的后两个字 ,是第二个成语的前两个字,第二个成语的后两个字,又是第三个成语的前两个字。所以写三个嵌套的循环,从存储了后两个字的数组开始,和存储了前两个字的数组作比较,如果两个字相同,就再使用后者对应的成语的后两个字,和存储了前两个字的数组作比较,如果还能发现相同的,就表示这三个成语符合条件。

    运行,几秒钟就可以看到所有结果:

    将结果复制粘贴到表格里,数量 2 万 5809:

    全部结果就不发出来了,因为不知道知乎是否支持写 20 多万字的回答。


    在表格的截图里,还有三个单元表,CY 看起来像是表示成语……嗯,这其实是一个失败的尝试。本想直接在表格里处理,可是没料到 VLOOKUP 函数处理速度太慢,几万条数据直接让表格崩溃了,所以最后就留一张测试部分的截图作为纪念吧。


    2018.11.29 更新

    感谢 @忠肝义胆吕奉先 在评论中指出回答里的一个问题:在输出的结果中,存在前后两个成语相同的情况,如果认为三个成语是互不相同的成语,则需要在代码中限制输出的是前后不相同的两个成语连接起来的八个字。

    除了直接改代码,也可以把结果复制粘贴到表格里,在表格里进行判断和筛选,这样还能发现一批前后两个字互换位置,结果仍是成语的成语。

    扫描二维码下载知乎日报

    支持 iOS 和 Android
    二维码下载知乎日报
    阅读更多 德国工人为什么愿意干到退休?因为他们站着把钱挣了 ag游戏