寻找最长单词链
大家经常玩成语接龙游戏,我们试一试英语的接龙吧:一个文本文件中有N 个不同的英语单词, 我们能否写一个程序,快速找出最长的能首尾相连的英语单词链,每个单词最多只能用一次。最长的定义是:最多单词数量,和单词中字母的数量无关。
统一输入文件名称:input1.txt, input2.txt
统一输出文件名称:output1.txt,output2.txt
【设计思想】
看到这个题,首先要做的是将题目简单化,这也是老师上课经常说的,只有将复杂的问题简单化,才能效率提高。
思路分析:
* 先将单词从input.txt文件读入
* 将单词首尾字母存储
* 将结果存储到文件output.txt里
其中,第二步是最主要的代码部分:
将读取的TXT文档中的字符串进行分割,然后存到动态数组中
遍历动态数组,将重复单词剔除,同时将单词的首位字母和单词本身存在新的对象数组中
建立动态数组A,用来存储动态数组B,数组B用来存储生成的单词链
遍历首尾单词,如果首个单词的尾字母和下一个单词的首字母相同则将单词加入数组B1,双重循环遍历存储
最后在A数组中查找最长的B数组,将B数组存储到output.txt中
【代码】
package dancilian; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.List; class Word{ public String value; public String first; public String end; public Word(String value,String first,String end) { this.value = value; this.first = first; this.end = end; } } public class main { /** * 先将单词从input.txt文件读入 * 将单词首尾字母存储 * 将结果存储到文件output.txt里 */ //读取文件内容 public static String txt2String(File file){ StringBuilder result = new StringBuilder(); try{ BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 String s = null; while((s = br.readLine())!=null){//使用readLine方法,一次读一行 result.append(System.lineSeparator()+s); } br.close(); }catch(Exception e){ e.printStackTrace(); } return result.toString(); } public static void main(String[] args){ File file = new File("E:\\Program Files\\eclipse操作\\dancilian\\src\\dancilian\\input.txt"); String result = txt2String(file); System.out.println(result); String Huafen[]; List<Word> list = new ArrayList<>(); Huafen = result.split(" "); for(int i =0;i<Huafen.length;i++) System.out.println(Huafen[i]); /* * 将单词首尾字母找出,存到数组list*/ for(int i = 0 ;i < Huafen.length;i++) { String w = Huafen[i]; int l = w.length(); String first = w.substring(0,1);//首字母 String end = w.substring(w.length()-1);//尾字母 Word n = new Word(w,first,end); list.add(n); } for(int i = 0 ; i < list.size(); i++) { System.out.println(list.get(i).value+" "+list.get(i).first + " " + list.get(i).end); } System.out.println(list.get(0).value); System.out.println(list.get(0).first); System.out.println(list.get(0).end); String key = list.get(0).end; ArrayList al = new ArrayList(); for(int i = 1; i < list.size();i++) { ArrayList pa = new ArrayList(); pa.add(list.get(i-1).value); for(int j = i; j < list.size();j++) { if(key.equals(list.get(j).first)) { key = list.get(j).end; pa.add(list.get(j).value); } } al.add(pa); } ArrayList max = new ArrayList(); max = (ArrayList) al.get(0); for(int i=1;i<al.size();i++) { ArrayList now = (ArrayList) al.get(i); if(max.size()<now.size()) { max = now; } } for(int i = 0 ;i< max.size();i++) { System.out.println(max.get(i)); } String [] as = new String [100]; for(int i = 0 ;i< max.size();i++) { as[i] = (String) max.get(i); } try { BufferedWriter bw = new BufferedWriter(new FileWriter("e://output.txt")) ; for(int i = 0;i<as.length;i++) { bw.write(as[i]); } } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } }
程序需要考虑下列异常状况:
例如,文件不存在,你的程序会崩溃么,还是能优雅地退出并给用户提示信息?
在代码中可以添加异常抛出和获取,或者直接用if语句输出提示并退出。
如果文件没有任何单词、只有一个单词、没有可以首尾相连的单词,程序应该如何输出?
这些也是可以在一开始就if语句进行判断,当出现三种情况时分别输出什么。
如果输入文件有一万个单词,你的程序能多快输出结果?
这就涉及到提高自己的代码效率,降低时间复杂度,优化代码。