简体   繁体   English

在列表上实现排序算法<string>

[英]Implementing sorting algorithms on a List<string>

I have created some sorting algorithms inside CustomDataList class: 我在CustomDataList类中创建了一些排序算法:

public void SortStudents() //sorts students alphabetically
    {
        string temp;
        for (int i = 0; i < students.Count; i++)
        {
            for (int j = i + 1; j < students.Count; j++)
            {
                if (string.Compare(students[i], students[j]) > 0)
                {
                    temp = students[j];
                    students[j] = students[i];
                    students[i] = temp;
                }
            }
            Console.WriteLine(students[i]);
        }
    }


    public string GetMaxElement()
    {
        string tempMax = null;
        foreach (string element in students)
        {
            if (tempMax == null || string.Compare(tempMax, element) > 0)
            {
                tempMax = element;
            }
        }
        return tempMax;
    }

    public string GetMinElement()
    {
        string tempMin = null;
        foreach (string element in students)
        {
            if (tempMin == null || string.Compare(tempMin, element) < 0)
            {
                tempMin = element;
            }
        }
        return tempMin;
    }
}

And the following code inside the Main() method: 以及Main()方法中的以下代码:

CustomDataList customDataList = new CustomDataList();
        //Add(element)
        customDataList.AddStudent("Jenny");
        customDataList.AddStudent("Loren");
        customDataList.AddStudent("Martin");
        customDataList.AddStudent("Hannah");
        customDataList.AddStudent("Joules");
        customDataList.AddStudent("Daniel");
        customDataList.AddStudent("Andy");
        customDataList.AddStudent("Emilio");
        customDataList.AddStudent("Ariana");
        customDataList.AddStudent("Nikkita");

This code works fine, but now I need to add other sorting algorithms (for example algorithms that sort the list based on the length of the name) similar to SortStudents() method (without using .Sort() method). 这段代码运行良好,但是现在我需要添加类似于SortStudents()方法(不使用.Sort()方法)的其他排序算法(例如,基于名称的长度对列表进行排序的算法)。

I would appreciate it if you could suggest other kind of sorting and some hints about how to create that sorting algorithm. 如果您可以建议其他排序方式,以及有关如何创建该排序算法的一些提示,我们将不胜感激。

If you are not obliged to use regular array operations, I suggest you to use 如果您没有义务使用常规数组操作,建议您使用

var result = customDataList.OrderBy(x => x.Length)

and for sorting by name 并按名称排序

var result = customDataList.OrderBy(x => x);

If you need to use array sort algorithm, replace 如果需要使用数组排序算法,请替换

if (string.Compare(students[i], students[j]) > 0)

With

if (students[i].Length < students[j].Length)

You can make it more object oriented. 您可以使其更加面向对象。 Declare a student class like this: 声明这样的学生班级:

