欧拉计划 发表于 2015-4-23 16:23:35

题目22:文件中所有名字的得分之和是多少?

本帖最后由 永恒的蓝色梦想 于 2020-7-31 10:42 编辑

Names scores

Using names.txt, 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 是一个 46K 大小的文本文件,包含 5000 多个英文名字。利用这个文件,首先将文件中的
名字按照字母排序,然后计算每个名字的字母值,最后将字母值与这个名字在名字列表中的位置相乘,得到这个名字的得分。

例如将名字列表按照字母排序后, COLIN 这个名字是列表中的第 938 个,它的字母值是 3 + 15 + 12 + 9 + 14 = 53。

所以 COLIN 这个名字的得分就是 938 × 53 = 49714.

文件中所有名字的得分总和是多少?

愤怒的大头菇 发表于 2016-8-29 10:16:11

这一题中的names.txt的链接
https://projecteuler.net/project/resources/p022_names.txt

愤怒的大头菇 发表于 2016-8-29 10:19:01

f = open('names.txt')
dic = {
      'A':1,
      'B':2,
      'C':3,
      'D':4,
      'E':5,
      'F':6,
      'G':7,
      'H':8,
      'I':9,
      'J':10,
      'K':11,
      'L':12,
      'M':13,
      'N':14,
      'O':15,
      'P':16,
      'Q':17,
      'R':18,
      'S':19,
      'T':20,
      'U':21,
      'V':22,
      'W':23,
      'X':24,
      'Y':25,
      'Z':26}
list1 = []
name = ''
for each in f:
      for i in each:
            if i ==',':
                  list1.append(name)
                  name = ''
            else:
                  if i !='"':
                        name += i
      list1.append(name)
list2=[]
while True:
      length = len(list1)
      first = list1
      for i in range(1,length):
            if len(first) > len(list1):
                  temp = len(list1)
            else:
                  temp = len(first)
            for n in range(temp):
                  if dic] > dic]:
                        first = list1
                        break
                  elif dic] < dic]:
                        first = first
                        break
                  elif dic] == dic]:
                        if n == temp - 1:
                              if len(first) < len(list1):
                                    first = first
                                    break
                              else:
                                    first = list1
                                    break
                        continue
      list2.append(first)
      list1.remove(first)
      if not len(list1):
            break
total = 0
for each in list2:
      count = 0
      for i in each:
            count +=dic
      total += count * (list2.index(each)+1)
print(total)

答案是871198282

jerryxjr1220 发表于 2016-10-11 23:09:49

本帖最后由 永恒的蓝色梦想 于 2020-6-6 08:48 编辑

871198282


Name = ["MARY","PATRICIA",...,"PORTER","LEIF","JERAMY","BUCK","WILLIAN","VINCENZO","SHON","LYNWOOD","JERE","HAI","ELDEN","DORSEY","DARELL","BRODERICK","ALONSO"]
ABC = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
Name.sort()
total = 0
for (k,each) in enumerate(Name, start = 1):
        score = 0
        for l in range(len(each)):
                for (i,words) in enumerate(ABC, start = 1):
                        if each == words:
                                score += i
        score *= k
        total += score
print total

渡风 发表于 2017-1-21 13:38:05

本帖最后由 渡风 于 2017-1-21 13:43 编辑

此代码使用matlab编程
Problem22所用时间为0.89201秒
Problem22的答案为871198282
文本跟楼上的链接一样,哎,不能贴上文件
%% 题目22:文件中所有英文总得分是多少      
%读取数据
function Ouput=Problem22(Input)
tic
if nargin==0
Input=importdata('Name.txt');
end
B=char(Input);
C=strrep(B,'"','');%字符串替换,将"带替为’
C=[',',C,','];
Num=0;%逗号的数量,Num-1为名字的个数
Set=[];
for ii=1:length(C)
    if C(ii)==','
      Temp=;%将','的位置记录下来
      Set=Temp;
      Num=Num+1;
    end
end
Name{1,Num-1}=[];%记录字符串
for jj=1:Num-1
    Name{jj}=C(Set(jj)+1:Set(jj+1)-1);%将字符串分类
