Java实现成语接龙 您所在的位置:网站首页 单词接龙Java实现 Java实现成语接龙

Java实现成语接龙

2024-06-29 23:22| 来源: 网络整理| 查看: 265

近来,想做一些算法练习,无意中想到了我们非常熟悉的成语接龙游戏(本次以四字成语为例),就想着如何用java实现成龙接龙的关键逻辑。说干就干,于是很快梳理了一下思路:

1、首先在数据库构建一个表,导入大量的成语,作为成语储备。(这是基础)

2、思考接龙逻辑,实现成语接龙。(这是核心)

首先,我们来构建成语库,根据成语接龙的游戏规则,思考了下,表至少需要以下字段:成语内容、成语首字、成语末尾字。如果成语接龙的规则再放宽,比如接龙的时候只考虑读音一致也行,那么再补充成语首字拼音、成语末尾字拼音两个字段。于是,表结构基本确定下来了,以Spring Data JPA为例,成语的Entity如下:

@Entity @Table(name = "t_idiom") public class IdiomEntity { @Id private String id = Util.getUUIDStr(); private String value;//四字成语,如:龙飞凤舞 private String wordS;//成语的首字 private String wordE;//成语的末尾字 private String pinyinS;//成语的首字拼音 private String pinyinE;//成语的末尾字拼音 private String paraphrase;//成语解释 //为节约篇幅,此处省略get、set方法。 }

表建好之后就需要导入数据了,我从网上找了个txt版的成语大全,非常全,大概接近三万条成语。这么多数据,当然需要通过程序导入表里了,可以通过java读取txt文件的内容,加以逻辑,将数据存到表里。java读取txt文件的代码可自行研究学习,不在详细解释,因为这不是本文的重点。txt文件内容的格式如下:

读取txt文件并保存数据代码如下:

@Override public void readTxt(String filePath) { File file = new File(filePath); StringBuilder result = new StringBuilder(); try{ BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 String s = null; while((s = br.readLine())!=null){//使用readLine方法,一次读一行 if (s.indexOf("拼音") > 0) { String value = s.substring(0, s.indexOf("拼音")).trim(); if (value.length() == 4) { IdiomEntity idiomEntityOld = idiomRepo.findFirstByValue(value); if (idiomEntityOld == null) { try { String pinyin = s.substring(s.indexOf("拼音:") + 3, s.indexOf("释义")); String paraphrase = s.substring(s.indexOf("释义:") + 3); String wordS = value.substring(0,1); String wordE = value.substring(3,4); String pinyinS = pinyin.substring(0, pinyin.indexOf(" ")); String pinyinE = pinyin.substring(pinyin.lastIndexOf(" ") + 1); IdiomEntity idiomEntity = new IdiomEntity(); idiomEntity.setValue(value); idiomEntity.setWordS(wordS); idiomEntity.setPinyinS(pinyinS); idiomEntity.setWordE(wordE); idiomEntity.setPinyinE(pinyinE); idiomEntity.setParaphrase(paraphrase); idiomRepo.save(idiomEntity); } catch (Throwable e) { continue; } } } } } br.close(); }catch(Exception e){ e.printStackTrace(); } }

 成语大全里已经给出了成语的汉语拼音了,非常方便,但是如果没有带拼音的话,我们也可以通过java代码获取汉字的汉语拼音,代码如下:

/** * 汉字转为拼音 * @param chinese * @return */ public static String ToPinyin(String chinese){ String pinyinStr = ""; char[] newChar = chinese.toCharArray(); HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat(); defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE); defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); for (int i = 0; i < newChar.length; i++) { if (newChar[i] > 128) { try { pinyinStr += PinyinHelper.toHanyuPinyinStringArray(newChar[i], defaultFormat)[0]; } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); } }else{ pinyinStr += newChar[i]; } } return pinyinStr; }

读入成语数据,算是完成了第一步,如图:

一共28603条成语,成语库很丰富了。

接下来,最关键的一步,实现成语接龙的逻辑,就以最常见的游戏规则(接龙的时候前后两个成语的首尾字必须一致)为例。思路如下:根据输入的第一个成语(也就是龙头句),根据它的末尾字(也就是关节字)来接龙,我们可以去数据库里检索第二个成语(首字等于龙头句的末尾字)。检索到的第二个成语肯定不止一个,按照同样逻辑,检索下一个成语,每次检索都会有多个答案。就像一棵树一样,龙头句相当于树的根部,每次接龙多会分N个树杈,直到无法接上(到达叶子)。也就是说每条从树根到达某个叶子节点的路径都是成语接龙的答案。如何得到这些答案,并输出出来,核心就是利用递归和遍历。实现代码如下:

@Override public void idiomPlay(String sIdiom) { //sIdiom:输入的成语(龙头句) String wordE = sIdiom.substring(3, 4); //关节字 doPlay(sIdiom, wordE); } //递归方法 public void doPlay(String idiomStr, String wordE){ List idiomEntities = idiomRepo.findAllByWordS(wordE); //根据关节字检索下一条成语 if (idiomEntities.size() > 0) { for (IdiomEntity entity : idiomEntities) { if (idiomStr.indexOf(entity.getValue()) > -1) { //如果检索到的成语已经在之前的成语串里,则停止递归 System.out.println(idiomStr); } else { doPlay(idiomStr + "->" + entity.getValue(), entity.getWordE()); } } } else { //检索不到下一条成语,该路径完成 System.out.println(idiomStr); } }

输入“龙飞凤舞”,执行结果片段如下:

由于成语库非常大,接龙的答案会非常多,一时半会是执行不完的。在测试的过程中,发现有时会输出重复的答案,分析发现,在成语串已经非常长的情况下,检索下一条成语的时候如果检索到很多个,则可能会出现其中多个是已经在之前成语串中出现过,根据程序逻辑,这种情况会输出几条重复的答案,但是不会出现死循环。可以利用set集合去重,本文不再详述。

这样,一个简单的成语接龙就实现了,其他接龙玩法可依本例扩展,不再详述。

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有