#22 Project Euler:为什么我的回答错了?

时间:2016-03-19 20:33:11

标签: python python-3.x

我正在努力解决Project Euler上的Problem 22

  

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

     

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

     

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

names.txt的内容是

"MARY","PATRICIA","LINDA","BARBARA","ELIZABETH","JENNIFER","MARIA",....[46k omitted]

我不明白为什么在使用此代码时我得到的答案不正确:

import os
chart=open('names.txt')
doc=chart.read()
doc=doc.split(',')
doc.sort()
z=0

def nameNum(name):
    r=0
    for letter in name:
        r=r+ord(letter) - 64
    return r

for string in doc:
    z+=(doc.index(string)+1)*nameNum(string)
print z

我试图让z产生答案,但它不正确,我无法弄清楚原因。

顺便说一下,这是python 3。

2 个答案:

答案 0 :(得分:3)

您正在为引号"和名称进行评分。最简单的方法是在以逗号分割之前删除它们;

...
doc=chart.read()
doc=doc.replace('"', '')
doc=doc.split(',') 
...

在修复之前,你获得了COLIN的负分

Name: "COLIN", pos: 938, score: -6566

...但是根据示例修复后它是正确的;

Name: COLIN, pos: 938, score: 49714

答案 1 :(得分:1)

您的实际算法没有任何问题,但问题是当您按,分割文件时,每个名称周围仍有"个字符;因此,您错误地将2 * (64 - ord('"'))添加到每个名称的分数中,这就是您获得错误结果的原因。

该文件的格式可以通过ast.literal_eval()轻松解析为字符串元组:

import ast
with open('names.txt') as f:
     contents = f.read()
     names = sorted(ast.literal_eval(contents)) 

现在names是一个排序的名称列表,没有任何额外的字符。使用此列表而不是doc,我从您的算法中得到了正确的结果。

虽然这不会影响算法本身,但使用.index查找项目索引的效率非常低:

for string in doc:
    z+=(doc.index(string)+1)*nameNum(string)

你应该use enumerate代替:

for number, name in enumerate(names, start=1):
    z += number * nameNum(name)

现在names是一个排序的名称列表,没有任何额外的字符。通过这些更改,我得到了正确的结果。