public class Student : IComparable<Student>
{
    public int ID {get;set;}
    public string Name {get;set;}

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

Now, 现在,

List<Student> customDataList = new List<Student>();

customDataList.AddStudent("Jenny");
customDataList.AddStudent("Loren");
customDataList.AddStudent("Martin");
customDataList.AddStudent("Hannah");
customDataList.AddStudent("Joules");
customDataList.AddStudent("Daniel");
customDataList.AddStudent("Andy");
customDataList.AddStudent("Emilio");
customDataList.AddStudent("Ariana");
customDataList.AddStudent("Nikkita");

customDataList.Sort();  // sorts by name. default sorting

To implement multiple sorting, you can do this: implement an IComparer interface: 要实现多种排序,您可以执行以下操作:实现IComparer接口:

public class NameLengthComparer: IComparer<string>
{
    public int Compare(string x, string y)
    {
        if (x == null)
        {
            if (y == null)
            {
                // If x is null and y is null, they're
                // equal. 
                return 0;
            }
            else
            {
                // If x is null and y is not null, y
                // is greater. 
                return -1;
            }
        }
        else
        {
            // If x is not null...
            //
            if (y == null)
                // ...and y is null, x is greater.
            {
                return 1;
            }
            else
            {
                // ...and y is not null, compare the 
                // lengths of the two strings.
                //
                int retval = x.Length.CompareTo(y.Length);

                if (retval != 0)
                {
                    // If the strings are not of equal length,
                    // the longer string is greater.
                    //
                    return retval;
                }
                else
                {
                    // If the strings are of equal length,
                    // sort them with ordinary string comparison.
                    //
                    return x.CompareTo(y);
                }
            }
        }
    }
}

then call like 然后像

NameLengthComparer nc = new NameLengthComparer();
customDataList.Sort(nc);  // sorts by length of Name

Reference: https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.sort?redirectedfrom=MSDN&view=netframework-4.7.2#System_Collections_Generic_List_1_Sort_System_Collections_Generic_IComparer__0__ 参考: https : //docs.microsoft.com/zh-cn/dotnet/api/system.collections.generic.list-1.sort?redirectedfrom=MSDN&view=netframework-4.7.2#System_Collections_Generic_List_1_Sort_System_Collections_Generic_IComparer__0__

If you build a solid enterprise application, and want to support many types of objects / sorting algorithms / comparison logic, then you need to consider proper object-oriented IComparable , as suggested by other answers. 如果您构建一个可靠的企业应用程序,并且想要支持多种类型的对象/排序算法/比较逻辑,则需要考虑其他答案所建议的适当的面向对象的IComparable You may also want to wrap your sorting algorithm into an abstract interface. 您可能还希望将排序算法包装到抽象接口中。

However, if you are just experimenting, as a point of view, there is a more functional way to implement it and it may look more natural for some developers, for example for JavaScript developers. 但是,从角度来看,如果您只是进行实验,则可以使用一种更实用的方法来实现它,对于某些开发人员(例如对于JavaScript开发人员),它看起来更自然。

You can pass a Func as a high-order function which will be responsible for the logic of comparing objects. 您可以将Func作为高阶函数传递,该函数将负责比较对象的逻辑。 It is much shorter and lets you reuse your sorting algorithm with any kind of comparison logic without implementing monstrous synthetic comparer classes. 它更短,可以让您将排序算法与任何种类的比较逻辑一起重用,而无需实现庞大的综合比较器类。

public void SortStudents(Func<string, string, int> compareFunction) 
{
    string temp;
    for (int i = 0; i < students.Count; i++)
    {
        for (int j = i + 1; j < students.Count; j++)
        {
            if (compareFunction(students[i], students[j]) > 0)
            {
                temp = students[j];
                students[j] = students[i];
                students[i] = temp;
            }
        }
        Console.WriteLine(students[i]);
    }
}

SortStudents(string.Compare); // sorts students alphabetically
SortStudents((a, b) => a.Length.CompareTo(b.Length)); // sorts students by the length of their names

You can then reuse this Func in any other algorithms involving comparison: 然后,您可以在涉及比较的任何其他算法中重用此Func

public string GetMaxElement(Func<string, string, int> compareFunction)   
{
    string tempMax = null;

    foreach (string element in students)
    {
        if (tempMax == null || compareFunction(tempMax, element) > 0)
        {
            tempMax = element;
        }
    }

    return tempMax;
}

You can use IComparer interface 您可以使用IComparer界面

public void SortStudents(IComparer<string> comparer) // sort students using bubble sort
{
    string temp;
    for (int i = 0; i < students.Count; i++)
    {
        for (int j = i + 1; j < students.Count; j++)
        {
            if (comparer.Compare(students[i], students[j]) > 0) // use given comparer instead.
            {
                temp = students[j];
                students[j] = students[i];
                students[i] = temp;
            }
        }
        Console.WriteLine(students[i]);
    }
}

And sort like

//sorts students alphabetically
customDataList.SortStudents(Comparer<string>.Create((a, b) => string.Compare(a, b)));

//sorts students by length
customDataList.SortStudents(Comparer<string>.Create((a, b) => a.Length.CompareTo(b.Length)));

Basically, you are using the same sorting algorithm, same code but with different comparison logic provided by IComparer interface. 基本上,您使用的是相同的排序算法,相同的代码,但具有IComparer接口提供的不同比较逻辑。

This technique is called "Dependency Injection". 该技术称为“依赖注入”。 in this case is type of a method injection. 在这种情况下是方法注入的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM