【问题标题】:C# Add counter for each number in loopC#为循环中的每个数字添加计数器
【发布时间】:2015-09-24 16:35:37
【问题描述】:

我正在编写一个程序,它将用户数据值 1-10 存储到一个数组中。我试图弄清楚如何添加一个计数器,让我可以输出每个数字被输入了多少次以及输入了多少无效数字。

    class Program
{
    static void Main(string[] args)
    {
        int[] data = GetData();
    }

    private static int[] GetData()
    {
        int[] dataArray = new int[100];
        int n = 0;
        int intValue = 0;

        while (true)
        {
            Console.WriteLine("Enter a number 0-10 (Q to end)");
            string lineValue = Console.ReadLine();

            if (lineValue.ToLower().Trim().Equals("q"))
            {
                break;
            }

            if (!int.TryParse(lineValue, out intValue))
            {
                Console.WriteLine("INVALID DATA - Try again.");
                continue;
            }

            if (intValue < 0 || intValue > 10)
            {
                Console.WriteLine("NUMERIC DATA OUT OF RANGE - Try again.");
                continue;
            }

            dataArray[++n] = intValue;
            dataArray[0] = n;
        }
        return dataArray;
    }
}

【问题讨论】:

  • 我猜反对票是因为您必须非常努力地寻找实际问题。如果您编辑问题以更清楚地说明您到底遇到了什么问题,希望他们能收回反对票(甚至可能投票)。

标签: c# counter


【解决方案1】:

您可以在while 条件之前为无效号码设置一个计数器。

int invalidNumbersCounter = 0;

然后你可以在每次输入无效时增加这个计数器:

if (!int.TryParse(lineValue, out intValue))
{
    Console.WriteLine("INVALID DATA - Try again.");
    invalidNumbersCounter++;  
    continue;
}

关于您的其他问题,每个数字有多少次,您可以使用普通 LINQ 来解决问题。

static void Main(string[] args)
{
    int[] data = GetData();

    var statistics = data.GroupBy(x=>x)
                         .Select(gr => new 
                         { 
                             Number = gr.key, 
                             Times = gr.Count() 
                         });

    foreach(var statistic in statistics)
    {
        Console.WriteLine(String.Format("The number {0} found {1} times in you array", statistic.Number, statistic.Times));
    }
}

上述查询的结果将是一个匿名类型的对象序列,具有两个属性,即数字和该数字在数组中的数字。

更新

为了避免计算用户未输入的值并且本质上是数组的初始值,我们可以在创建数组时将数组的值初始化为 -1,如下所示:

int[] dataArray = Enumerable.Repeat(-1, 100).ToArray();

然后我们必须将我们的 linq 查询更新为以下查询:

 var statistics = data.Skip(1)
                      .Where(number => number!=-1)
                      .GroupBy(x=>x)
                      .Select(gr => new 
                      { 
                          Number = gr.key, 
                          Times = gr.Count() 
                      });

【讨论】:

  • 空槽也存在问题(我会在 GroupBy 之前添加一个 Where 来删除它们)。但这就是我的想法。 (并且 data[0] 的值也应该被排除在计数之外)
  • 您好史蒂夫,感谢您的评论。我有一个问题。由于data 将是一个整数数组,那么空槽在哪里?肯定有一些我没有正确捕捉到的东西。
  • @Christos 我猜是因为他将他的int 数组初始化为 100。如果你只输入 2 个数字,那么数组中会有 98 个单独的 0 对吗?
  • @Kritner 我明白你的推理,但如果有人输入 0,这将是一个有效的输入,除非我没有正确理解它。
  • @Christos dotnetfiddle.net/vCH1r6 这就是我的意思。如果您运行应用程序并输入“1”然后输入“q”,它将列出 1 列出一次,列出 0 99 次 - 即使用户从未输入过 0 一次。
【解决方案2】:

你可以这样做:

public class Program
{
    public static void Main(string[] args)
    {
        // note updated to use a list rather than array (just preference)
        List<int> data = GetData();         
    }

    private static List<int> GetData()
    {
        List<int> list = new List<int>();
        int intValue = 0;
        int invalidAttempts = 0; // added to keep track of invalid values

        while (true)
        {
            Console.WriteLine("Enter a number 0-10 (Q to end)");
            string lineValue = Console.ReadLine();

            if (lineValue.ToLower().Trim().Equals("q"))
            {
                break;
            }

            if (!int.TryParse(lineValue, out intValue))
            {
                Console.WriteLine("INVALID DATA - Try again.");
                invalidAttempts++;
                continue;
            }

            if (intValue < 0 || intValue > 10)
            {
                Console.WriteLine("NUMERIC DATA OUT OF RANGE - Try again.");
                invalidAttempts++;
                continue;
            }

            list.Add(intValue);
        }

        Console.WriteLine("Invalid attempts {0}", invalidAttempts);

        // this is using linq to group by the individual numbers (keys),
        // then creates an anon object for each key value and the number of times it occurs.
        // Create new anon object numbersAndCounts
        var numbersAndCounts = list
            // groups by the individual numbers in the list
            .GroupBy(gb => gb)
            // selects into a new anon object consisting of a "Number" and "Count" property
            .Select(s => new {
                Number = s.Key,
                Count = s.Count()
            });

        foreach (var item in numbersAndCounts)
        {
            Console.WriteLine("{0} occurred {1} times", item.Number, item.Count);
        }

        return list;
    }
}

请注意,我使用的是 list 而不是 array,我发现它们更易于使用。

工作演示:

https://dotnetfiddle.net/KFz1UY

是否可以按数字顺序输出?现在它只显示首先输入的任何数字。比如 1, 7, 7, 4 就是 1:1 7:2 4:1,怎么改成 1:1 4:1 7:2?

当然可以!见下文(和更新的原始演示)

我刚换了:

    var numbersAndCounts = list
        .GroupBy(gb => gb)
        .Select(s => new {
            Number = s.Key,
            Count = s.Count()
        });

到:

    var numbersAndCounts = list
        .GroupBy(gb => gb)
        .Select(s => new {
            Number = s.Key,
            Count = s.Count()
        })
        .OrderBy(ob => ob.Number);

【讨论】:

  • 谢谢。这完全符合我的要求,但是我对您使用的 linq 技术不太熟悉。
  • 如果您不熟悉 LINQ,那真是太棒了。这是一个开始:msdn.microsoft.com/en-us/library/bb397933.aspx
  • 是否可以按数字顺序输出?现在它只显示首先输入的任何数字。比如 1, 7, 7, 4 会是 1:1 7:2 4:1,我怎样才能把这个改成 1:1 4:1 7:2?
  • 当然,你可以这样做。你只需要一个OrderBy(gb=&gt;gb.Key) 子句。请将此子句放在GroupBy 之后和投影之前,Select
【解决方案3】:

您已经有一个计数器 (n) 示例,您可以将其用作示例来记录无效输入的数量。只需在这个 if 块内增加它:

if (intValue < 0 || intValue > 10)
        {
            Console.WriteLine("NUMERIC DATA OUT OF RANGE - Try again.");
            myInvalidCounter ++;
            continue;
        }

要计算输入的每个数字 - 您可以分析存储在 dataArray 中的数据。

编辑:我刚刚注意到您有两个无效数据示例 - 错误的原始数据和超出范围的数据 - 您需要根据需要设置计数器 - 可能每个一个或一个共享一个等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多