C# 字符串C的桶排序问题#

C# 字符串C的桶排序问题#,c#,arrays,sorting,bucket-sort,C#,Arrays,Sorting,Bucket Sort,我正在编写一个程序,该程序接收学生信息的数据,包括学生ID#字段、学生名字字段和学生姓氏字段。用户将为每个学生(最多20名学生)输入数据,或者直到用户为学生ID字段输入“999”。接下来,我想根据姓氏字段将学生信息分为两个单独的桶 我有一个水桶正确分离的问题。我将使用CompareTo方法来比较student last name数组的姓氏字符串,但当我打印存储桶时,它们是混淆的。例如,以A-K开头的姓氏应进入“低值”存储区,以J-Z开头的姓氏应进入“高值”存储区 using System

我正在编写一个程序,该程序接收学生信息的数据,包括学生ID#字段、学生名字字段和学生姓氏字段。用户将为每个学生(最多20名学生)输入数据,或者直到用户为学生ID字段输入“999”。接下来,我想根据姓氏字段将学生信息分为两个单独的桶

我有一个水桶正确分离的问题。我将使用CompareTo方法来比较student last name数组的姓氏字符串,但当我打印存储桶时,它们是混淆的。例如,以A-K开头的姓氏应进入“低值”存储区,以J-Z开头的姓氏应进入“高值”存储区

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace _123_Assignment2
    {
    using System;
    using static System.Console;
    class Program
    {
    struct student
    {
        public int studentId;
        public string firstName;
        public string lastName;
    };

    static void Main(string[] args)
    {
        student[] studentInfo = new student[20];
        string[] bucketLow = new string[20];
        string[] bucketHigh = new string [20];
        int x = 0;
        int y = 0;
        int z = 1;



        WriteLine("Enter student ID number:");
        studentInfo[x].studentId = Convert.ToInt32(ReadLine());

        while (studentInfo[x].studentId != 999)
        {
            WriteLine("Enter first name:");
            studentInfo[x].firstName = ReadLine();
            WriteLine("Enter last name:");
            studentInfo[x].lastName = ReadLine();
            x++;
            WriteLine("Enter student ID number:");
            studentInfo[x].studentId = Convert.ToInt32(ReadLine());
        }


        for (int j = 0; j < x; j++)
        {

      if(studentInfo[j].lastName.CompareTo(studentInfo[z].lastName)<= 0)

                bucketLow[y] = studentInfo[j].lastName;
            else
                bucketHigh[y] = studentInfo[j].lastName;

                y++;
                z++;
        }

        WriteLine("Unsorted Table:");
        for (int j = 0; j < studentInfo.Length; j++)
        {

       WriteLine("{0}{1}{2}",studentInfo[j].studentId,studentInfo[j].firstName,
       studentInfo[j].lastName);
        }
        WriteLine("Bucket 1:");
        for (int j = 0; j < x; j++)
        {
            WriteLine(bucketLow[j]);
        }
        WriteLine("Bucket 2:");
       for (int j = 0; j < x; j++)
        {
            WriteLine(bucketHigh[j]);
       }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间_123_赋值2
{
使用制度;
使用静态系统控制台;
班级计划
{
结构学生
{
公共int学生;
公共字符串名;
公共字符串lastName;
};
静态void Main(字符串[]参数)
{
学生[]学生信息=新学生[20];
字符串[]bucketLow=新字符串[20];
字符串[]bucketHigh=新字符串[20];
int x=0;
int y=0;
intz=1;
WriteLine(“输入学生ID号:”);
studentInfo[x].studentId=Convert.ToInt32(ReadLine());
while(studentInfo[x].studentId!=999)
{
WriteLine(“输入名字:”);
studentInfo[x].firstName=ReadLine();
WriteLine(“输入姓氏:”);
studentInfo[x]。lastName=ReadLine();
x++;
WriteLine(“输入学生ID号:”);
studentInfo[x].studentId=Convert.ToInt32(ReadLine());
}
对于(int j=0;j如果(studentInfo[j].lastName.CompareTo(studentInfo[z].lastName)因为这似乎是家庭作业,我将避免为您实际编写正确的代码。但至少您存在一些问题:

  • 为了直接解决您的问题,您必须对数组元素进行排序的代码使用了错误的比较。如果您有两个桶,并且希望其中一个桶表示从
    A
    K
    的姓氏,另一个桶表示从
    L
    Z
    的姓氏,则需要比较to
    K
    L
    来确定正确的存储桶。与其他名称进行比较只会使数据随机化。类似于
    string.Compare(studentInfo[j]。lastName,“L”,StringComparison.CurrentCultureIgnoreCase)的方法应该可以工作<0
  • 您需要维护两个索引,每个bucket一个,并且如果您实际将学生记录复制到该bucket中,则只增加该bucket的索引
  • 如果您实际尝试输入20名学生的数据,您当前的代码将因
    IndexOutOfRangeException
    而崩溃,因为您递增
    x
    并将ID值存储到数组中,而不检查是否输入了20名学生的数据。输入20名学生后,即使用户输入
     999
    while
    条件将不会检查该值,直到为时已晚且代码已尝试将该值存储到数组中
  • 可能还有其他问题;这些是我第一眼看到的问题


    作为将来的参考,在这里询问有关堆栈溢出的问题时,您应该确保您提供了一个良好的解决方案。您很接近,至少代码是完整的。但不要让其他用户输入您的测试数据。编写一个单独的程序,其中包含所有内置数据,没有用户提示,也不会执行任何不严格要求的操作需要重现您的问题。

    我认为您的排序不起作用(j和z比较):


    studentInfo[j].lastName.CompareTo(studentInfo[z].lastName)

    如果你必须使用一个结构和数组,那么你可以考虑下面的代码来把名字分成适当的桶。正如我所说的,你需要两个索引,每个桶都有一个索引。因为你把数组的大小固定到20,如果输出结果小于20,就会有空行。

    x = studentInfo.Length;
    int lowIndex = 0;
    int highIndex = 0;
    
    for (int j = 0; j < x; j++) {
      if (String.CompareOrdinal(studentInfo[j].lastName, "L") < 0) {
        bucketLow[lowIndex] = studentInfo[j].lastName;
        lowIndex++;
      } else {
        bucketHigh[highIndex] = studentInfo[j].lastName;
        highIndex++;
      }
    }
    
    x=学生信息长度;
    int低指数=0;
    int-highIndex=0;
    对于(int j=0;j
    以及答案中的好建议。您是否考虑过将
    学生
    设置为一个类,并使用列表而不是数组?这可能会使事情变得更简单。它需要使用具有三个数组的结构。如果是这种情况,那么您应该跟踪将名称分离到存储桶中的代码。使用相同的索引“y”'对于两个存储桶,将在两个存储桶中创建间隙。您将需要两个索引,一个用于低存储桶,一个用于高存储桶。谢谢,我在输出中获得间隙,并创建了两个索引以消除该问题。谢谢,我不知道我可以与那样的设置字符进行比较。这就是我正在寻找的,它让我处于正确位置现在跟踪并给我想要的输出,谢谢!谢谢你的反馈,我将实施你的建议,我感谢你的输入。
    for (int j = 0; j < x; j++)
    {
      if(studentInfo[j].lastName.CompareTo(studentInfo[z].lastName)<= 0)
          bucketLow[y] = studentInfo[j].lastName;
       else
          bucketHigh[y] = studentInfo[j].lastName;
          y++;
          z++;
       }
    }
    
    for (var i = 0; i < studentInfo.Length; i++)
    {
       if (studentInfo[i].lastName[0] <= 'K')
          bucketLow[y] = studentInfo[i].lastName;
       else
          bucketHigh[y] = studentInfo[i].lastName;
    
       y++;
    }
    
    x = studentInfo.Length;
    int lowIndex = 0;
    int highIndex = 0;
    
    for (int j = 0; j < x; j++) {
      if (String.CompareOrdinal(studentInfo[j].lastName, "L") < 0) {
        bucketLow[lowIndex] = studentInfo[j].lastName;
        lowIndex++;
      } else {
        bucketHigh[highIndex] = studentInfo[j].lastName;
        highIndex++;
      }
    }