题目:
Names scores
Problem 22
Using names.txt (right click and ‘Save Link/Target As...‘), a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical
position in the list to obtain a name score.
For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN would obtain a score of 938 × 53 = 49714.
What is the total of all the name scores in the file?
翻译:
题目给出文件 names.txt ,里面存放的是 5000多个名字。我们的工作有3步,第一步:将所有名字按照字典顺序排序。第二步:算出每个名字的位置值。计算方法:按照每个字母在字母表中的顺序,A:1,B:2....,算出一个名字所有字母的和,然后用这个值乘以当前名字所在的位置,比如“COLIN",所有字母和为:3+15+12+9+14=53, 再乘以名字排序后的位置:938得到 53*938=49714,为”COLIN"的位置值。第三步:求所有名字的位置值相加的和。
思路:
说了这么大一堆,就是说需要把names.txt中的所有名字读出来,放到String数组中,然后将数组排序,就可以得到排序过后的名字列表。然后算每个名字的字母值的和乘以当前的索引就求得了这个名字的位置值,然后将所有名字的位置值相加,搞定!(位置值是我自己的说法,大家不用在意)
代码:
package projectEuler; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; public class Problem22 { public static void main(String[] args) { File file = new File("F://", "names.txt"); ArrayList<String> listStr = new ArrayList<String>(); int result = 0; if (null != file) { try { FileReader fr = new FileReader(file); StringBuffer sb = new StringBuffer(); int ch; //这里条件 ">=-1"主要考虑到names.txt 的最后一个名字后面没有",",所有读到末尾的时候还应该添加一次名字到list中 while((ch = fr.read()) >= -1){ if (ch == ',' || ch == -1) { listStr.add(sb.substring(1, sb.length() - 1)); sb.delete(0, sb.length()); if (ch == -1) { break; } continue; } sb.append((char)ch); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //直接采用java内部的排序,省去排序麻烦,速度也快 Collections.sort(listStr); int listLen = listStr.size(); for (int i = 0; i < listLen; i++) { result += countStrValue(i, listStr.get(i)); } System.out.print("result:" + result); } } /** * 计算每个字符串的位置值 * @param index string所在位置 * @param str string字符串 */ public static int countStrValue(int index, String str) { int len = str.length(); char ch; int sum = 0; for (int i = 0; i < len; i++) { ch = str.charAt(i); //都是大写字母,所以可以直接减64 sum += (int) (ch - 64); } return sum * (index + 1); } }
代码里面有注释,这里就不做解释了,很简单。
本来想读取文件中的字符串到ArrayList中是一个字母一个字母读取,会花费很多时间,花了很多时间想优化,也没有找到好的方法。
然后还有一个问题就是,很多人肯定会被字符串排序那儿难倒,毕竟比较次数那么多,要考虑性能的话还是有一定难度,所以我选择了java自带的排序,这个太偷懒了,不值得借鉴哦,还是自己写一个吧!