end
%% 数据处理
Name=sort(Name);%对名字进行排序
Score=zeros(1,Num-1);
for jj=1:Num-1
    Score(jj)=Letter_Score(Name{jj});
end
Result=Score.*(1:Num-1);
Output=sum(Result);
toc
disp('此代码使用matlab编程')
disp(['Problem22所用时间为',num2str(toc),'秒'])
disp(['Problem22的答案为',num2str(Output)])
end
%% 子程序
%输入一个字母字符串,得到其相应的分数,A得1,B得2...Z得26
function Output=Letter_Score(Input)
if nargin==0
Input='ABCD';
end
lett={'a','b','c','d','e','f','g','h','i','j','k','l',...
    'M','N','o','p','q','r','s','t','u','v','w','x','y','z'};%a-z
Lett={'A','B','C','D','E','F','G','H','I','J','K','L',...
    'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};%A-Z
Score=0;
L=length(Input);
for ii=1:L
    Temp=Input(ii);
    for jj=1:26
      if Temp==Lett{jj}||Temp==lett{jj}
            Score=Score+jj;
      end
    end
end
Output=Score;
end

            

NiceB 发表于 2017-3-7 17:49:19

871198282
used:0.02100110s


import time
start=time.time()
f=open("p022_names.txt",'r')
name_lists=f.read().replace("\"","").split(",")
f.close()
name_lists.sort()
sum=0
for index,i in enumerate(name_lists):
    subsum=0
    for char in i:
      subsum+=ord(char)-64
    sum+=(index+1)*subsum
print (sum)
print("used:%.8fs" % (time.time()-start))

marmot 发表于 2017-3-9 00:26:39

# 读文件,大写/小写 排序,我注释了大写版本
with open('022_data.txt','r') as f:
    names = f.read().split(",")
    # names = sorted()
    names = sorted()

# ASCII码自己百度一下就可以了
def mark(a):
    # return int(ord(a) - 64)
    return int(ord(a) - 96)

sum_mark = 0
for i,name in enumerate(names):
    name_mark = sum()
    sum_mark += name_mark * (i+1)
print('答案是: ' + str(sum_mark))

wuchaoqun0311 发表于 2017-3-22 15:22:54

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

public class Problem22 {

        public static void main(String[] args) {
                File file=new File("resources/txt/problem22.txt");
                BufferedReader reader=null;
                if(file.isFile()&&file.exists()){
                        try {
                                InputStreamReader read=new InputStreamReader(new FileInputStream(file), "UTF-8");
                                reader=new BufferedReader(read);
                                String lineText="";
                                String result="";
                                while((lineText=reader.readLine())!=null){
                                        result=lineText;
                                }
                                String arr[]=result.replaceAll("\"", "").split(",");
                                long sum=0;
                                for(int pos=0;pos<arr.length;pos++){
                                        long perResult=0;
                                        int[] cs= arr.chars().toArray();
                                        for(int i:cs){
                                                perResult+=i-64;
                                        }
                                        perResult=perResult*(pos+1);
                                        sum+=perResult;
                                }                               
                                System.out.println(sum);
                                System.out.println(arr);
                                System.out.println(arr);
                        } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                        } catch (FileNotFoundException e) {
                                e.printStackTrace();
                        } catch (IOException e) {
                                e.printStackTrace();
                        }finally {
                               
                        }
                }else{
                        System.out.println("文件problem22.txt不存在或类型错误!");
                }
        }
}


输出结果
850081394
MARY
ALONSO


文档是欧拉计划上下载的,不知道哪里出了问题,感觉没问题

进击的小蜗牛 发表于 2017-5-23 15:34:03

f = open("names.txt","r")
name = f.read().replace("\"","").split(",")
name.sort()    #排序列表
jisu = num =0
nm=1
for i in name:
    for j in i:
      num += (ord(j)-64)
   jisu += num*nm
   num =0
   nm+=1
print(jisu)
列表元素从1开始计算的
计算结果:871198282

zengtaozt 发表于 2017-8-6 11:25:01

