19

希望有人可以提供帮助。我创建了一个可变长度数组,它将接受多个名称输入。我现在想按字母顺序对数组进行排序并将其返回到控制台屏幕。

我以为 Array.Sort(names); 会为我做这个,但我得到一个异常抛出。我一直在看笔记、示例和在线,但似乎没有什么与我正在做的事情相匹配。

到目前为止,我已经完成了以下操作。我差点把头发扯掉了!PS 我已经尝试解决这个问题好几个小时了,我已经 30 多岁了,正在努力学习自己,所以请不要只说“做你的功课”我已经尝试解决这个问题,但不能,所以我需要有人解释我哪里错了。这是一个星期天,我正在努力做额外的工作,但没有笔记可以准确地涵盖这一点

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

namespace Student_Array
{
    class Program
    {
        struct Student
        {
            public string Name;
        }

        static void Main(string[] args)
        {
            int numberOfStudents;
            Student[] names;
            string input;

            Console.WriteLine("How many students are there?");
            input = Console.ReadLine();
            numberOfStudents = int.Parse(input);

            names = new Student[numberOfStudents];


            for (int i = 0; i < names.Length; i++)
            {
                Student s;
                Console.WriteLine("Please enter student {0}'s name", (i + 1));
                s.Name = Console.ReadLine();
                names[i] = s;
            }
            ***Array.Sort<Student>(names);***
            for (int i = 0; i < names.Length; i++)
            {

                Console.WriteLine(names[i].Name);
            }
        }
    }
}
4

7 回答 7

38

这可以解决问题

Array.Sort(names, (x,y) => String.Compare(x.Name, y.Name));
于 2013-05-19T16:02:49.440 回答
7

您在这里的问题可能是您混淆了学生和姓名的概念。通过定义Student结构,您正在创建一个可以表示的不仅仅是名称的实体。例如,您可以将其扩展为包括AgeHometown等。(因此,命名数组可能students比命名数组更有意义names。)

struct Student
{
    public string Name;
    public int Age;
    public string Hometown;
}

考虑到多个字段的可能性,该Array.Sort方法需要知道您想要对列表进行排序。您希望学生按姓名、年龄或家乡排序吗?

根据 MSDN 文档Array.Sort<T>

Array使用IComparable<T>Array 的每个元素的通用接口实现对整体中的元素进行排序。

这意味着您尝试排序的类型 - 在您的情况下Student- 必须实现IComparable<T>接口,以便Array.Sort实现知道它应该如何比较两个Student实例。如果您确信学生将始终按名称排序,您可以像这样实现它:

struct Student : IComparable<Student>
{
    public string Name;
    public int Age;
    public string Hometown;

    public int CompareTo(Student other)
    {
        return String.Compare(this.Name, other.Name);
    }
}

或者,您可以提供一个函数,将排序键提取到排序方法本身。实现这一点的最简单方法是通过 LINQOrderBy方法:

names = names.OrderBy(s => s.Name).ToArray();
于 2013-05-19T16:01:24.227 回答
5

如果您扩展 Student 以实现 IComparable ,则可以Sort按原样使用;

    struct Student : IComparable<Student>
    {
        public string Name;
        public int CompareTo(Student other)
        {
            return String.Compare(Name, other.Name,
                   StringComparison.CurrentCultureIgnoreCase);
        }
    }

...或者您可以将比较 lambda 传递给 Sort ...

Array.Sort<Student>(names, (x, y) => String.Compare(x.Name, y.Name,
                                     StringComparison.CurrentCultureIgnoreCase));

...或者作为第三种选择,只需创建一个新的排序数组;

var newArray = names.OrderBy(x => x.Name.ToLower()).ToArray();
于 2013-05-19T16:09:01.053 回答
1

创建一个比较器类

class StudentComparer : IComparer<Student>
{
    public int Compare(Student a, Student b)
    {
        return a.Name.CompareTo(b.Name);
    }
}

种类:

Array.Sort(students,new StudentComparer());
于 2014-02-19T14:30:53.970 回答
0

要按数组中对象的name属性排序,您可以使用StudentStudent

Array.Sort(names, (s1, s2) => String.Compare(s1.Name, s2.Name));

它将对您的数组进行排序,或者使用System.Linq

names = names.OrderBy(s => s.Name).ToArray();

它可以返回排序后IEnumerable的数组 ( .ToArray()) 或列表 ( .ToList().)

如另一个答案中所指出的,如果重要,请记住对不区分大小写进行排序,可以这样做String.Compare

String.Compare(s1.Name, s2.Name, StringComparison.CurrentCultureIgnoreCase)
于 2013-05-19T16:02:41.613 回答
0

您也可以使用它,而不是使用 Array.Sort。

names = names.OrderBy(p => p.Name).ToArray();
于 2013-05-19T16:03:25.250 回答
-4

您可以在这里找到其中一种基本算法:简单冒泡排序 c#

您必须进行一些修改,该示例适用于 int,对于字符串,您必须比较名称。

你可以找到更好的排序算法。现在冒泡排序适合你。

于 2013-05-19T16:02:50.127 回答