在检查字符串字母的基础上需要帮助返回点

时间:2019-06-07 01:22:48

标签: c# unit-testing

我正在尝试根据给定的测试用例检查字符串是否具有字母。但是,字母 a 有一个例外,a的每个字母将被视为价值的一半。例如,字母 a 的价值为300,但是我们想除以2,每个字母的价值为150分。

UnitTest:

[TestCase("software", 'w', 250, 250)]
[TestCase("craftmanship", 'a', 300, 300)]
public void WheelofFortune(string secretWord, char letterGuess, int pointValue, int expected)
    {
        var actual = warmups.WheelofFortune(secretWord, letterGuess, pointValue);
        Assert.AreEqual(expected, actual);
    }

单位:

//Given a target word, a letter guess by a customer, and a point value. 
//Return the number of points earned.

    public int WheelofFortune(string secretWord, char letterGuess, int pointValue)
    {
        int sum = 0;
        int pointValue2 = (pointValue / 2);

        for (int i = 0; i < secretWord.Length; i++)
        {
            if (secretWord[i] == letterGuess)
                sum += pointValue;

            if (secretWord[i] == letterGuess && letterGuess == 'a')
                sum += pointValue2;

            if (secretWord[i] == secretWord.Length - 1)
                return sum;
        }
        return sum;            
    }

问题出在工艺上: 讯息:预计:300 但是是:900

为什么我得到900而不是300?

3 个答案:

答案 0 :(得分:3)

Ben和Mrinal在代码中向您显示了直接的问题。我将重点放在代码的结构上。

从您的问题来看,听起来像您想要这样的东西:

  

给出一个单词,一个猜测字符和一个分数,将分数乘以匹配数   字符。如果猜测字符为'a',则得分为一半。

在这种情况下,代码可以大大简化为:

public int WheelofFortune(string secretWord, char letterGuess, int pointValue)
{
    int count = secretWord.Count(letter => letter == letterGuess);
    int sum = pointValue * count;
    if (letterGuess == 'a')
        sum /= 2;
    return sum;
}

这给出了您要测试的值,抽象了循环并读取了更多类似说明的内容。它还简化了逻辑,使您不太可能错过双打比赛。

不确定您的代码为什么要包含等于字符串长度减去一个字符的字符的测试,因为这似乎与问题无关。很高兴纠正是否需要。

答案 1 :(得分:1)

之所以会发生这种情况,是因为您的逻辑在简单的调试中不正确,这表明当您找到字母a时,两个逻辑都将执行,因此每次迭代的值将变为 450 ,因此 450 * 2 = 900

if (secretWord[i] == letterGuess)
                sum += pointValue;

 if (secretWord[i] == letterGuess && letterGuess == 'a')
                sum += pointValue2;

使用Switch-Case修复1:

public int WheelofFortune(string secretWord, char letterGuess, int pointValue)
{
    int sum = 0;

    for (int i = 0; i < secretWord.Length; i++)
    {
        switch(secretWord[i])
        {
            case 'a':
                sum += pointValue/2;
            break;
            default:
                if (secretWord[i] == letterGuess)
                  sum += pointValue;
            break;          
        }
    }
    return sum;
}

修正2:使用字典的更好设计(只需在字典中添加另一个键,它将自动根据新逻辑进行计算)

public static Dictionary<char,double> sampleData = new Dictionary<char, double>
{
    ['a'] = 0.5
};

public int WheelofFortune(string secretWord, char letterGuess, int pointValue)
{
    int sum = 0;

    for (int i = 0; i < secretWord.Length; i++)
        if(sampleData.ContainsKey(secretWord[i]))
            sum += (int)(pointValue * sampleData[letterGuess]);

    return sum;
}

答案 2 :(得分:0)

您正在同时执行两个if子句,所以:

if (secretWord[i] == letterGuess)
            sum += pointValue;

您两次匹配a,因此将2x300 = 600加到总和上。然后

if (secretWord[i] == letterGuess && letterGuess == 'a')
            sum += pointValue2;

这也匹配,因此您将总和加2 * 150 = 300。 600 + 300 = 900。

您需要使用if else或case语句。像这样:

    for (int i = 0; i < secretWord.Length; i++)
    {
        if (secretWord[i] == letterGuess && letterGuess == 'a')
        {
            sum += pointValue2;
        }
        else if (secretWord[i] == letterGuess)
        {
            sum += pointValue;
        }
        //if (secretWord[i] == secretWord.Length - 1)
        //{
        //    return sum;
        //}

    }

这样,一旦满足一个if子句,它将忽略其余子句。