【问题标题】:Project Euler #22 in Java(off by 7 364 934)Java 中的 Project Euler #22(7 364 934 关闭)
【发布时间】:2015-01-23 02:42:23
【问题描述】:

使用 names.txt(右键单击并“将链接/目标另存为...”),一个 46K 的文本文件,其中包含超过 5000 个名字,首先按字母顺序对其进行排序。然后计算出每个名称的字母值,将该值乘以其在列表中的字母位置以获得名称分数。

例如,当列表按字母顺序排序时,COLIN 的值是 3 + 15 + 12 + 9 + 14 = 53,是列表中的第 938 个名称。因此,COLIN 将获得 938 53 = 49714 的分数。

文件中所有名称分数的总和是多少?

我得到的是 863833348,但正确答案是 871198282。我不知道出了什么问题,我尝试了所有方法但无法找出问题所在。

代码:

public static void main(String args[]) throws IOException {

    String alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    Pattern testRegEx=Pattern.compile("[^\\\"]\\w+[^\\\",]");

    String line;
    String filePath="//Users//painkillerfff//Documents//names.txt";
    BufferedReader readTextFile=new BufferedReader(new FileReader(filePath));

    List<String> nameList=new ArrayList<String>();
    while((line=readTextFile.readLine())!=null){
        //System.out.println(line);
        Matcher matcher=testRegEx.matcher(line);
        while(matcher.find()){
            nameList.add(matcher.group());
            //System.out.println(matcher.group());
        }
    }
    Collections.sort(nameList);

    long sumOfWords=0;
    long namePoint=0;
    long nameRank=1;
    for(String name: nameList){
        namePoint=0;
        for(int i=0;i<name.length();i++){
            namePoint+=alphabet.indexOf(name.charAt(i))+1;
        }
        namePoint=namePoint*nameRank;
        sumOfWords+=namePoint;
        nameRank++;
    }
    System.out.println("The Total Points is: "+sumOfWords);
}

【问题讨论】:

  • 确保正在处理名字和姓氏。那个正则表达式在做什么?
  • 该文件仅包含姓名,没有姓氏或名字分类。这是文件projecteuler.net/project/names.txt 的链接。感谢您的回复。
  • 我的意思是,验证文件中的名字和文件中的姓氏,正在处理中。也就是说,您不会将其中一个放入位桶中。
  • 我只是想强调这不是一个家庭作业问题,我只是出于兴趣才这样做。如果这就是否决票的原因。无论如何感谢您的回复。
  • 我已经验证过了,它实际上是在处理输入文件中的姓氏和输入文件中的名字。

标签: java regex string


【解决方案1】:

您的正则表达式存在某种缺陷。逗号计数显示有 5163 个名称,但您发布的名称有 5130 个。

帮助我理解正则表达式,我们可能会弄明白。

这是我的版本 - 不需要正则表达式。

    while ((line = readTextFile.readLine()) != null) {
        sb.append(line);
    }
    line = sb.toString();
    line = line.replace("\"", "");
    String[] a = line.split(",");
    System.out.println(a.length);

当然你应该使用真正的变量名,而不是a ;-)

编辑 - 我将您的正则表达式更改为

    Pattern testRegEx = Pattern.compile("\\w+");

它返回了 5163 个名字。

【讨论】:

  • 是的,我在使用 unix 测试正则表达式时才发现这一点。不过感谢您的帮助。在那之后我工作了。
【解决方案2】:

这是另一个实现:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;

public class P22 {
    public static void main(String args[]) {
        String content = null;
        try {
            content = new String(Files.readAllBytes(Paths.get("p022_names.txt")));
        } catch (IOException ioe) {
            ioe.getStackTrace();
        }
        String words[] = content.split("\",\"");
        int total = words.length;
        words[0] = words[0].substring(1);
        words[total-1] = words[total-1].substring(0,words[total-1].length()-1);
        Arrays.sort(words);
        int sumOfProducts = 0;
        int base = 'A'-1;
        for ( int i = 0 ; i < total ; i++ ) {
            int sum = 0;
            int len = words[i].length();
            for ( int j = 0 ; j < len ; j++ ) {
                sum+=words[i].charAt(j)-base;
            }
            sumOfProducts+=sum*(i+1);
        }
        System.out.println(sumOfProducts);
    }
}

总时间:56 毫秒

说明:

  • 文件被读取并存储到字符串中
  • 字符串由"," 分割。结果是一个单词数组,必须针对第一个和最后一个单词进行调整,因为在开头/结尾处有一个额外的 "
  • 数组使用Arrays.sort排序
  • 对于每个单词,位置都是i+1(因为i0 开始)并且使用char 实际上是一个整数这一事实来计算总和。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多