将月份转换为数字以用于排序算法 - 可能的数组限制?

时间:2017-04-24 00:06:00

标签: c# arrays algorithm sorting

作为我为其中一个作业创建的程序的一部分,有一个带有月份列表的文本文件(准确地说是600个),这些文件必须按时间顺序排序,而不需要内置的排序方法。我没有问题导入月份并将它们转换为数字,但输出数字数组的内容只输出数字6,11和12才输出0。我认为这可能是数组大小的限制,但它并不能解释为什么只输出3个数字。

代码:

static void Main(string[]args){
    Console.WriteLine("Unsorted Array:");
    string[] monArray = File.ReadAllLines("Month_1.txt");
    int[] numArray = new int[12] {1,2,3,4,5,6,7,8,9,10,11,12};
    int[] monthNums = new int[monArray.Length];
    int counter = 0;
    for (int i = 0; i < monArray.Length; i++){Console.WriteLine(monArray[i]);}
    foreach (string month in monArray){
        switch (month){
            case "January":
            monthNums[counter] = numArray[1];
            counter++;
            break;
            case "February":
            monthNums[counter] = numArray[2];
            counter++;
            break;
            case "March":
            monthNums[counter] = numArray[3];
            counter++;
            break;
            case "April":
            monthNums[counter] = numArray[4];
            counter++;
            break;
            case "May":
            monthNums[counter] = numArray[5];
            counter++;
            break;
            case "June":
            monthNums[counter] = numArray[6];
            counter++;
            break;
            case "July":
            monthNums[counter] = numArray[7];
            counter++;
            break;
            case "August":
            monthNums[counter] = numArray[8];
            counter++;
            break;
            case "September":
            monthNums[counter] = numArray[9];
            counter++;
            break;
            case "October":
            monthNums[counter] = numArray[10];
            counter++;
            break;
            case "November":
            monthNums[counter] = numArray[11];
            counter++;
            break;
            case "December":
            monthNums[counter] = numArray[12];
            counter++;
            break;
        }
        for (int i = 0; i < monthNums.Length; i++){Console.WriteLine(monthNums[i]);}
    }

2 个答案:

答案 0 :(得分:0)

问题在于,您要将.table-body { max-height: 200px; overflow-y:auto; } .t-row { display: flex; border-bottom: 1px solid grey; } .t-row:nth-child(even){ background: #e3e3e3; } .col { word-wrap: break-word; flex: 1 0 30%; max-width: 33.3333%; } .cell { padding: 8px; } <div class="table-wrap"> <div class="t-row t-header"> <div class="col"> <div class="cell"> Header 1 </div> </div> <div class="col"> <div class="cell"> Header 1 </div> </div> <div class="col"> <div class="cell"> Header 1 </div> </div> </div> <div class="table-body"> <div class="t-row"> <div class="col"> <div class="cell"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. </div> </div> <div class="col"> <div class="cell"> 1111 </div> </div> <div class="col"> <div class="cell"> 11111111 </div> </div> </div> </div> </div> 分配给相应monthNums[counter]中的值,并且每次迭代都会递增numArray,因此会增加600次。

我认为您真正想要做的是查找要从counter更新的月份索引,然后在numArray中添加一个该项的值,这可以使用monthNums运营商。

另外,请记住,数组基于++,这意味着索引0中的第一个项目。您的[0]数组包含monthNums项,即12 - 0索引。

11

此外,由于// Initialize the array starting at '0', not '1'... int[] numArray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // For any given month string, look up it's corresponding index in numArray // And use that value for the index to increment the count in monthNums switch (month) { case "January": monthNums[numArray[0]]++; break; case "February": monthNums[numArray[1]]++; break; case "March": monthNums[numArray[2]]++; break; // continue this pattern... } 中每个项目的值都是索引,因此您实际上不需要此数组 - 您只需要numArray ...

monthNums

更好的解决方案可能是为月份创建switch (month) { case "January": monthNums[0]++; break; case "February": monthNums[1]++; break; case "March": monthNums[2]++; break; // Continue this pattern ... } ,其中每个月的值对应于您要更新的索引,然后您可以使用enum来获取索引。默认情况下,枚举中的第一个项目为enum.TryParse,后面的每个项目增加0,因此我们无需在枚举中明确指定任何值。

枚举看起来像:

1

然后你可以像这样解析它:

enum Month
{
    January, February, March, April, May, June, July,
    August, September, October, November, December
}

这是一个程序的工作示例,该程序使用600个随机月份名称填充数组(以模拟您的文件),然后使用每个月的计数更新第二个数组,最后输出结果:

foreach (string month in monArray)
{
    Month convertedMonth;

    // If the value of 'month' from our string array can be converted to a Month, 
    // update the count in the corresponding array index
    if (Enum.TryParse(month, true, out convertedMonth))
    {
        monthNums[(int)convertedMonth]++;
    }
}

输出:

enter image description here

只需将字符串转换为月份,以下private static void Main() { // Populate our 'file' with 600 random month names: var rnd = new Random(); var monArray = new string[600]; for (int i = 0; i < 600; i++) { monArray[i] = ((Month) rnd.Next(0, 12)).ToString(); } // The array to hold counts for each month int[] monthNums = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Read each string, if it converts to a month, increment our counter foreach (string month in monArray) { Month convertedMonth; if (Enum.TryParse(month, true, out convertedMonth)) { monthNums[(int) convertedMonth]++; } } // Output the counts for each month for (int i = 0; i < monthNums.Length; i++) { Console.WriteLine($"{(Month) i} count: {monthNums[i]}"); } Console.Write("\nDone!\nPress any key to exit..."); Console.ReadKey(); } 和方法就可以解决问题:

enum

答案 1 :(得分:0)

我不知道你究竟在尝试什么,但似乎是这样:

  1. 一次读一个月,一行,并将它们转换为数字。
    1. 这些数字应方便地映射到数组的插槽1 - 12
    2. 因此,存储它们在此数组中出现次数的次数
  2. 现在按顺序读取计数数组(即排序顺序),并希望将计数与订单一起传达给输出。
  3. 我会从你正在做的事情中避免一些事情。

    1. 保持您的编码可扩展性
      1. 不同的区域设置(非格里历日历)(如果适用)
      2. 处理不区分大小写的输入
      3. 处理短月份名称而不是完整月份名称。
    2. 不要使用案例陈述。请尝试使用if语句或Dictionary根据上述答案进行处理。
    3. 我对您使用monthNumsnumArray所做的事情感到非常困惑。我认为numArray可能是多余的。
    4. 下面是我编写猜测一些要求并试图坚持你的想法的代码。

      static string[] MonthNames = new string[12]; // store the names of the month as found in the file to print out later
      
      static int GetMonthNumber(string month) {
          // Accommodating short month names and case sensitivity
          // TODO: handle locale issues for case and month names, if applicable
          var lowerMonth = month.ToLower();
          int value;
          if (lowerMonth.StartsWith("jan"))
              value = 0;
          else if (lowerMonth.StartsWith("feb"))
              value = 1;
          else if (lowerMonth.StartsWith("mar"))
              value = 2;
          else if (lowerMonth.StartsWith("apr"))
              value = 3;
          else if (lowerMonth.StartsWith("may"))
              value = 4;
          else if (lowerMonth.StartsWith("jun"))
              value = 5;
          else if (lowerMonth.StartsWith("jul"))
              value = 6;
          else if (lowerMonth.StartsWith("aug"))
              value = 7;
          else if (lowerMonth.StartsWith("sep"))
              value = 8;
          else if (lowerMonth.StartsWith("oct"))
              value = 9;
          else if (lowerMonth.StartsWith("nov"))
              value = 10;
          else if (lowerMonth.StartsWith("dec"))
              value = 11;
          else
              throw new ArgumentException($"Unknown month: {lowerMonth}", nameof(lowerMonth));
      
          MonthNames[value] = month;
      
          return value;
      }
      
      static void Main(string[] args) {
          Console.WriteLine("Unsorted Array:");
      
          string[] monArray = File.ReadAllLines("Month_1.txt"); /*new string[] { "January", "March", "January", "sept" };*/
      
          int[] monthNums = new int[11];
      
          for (int i = 0; i < monArray.Length; i++)
              Console.WriteLine(monArray[i]);
      
          foreach (string month in monArray)
              monthNums[GetMonthNumber(month)]++;
      
          for (int i = 0; i < monthNums.Length; i++) {
              if (monthNums[i] != 0)
                  Console.WriteLine($"{MonthNames[i],-10} : ({monthNums[i]} times)");
          }
      
      }