【问题标题】:miscalculating average of sums计算错误的平均值
【发布时间】:2016-04-18 18:44:40
【问题描述】:

到目前为止,这是我的代码。我从 txt 文件中提取数据并写入具有平均年龄和经验的新文件。我没有得到正确的平均值。我的错在哪里?

class Program
{
    static int age, exp, id, ageSum = 0, expSum = 0, empSum = 0;
    static double avgAge, avgExp;
    static char type;
    const string INPUT_FILE_NAME =
    "\\Users\\Jon.Jon-PC\\Documents\\Visual Studio 2015\\Projects\\ConsoleApplication9\\ConsoleApplication9\\data.txt";
    const string OUTPUT_FILE_NAME =
    "\\Users\\Jon.Jon-PC\\Documents\\Visual Studio 2015\\Projects\\ConsoleApplication9\\ConsoleApplication9\\dataout.txt";
    static StreamReader fileIn;
    static StreamWriter fileOut;
    static string lineIn, eligibility;


    static void OpenFiles()
    {
        if (File.Exists(INPUT_FILE_NAME))
        {
            fileIn = File.OpenText(INPUT_FILE_NAME);
            Console.WriteLine("{0} was opened", INPUT_FILE_NAME);
        }
        else
        {
            Console.WriteLine("Error: {0} does not exit\n",
           INPUT_FILE_NAME);
            Environment.Exit(0);
        }
        fileOut = File.CreateText(OUTPUT_FILE_NAME);
        if (File.Exists(OUTPUT_FILE_NAME))
            Console.WriteLine("{0} was created\n",
          OUTPUT_FILE_NAME);
        else
        {
            Console.WriteLine("Error: {0} could not be created\n",
          OUTPUT_FILE_NAME);

            Environment.Exit(0);
        }
    }

    static void ParseLineIn()
    {
        string[] words = new string[4];

        lineIn = lineIn.Trim();
        while (Regex.IsMatch(lineIn, "[ ]{2}"))
            lineIn = lineIn.Replace("  ", " ");
        words = lineIn.Split(' ');
        id = int.Parse(words[0]);
        type = char.Parse(words[1]);
        age = int.Parse(words[2]);
        exp = int.Parse(words[3]);
    }

    static void UpdateTotals()
    {
        empSum++;
        ageSum += age;
        expSum += exp;
    }

    static void CalcAvg()
    {
        avgAge = ageSum / empSum;
        avgExp = expSum / empSum;
    }

    static void PrintAvg()
    {
        fileOut.Write("Avg\t  {0}  {1}", avgAge, avgExp);
    }

    static void CalcRetirement()
    {
        switch (type)
        {
            case 'm':
            case 'M':

                if (age < 55 && exp < 20)
                    eligibility = ("lack of experience age");
                else if (age >= 55 && exp >= 20)
                    eligibility = ("can retire");
                else if (age >= 55 && exp < 20)
                    eligibility = ("lack of experience");
                else if (age < 55 && exp >= 20)
                    eligibility = ("underage");
                else
                    eligibility = ("Your entry is invalid");
                break;

            case 'w':
            case 'W':

                if (age < 63 && exp < 25)
                    eligibility = ("lack of exp age");
                else if (age >= 63 && exp >= 25)
                    eligibility = ("can retire");
                else if (age >= 63 && exp < 25)
                    eligibility = ("lack of exp");
                else if (age < 63 && exp >= 25)
                    eligibility = ("lack age");
                else
                    eligibility = ("Your entry is invalid");
                break;

            case 's':
            case 'S':

                if (age < 60 && exp < 24)
                    eligibility = ("lack of exp age");
                else if (age >= 60 && exp >= 24)
                    eligibility = ("can retire");
                else if (age >= 60 && exp < 24)
                    eligibility = ("lack of exp");
                else if (age < 60 && exp >= 24)
                    eligibility = ("underage");
                else
                    eligibility = ("Your entry is invalid");
                break;
        }
    }

    static void CloseFiles()
    {
        fileIn.Close(); fileOut.Close();
    }


    static void PrintReportHeadings()
    {
        fileOut.WriteLine("          Employee Report               ");
        fileOut.WriteLine();
        fileOut.WriteLine(" ID  Age Exp Eligibility ");
        fileOut.WriteLine("---- --- --- ----------- ");
    }

    static void printDetailLine()
    {
        fileOut.WriteLine("{0}  {1}  {2} {3}", id, age, exp, eligibility);
    }

    static void Main(string[] args)
    {
        OpenFiles();
        PrintReportHeadings();
        while ((lineIn = fileIn.ReadLine()) != null)
        {
            UpdateTotals();
            ParseLineIn();
            CalcRetirement();
            printDetailLine();

        }
        CalcAvg();
        PrintAvg();
        CloseFiles();
    }
}

我对编码很陌生,所以除了本学期所学的内容外,我知道的不多。我正在提取的文件中的数据如下。我应该计算 A 和 E 列的平均值。

       A  E
1235 W 45 20
2536 W 55 21
5894 W 60 30
4597 W 75 35
2597 S 35 10
5689 S 40 20
5489 W 55 39
5872 M 60 40
5569 M 55 25
5566 W 80 20
8865 M 59 35
5598 S 65 35

我目前的输出低于..

          Employee Report               
 ID  Age Exp Eligibility 
---- --- --- ----------- 
1235  45  20 lack of exp age
2536  55  21 lack of exp age
5894  60  30 lack age
4597  75  35 can retire
2597  35  10 lack of exp age
5689  40  20 lack of exp age
5489  55  39 lack age
5872  60  40 can retire
5569  55  25 can retire
5566  80  20 lack of exp
8865  59  35 can retire
5598  65  35 can retire
Avg   51  24

平均值应该是 57.0 和 27.5 我错过了什么?

【问题讨论】:

  • 如果您在适当的时候打印empSum、ageSum 和expSum 的诊断信息,这可能有助于调试问题。整个程序的转储没有精简到重现问题而不引入噪音所必需的程度,这对其他人并不是非常友好。有趣的一件事...您打印的平均值对于 13 个数据点是整数正确的,并且您有 13 行输入和 12 个数据点。
  • 你想在UpdateTotals()之前调用ParseLineIn(),否则你不添加最后一个年龄。此外,无论该行是否具有年龄/exp 数据,您都将增加empSum(因此,如果文件具有标题或空行,即使它们没有添加到总和中,您也将其增加 1)。我觉得还有其他问题,但从那里开始..
  • 您正在划分ints,这将导致您的结果四舍五入 - 只需将对待empSum、ageSum 和expSum 声明为double,您将获得所需的结果.
  • 谢谢,将 int 换成双精度并修复。

标签: c# average


【解决方案1】:

在UpdateTotals() 方法中执行任何计算之前,您最初可能会增加empSum:

while ((lineIn = fileIn.ReadLine()) != null)
{
        UpdateTotals(); // Increments your `empSum` (even for the header row)
        ParseLineIn();
        CalcRetirement();
        printDetailLine();
}

这可能会导致您的平均值除以一个值 13,该值比您预期的 12 大一,这可以解释您当前的问题。在递增 empSum 之前,您可能需要明确检查此行中是否有任何员工数据。

【讨论】:

  • 这可能要简单得多 - 请参阅我关于划分 ints 的评论。
猜你喜欢
  • 1970-01-01
  • 2019-07-19
  • 1970-01-01
  • 2013-01-14
  • 1970-01-01
  • 2017-02-06
  • 2012-06-19
相关资源
最近更新 更多