名字分数测试

时间:2018-07-04 20:57:12

标签: c#

我的代码旨在计算姓名分数测试,但是我无法应用以下规则来获得满分。

规则:

  • 字母的首次出现会奖励该字母的正常分数。

  • 第二次出现字母只会奖励四舍五入的分数。

  • 第三次出现字母将获得双倍积分。

  • 字母的任何其他出现均不得分。
  • 如果一个字母在字符串中相邻出现两次,则两个字母的正常分数加倍。

    namespace NameScoreTest
    {
    using System;
    using System.Collections.Generic;
    
    public static class Program
    {
        private static Dictionary<char, int> Letters = new Dictionary<char, int>(){
                {'A', 1}, {'B', 3}, {'C', 3}, {'D', 2}, {'E', 1}, {'F', 4}, {'G', 2}, {'H', 4}, {'I', 1}, {'J', 8}, {'K', 5}, {'L', 1}, {'M', 3 }, {'N', 1}, {'O', 1}, {'P', 3}, {'Q', 10 }, {'R', 1}, {'S', 1}, {'T', 1}, {'U',1}, {'V', 4}, {'W', 4}, {'X', 8}, {'Y', 4}, {'Z', 10}
            };
    
        static void Main(string[] args)
        {
            int score = CalculateScore("Thomas");
    
            Console.WriteLine("Score for name Thomas is " + score);
            Console.WriteLine("Press any key to exit");
    
            Console.ReadKey();            
        }
    
        public static int CalculateScore(String input)
        {
            // The score
            int score = 0;
    
    
    
        foreach (char c in input)
    
        {
            char o = Char.ToUpper(c);
    
                foreach (var item in Letters)
                {
                 // Must apply rules here
                    if(o == item.Key)   
                    {
                        score += item.Value;
    
                    }
                }
    }
    
    
            return score;
        }
    }
    }
    

3 个答案:

答案 0 :(得分:1)

对于每个字母,必须存储出现的次数。为此,您需要创建一个包含值和出现的类。

class LetterInfo
{
    public LetterInfo(int value)
    {
        Value = value;
    }

    public int Value { get; }
    public int Occurrence{ get; set; }
}

现在您可以使用来初始化字典

private static Dictionary<char, LetterInfo> Letters = new Dictionary<char, LetterInfo>(){
        ['A'] = new LetterInfo(1),
        ['B'] = new LetterInfo(3),
        ['C'] = new LetterInfo(3),
        ['D'] = new LetterInfo(2),
        ['E'] = new LetterInfo(1),
        ['F'] = new LetterInfo(4),
        ['G'] = new LetterInfo(2),
        ['H'] = new LetterInfo(4),
        ['I'] = new LetterInfo(1),
        ['J'] = new LetterInfo(8),
        ['K'] = new LetterInfo(5),
        ['L'] = new LetterInfo(1),
        ['M'] = new LetterInfo(3),
        ['N'] = new LetterInfo(1),
        ['O'] = new LetterInfo(1),
        ['P'] = new LetterInfo(3),
        ['Q'] = new LetterInfo(10),
        ['R'] = new LetterInfo(1),
        ['S'] = new LetterInfo(1),
        ['T'] = new LetterInfo(1),
        ['U'] = new LetterInfo(1),
        ['V'] = new LetterInfo(4),
        ['W'] = new LetterInfo(4),
        ['X'] = new LetterInfo(8),
        ['Y'] = new LetterInfo(4),
        ['Z'] = new LetterInfo(10)
};

然后逻辑就这样

int score = 0;
int lastPoints = 0;
char lastLetter = (char)0;
foreach (char c in input) {
    char o = Char.ToUpper(c);
    if (Letters.TryGetValue(o, out var info)) {
        info.Occurrence++; // Keep track of the occurrence.
        if (o == lastLetter) {
            score += -lastPoints + 4 * info.Points; // Subtract points for last letter
                                                    // then add double points for both.
            lastPoints =  2 * info.Points;
        } else {
            switch (info.Occurrence) {
                case 1:
                    lastPoints = info.Points;
                    break;
                case 2:
                    lastPoints = (info.Points + 1) / 2;
                    break;
                case 3:
                    lastPoints = 2 * info.Points;
                    break;
                default:
                    lastPoints = 0;
                    break;
            }
            score += lastPoints;
        }
        lastLetter = o;
    }
}

请注意,该代码会记住最后一个字母以及添加到该字母分数中的分数。如果当前字母与最后一个字母相同,则将删除在该字母的最后一个循环中先前计算的点,因为最后一个规则适用于该字母。然后,两个点都加了两倍(即正常点的4倍)。

  