进击的小蜗牛 发表于 2017-5-23 15:34
列表元素从1开始计算的
计算结果:871198282

因为还没有做排序

debuggerzh 发表于 2020-7-30 17:26:25

来一个剑走偏锋~
先用excel vba处理数据格式
Option Explicit

Public Sub PE22()
    Open "pe22.txt" For Input As #1
    Dim s As String
    Dim cnt As Integer
    cnt = 1
    Do Until EOF(1)
      Input #1, s
      Range("a" & CStr(cnt)).Value = s
      cnt = cnt + 1
    Loop
    Close #1
End Sub

对a列升序排序后,将结果复制到in.txt中
#include<sstream>
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cstring>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#include<stack>
#include<list>
#define ICRS(i,ini,end) for (int i = ini;i < end;i++)//increase,i.e.ICS(i,0,n)
#define DCRS(i,ini,end) for (int i = ini - 1;i >= end;i--)//decrease,i.e.DCS(i,n,0)
#define MEM(x,y) memset(x,y,sizeof(x))
#define LOCAL
#define TEST
using namespace std;
typedef long long ll;
const int M = 100 + 10;
const int INF = 1e9;
const double EPS = 1e-6;
int pts(const string & s){
int sum = 0;
ICRS(i,0,s.length())sum += s - 'A' + 1;
return sum;
}

int main(){
        #ifdef LOCAL
                freopen("i.in","r",stdin);
        #endif // LOCAL
int cnt = 0;
int sum = 0;
string s;
while(cin >> s){
    sum += pts(s) * ++cnt;
}
cout << sum;
        return 0;
}

debuggerzh 发表于 2020-7-30 17:27:43

debuggerzh 发表于 2020-7-30 17:26
来一个剑走偏锋~
先用excel vba处理数据格式



pe22.txt即为欧拉计划源文档

永恒的蓝色梦想 发表于 2020-7-30 18:08:07

debuggerzh 发表于 2020-7-30 17:26
来一个剑走偏锋~
先用excel vba处理数据格式



好多头文件啊{:10_306:}

debuggerzh 发表于 2020-7-31 10:23:03

永恒的蓝色梦想 发表于 2020-7-30 18:08
好多头文件啊

竞赛题模板hhh
用万能头也行
#include<bits/stdc++.h>

永恒的蓝色梦想 发表于 2020-7-31 10:31:40

debuggerzh 发表于 2020-7-31 10:23
竞赛题模板hhh
用万能头也行

哈哈哈,我这里用不了万能头{:10_277:}
你是这道题解封后的第一个回答者,给你评个分{:10_256:}

永恒的蓝色梦想 发表于 2020-7-31 11:18:28

本帖最后由 永恒的蓝色梦想 于 2020-9-12 13:11 编辑

#include<iostream>
#include<fstream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;



template<class File, class Container>
void read(File& file, Container& container)noexcept {
    string str;


label:
    if (file) {
      if (file.get() == '"') {
            if (getline(file, str, '"')) {
                container.push_back(str);
                goto label;
            }
      }
      else {
            goto label;
      }
    }
}



int main() {
    ios::sync_with_stdio(false);

    ifstream file("p022_names.txt");
    vector<string>names;
    size_t index = 0;
    unsigned long long sum = 0;
    unsigned short temp;


    read(file, names);
    sort(names.begin(), names.end());


    while (index < names.size()) {
      temp = 0;

      for (char ch : names) {
            temp += ch - 64;
      }

      index++;
      
      sum += temp * index;
    }


    cout << sum << endl;
    return 0;
}

永恒的蓝色梦想 发表于 2020-7-31 15:25:32

本帖最后由 永恒的蓝色梦想 于 2020-7-31 15:28 编辑

Python 一行:print(sum(index * sum(ord(char) - 64 for char in name) for index, name in enumerate(sorted(eval(open("p022_names.txt").read())), 1)))

debuggerzh 发表于 2020-7-31 16:52:21

永恒的蓝色梦想 发表于 2020-7-31 10:31
哈哈哈,我这里用不了万能头
你是这道题解封后的第一个回答者,给你评个分