托马斯-> 11
  Emanuelle-> 14有趣,因为您遇到了3次E和两次L


存储点和事件的另一种方法是将它们存储在数组中,并使用字符代码作为索引。在C#中,您可以在char上执行整数算术运算。索引是用int index = o - 'A';计算的,即o == 'A'的索引是0

private static int[] Points = new int[26] { 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3,
                                            10, 1, 1, 1, 1, 4, 4, 8, 4, 10 };

实现基本相同,我们不需要额外的类。

int score = 0;
int lastPoints = 0;
char lastLetter = (char)0;
int[] occurrences = new int[26];
foreach (char c in input) {
    char o = Char.ToUpper(c);
    if ('A' <= o  && o <='Z') {
        int index = o - 'A';
        occurrences[index]++;
        int points = Points[index];
        if (o == lastLetter) {
            score += -lastPoints + 4 * points;
            lastPoints = 2 * points;
        } else {
            switch (occurrences[index]) {
                case 1:
                    lastPoints = points;
                    break;
                case 2:
                    lastPoints = (points + 1) / 2;
                    break;
                case 3:
                    lastPoints = 2 * points;
                    break;
                default:
                    lastPoints = 0;
                    break;
            }
            score += lastPoints;
        }
        lastLetter = o;
    }
}

答案 1 :(得分:0)

您可以使用另一本词典来保存每个字符及其出现次数,然后基于该字符计算点。

Dictionary<char, int> Letters2 = new Dictionary<char, int>() ;
foreach (char c in input)
{
    char o = Char.ToUpper(c);
    int countofoccur = input.Split(o).Length - 1;
    Letters2.Add(o, countofoccur);
}

或使用linq:

Letters2.Add(o, input.Count(x => x == o));

对于点也许不是完美的方法,但是您可以使用switch语句,并且得分必须是double,请将其添加到先前的foreach的末行:

double score = 0;
Dictionary<char, double> Letters3 = new  Dictionary<char, double>();
foreach(var c2 in Letters)
{
    if (o == c2.Key)
    {
        switch(countofoccur)
        {
            case 1:
                score = c2.Value;
                Letters3.Add(o, score);
                break;
            case 2:
                score = c2.Value+ (0.5 * c2.Value);
                Letters3.Add(o, score);
                break;

            case 3:
                score = c2.Value + (0.5 * c2.Value) +2*c2.Value;
                Letters3.Add(o, score);
                break;
            default :  
            break;  
        }
    }
}

答案 2 :(得分:0)

在这里,您可以使用其他字典来存储事件。我已经测试了几个例子:

public static class Program
{
    private static Dictionary<char, int> Letters = new Dictionary<char, int>(){
            {'A', 1}, {'B', 3}, {'C', 3}, {'D', 2}, {'E', 1}, {'F', 4}, {'G', 2}, {'H', 4}, {'I', 1}, {'J', 8}, {'K', 5}, {'L', 1}, {'M', 3 }, {'N', 1}, {'O', 1}, {'P', 3}, {'Q', 10 }, {'R', 1}, {'S', 1}, {'T', 1}, {'U',1}, {'V', 4}, {'W', 4}, {'X', 8}, {'Y', 4}, {'Z', 10}
        };
    private static Dictionary<char, int> occurences = new Dictionary<char, int>();

    private static char previous = ' ';

    static void Main(string[] args)
    {
        int score = CalculateScore("Thomas");

        Console.WriteLine("Score for name Thomas is " + score);
        Console.WriteLine("Press any key to exit");

        Console.ReadKey();            
    }

    public static int CalculateScore(String input)
    {
     // The score
     int score = 0;
     foreach (char c in input)
     {
        char o = Char.ToUpper(c);

        if (occurences.ContainsKey(o))
        {
           occurences[o] += 1;
           if (occurences[o] == 2)
           {
              if (o == previous)
              {
               score += 3 * letters[o]; //if second letter, than previously was added normal value, thus we add triple value to get to double value for both letters
              }
              else
              {
                  score += (int) Math.Ceiling(1.0 * letters[o] / 2);
              }
           }
           else if (occurences[o] == 3)
            {
               if (o == previous)
               {
                  score -= (int) Math.Ceiling(1.0 * letters[o] / 2); //subtracts previously added score for the letter (half of normal value)
                  score += 4 * letters[o]; //adds double value for 2 letters, thus equals 4
                }
                else
                {
                   score += 2 * letters[o];
                }
            }
            else if (o == previous)
            {
               score += 2 * letters[o];
            }
          }
          else
          {
             occurences[o] = 1;
             score += letters[o];
          }
          previous = o;
          Console.WriteLine(score + " " + o);
       }
       return score;
    }
}