感谢~{:10_297:}

a1351468657 发表于 2021-3-9 20:09:43

本帖最后由 a1351468657 于 2021-3-10 11:45 编辑

f = open('names.txt', 'r')

temp = f.read().replace('"', '')
name = temp.split(',')
name.sort()

f.close()
sum1 = 0
len1 = len(name)
for i in range(len1):
    length = len(name)
    count = 0
    for j in range(length):
      count += ord(name) - 64
    sum1 += count * (i + 1)

print(sum1)

我用C语言想了一下午怎么排序,然后想出来了,发现数据量太大,能力有限。直接转用Python, 5分钟不到出来了。。。。
希望哪位大佬用C语言写出来能@我一下,谢谢!

睡了一觉,突然想到甲鱼老师在带你学C带你飞中教的快速排序算法,然后复制了一下(自己只知道原理但是代码实现还是有点困难),最后排序完成,成功解决最难的一步,排好序就好算多了。
若有问题,希望大佬指导一下!

#include <stdio.h>
#include <string.h>


void quick_sort(char array[], int left, int right);

void quick_sort(char array[], int left, int right)
{
        int i = left, j = right;
        char temp;
        char pivot;
        strcpy(pivot, array[((left + right) / 2)]);

        // 基准点设置为中间元素,你也可以选择其它元素作为基准点
       

        while (i <= j)
        {
                // 找到左边大于等于基准点的元素
                while (strcmp(array, pivot) < 0)
                {
                        i++;
                }
                // 找到右边小于等于基准点的元素
                while (strcmp(array, pivot) > 0)
                {
                        j--;
                }
                // 如果左边下标小于右边,则互换元素
                if (i <= j)
                {
                        strcpy(temp, array);
                        strcpy(array, array);
                        strcpy(array, temp);
               
                       
                        i++;
                        j--;
                }
        }

        if (left < j)
        {
                quick_sort(array, left, j);
        }

        if (i < right)
        {
                quick_sort(array, i, right);
        }

}



int main()
{
        FILE *fp;
        fp = fopen("names.txt", "r");
       
        char ch, name;
        int i = 0, j = 0, k, sum = 0;
       
        while (!feof(fp))//将文件中名字写入字符串数组name中
        {
                ch = fgetc(fp);

                if (ch == '"')
                {
                        j = 0;
                        goto Label;
                }
                if (ch == '\n')
                {
                        goto Label;
                }
                else
                {
                        if (ch == ',')
                        {
                                i++;
                        }
                        else
                        {
                                name = ch;
                                name = '\0';
                                j++;
                        }
                }
        Label:continue;
        }
        fclose(fp);
        k = i - 1;
        quick_sort(name, 0, k);
       
        for (i = 0; i <= k; i++)
        {
                for (j = 0; name != '\0'; j++)
                {
                        sum += (name - 64) * (i + 1);
                }
        }

        printf("%d", sum);
        return 0;
}

答案:871198282;
秒出的;

ft215378 发表于 2021-10-15 14:58:59

#文件中所有名字的得分之和
with open("C:\\Users\\Administrator\\Desktop\\names.txt") as f:
    s = f.read()
s = s.split(',')
s.sort()
d = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, \
   'F': 6, 'G': 7, 'H': 8, 'I': 9, 'J': 10, \
   'K': 11, 'L': 12, 'M': 13, 'N': 14, 'O': 15, \
   'P': 16, 'Q': 17, 'R': 18, 'S': 19, 'T': 20, \
   'U': 21, 'V': 22, 'W': 23, 'X': 24, 'Y': 25, 'Z': 26}
each_name_letter = 0
each_name_score = 0
name_score = 0
i = 0
while True:
    for j in s:
      if j != '"':
            each_name_letter += d
    each_name_score = each_name_letter * (i+1)
    name_score += each_name_score
    i += 1
    each_name_letter = 0
    each_name_score = 0
    if i == len(s):
      break
print(name_score)
页: [1] 2
查看完整版本: 题目22:文件中所有名字的得分之和是多少?