【问题标题】:How to fix sort in ascending and descending order?如何修复升序和降序排序?
【发布时间】:2020-09-28 01:36:36
【问题描述】:

我有这个错误,我无法将选择排序为正确的升序和降序。我已经尝试了所有可能的解决方案来解决这个问题,但我想不出别的办法。如果有人愿意帮助我解决这个问题,我将不胜感激。

错误示例 -

  • 布鲁斯·韦恩
  • 克拉克·肯特
  • 罗纳德·雷蒙德
  • 黛娜·兰斯
  • 亚瑟库里
  • 沙耶拉霍尔

我希望它是怎样的 -

  • 亚瑟库里
  • 布鲁斯·韦恩
  • 克拉克·肯特
  • 黛娜·兰斯
  • 罗纳德·雷蒙德
  • 沙耶拉霍尔

排序方法

public static void Sort(Employee[] emp, int size, int choice) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = i + 1; j < size - 1; j++) {
            bool switchval = false;
            switch (choice) {
                case 1: // ascending sort by employee name 
                    if (emp[j].GetName().CompareTo(emp[j + 1].GetName()) > 0)
                        switchval = true;
                    break;
                case 2: // ascending sort by employee number
                    if (emp[j].GetNumber() > emp[j + 1].GetNumber())
                        switchval = true;
                    break;
                case 3: // descending sort by hourly rate
                    if (emp[j].GetRate() < emp[j + 1].GetRate())
                        switchval = true;
                    break;
                case 4: // descending sort by weekly hours
                    if (emp[j].GetHours() < emp[j + 1].GetHours())
                        switchval = true;
                    break;
                case 5: // descending sort by gross pay 
                    if (emp[j].GetGross() < emp[j + 1].GetGross())
                        switchval = true;
                    break;
            }
            if (switchval) { 
                Employee temp;
                temp = emp[i];
                emp[i] = emp[j];
                emp[j] = temp;
            }
        }
    }
}

【问题讨论】:

  • 在 C#7 中,您可以使用元组交换两个变量:(emp[i], emp[j]) = (emp[j], emp[i]);
  • 为什么刚刚删除了stackoverflow.com/questions/64638646/… 问题?这似乎完全可以回答;我只是在等待完整的代码,以确保它易于实现。
  • @Enigmativity 无法发送完整的代码,因为它有一个流式阅读器文件,其中的单词乱码。
  • @BeR - 这似乎不是不可能的。在任何情况下你都可以使用 postbin。尽管如此,答案很简单,但是您的代码是以复杂的方式编写的。我希望向您展示答案以及如何简化您的编码。

标签: c# sorting


【解决方案1】:

您正在尝试实现bubble sort 算法,但您对数组的迭代不正确。首先,将内部 for 循环更改为:

for (int j = 0; j < size - 1; j++)

然后将 if 块改为:

if (switchval)
{
    Employee temp;
    temp = emp[j];
    emp[j] = emp[j+1];
    emp[j+1] = temp;
}

因为您想基于j 而不是i 执行此操作(因为i 用于迭代所有元素,而不是排序本身的一部分)。

【讨论】:

  • 这行得通。非常感谢。
  • 这是一个很好的答案,但其中有一些假设。 OP 并没有真正说有实现“传统”冒泡排序(n^2 迭代);在您的回答中,您做出了这个决定,但我认为这有点歪曲。 i 可用于在比较迭代中推导 j 的上限。即for (int j = 0; j &lt; size - 1 - i; j++)。这被称为优化冒泡排序。您还应该在i 循环中检查在j 比较迭代中是否发生了任何交换。如果不是,则已排序,退出i 循环。 (此行为是冒泡排序的一部分)
  • 想了想;我在这里根据我的评论创建了一个答案。
  • @BrettCaswell 确实需要进行优化,但我的回答是基于所需的最少更改量。如果我要推荐最好的行动方案,那么我会提出一些截然不同的建议
【解决方案2】:

扩展@Hayden 的回答(以及我对它的评论):您应该恭敬地将switchVal if 语句块中i 的所有引用替换为jj+1


通过在 for 循环的声明部分定义 ji,似乎您将 i 关联到 j 以尝试进行优化的冒泡排序;也就是说,您试图避免多余的比较。

您应该使用i 来推导值以与for 循环的条件部分中的j 进行比较(即max):

for (var j = 0; j &lt; size - 1 - i; j++)

随着每个完整的j 迭代循环出现,元素emp[(size - 1 - i) - 1] 将位于正确的排序索引中。任何与该元素相关的冗余比较都将被跳过。

此外,您应该检查是否在每个完整的j 迭代循环中发生了交换,以处理列表已经排序的情况。


在以下代码部分中,我定义了Employee[] employees。我将演示使用IOrderedEnumerable&lt;T&gt;.OrderBy&lt;T, TKey&gt;(Func&lt;T, TKey&gt;) 进行初始排序 - 并将结果分配给employeesSortedByNameDesc。然后我将反转该数组并将其分配给变量reverseEmployees;最后,我将使用更改后的Sort 方法来使用每个Employee[] 变量。

概述和注意事项:

  • Sort() employees
  • Sort() employeesSortedByNameDesc
    • 不应发生交换
    • 最小迭代次数
  • Sort() reversedEmployees
    • j 的每次迭代都会有一个swap
    • 每次完成 j 迭代将导致一项被排序\移到数组末尾;
    • 最大迭代次数

Employee类型

public class Employee
{
    internal string FirstName { get; set; }
    internal string LastName { get; set; }

    public string GetName() => $"{FirstName} {LastName}".Trim();

}

Sort() 方法(带有hasSwapOccurred 检查条件break;

static void Sort(Employee[] emp, int size, int choice)
{
    for (int i = 0; i < size - 1; i++)
    {
        bool hasSwapOccurred = false;

        for (int j = 0; j < size - 1 - i; j++)
        {
            bool switchval = false;
            switch (choice)
            {
                case 1: // ascending sort by employee name 
                    if (emp[j].GetName().CompareTo(emp[j + 1].GetName()) > 0)
                        switchval = true;
                    break;
                default:
                    break;
            }
                
            if (switchval)
            {
                Employee temp;
                temp = emp[j];
                emp[j] = emp[j + 1];
                emp[j + 1] = temp;
            }

            //Console.WriteLine($"(switchval := {switchval}, hasSwapOccurred := {hasSwapOccurred}) => [{string.Join(",", emp.Select(e => e.GetName()).ToArray()) }]");
        }
        //Console.WriteLine("-----");

        if (!hasSwapOccurred)
            break;
    }
    //Console.WriteLine("");
}

程序

static void Main(string[] args)
{
    var employees = new Employee[] 
    {
        new Employee { FirstName = "Bruce", LastName = "Wayne"},
        new Employee { FirstName = "Clark", LastName = "Kent"},
        new Employee { FirstName = "Ronald", LastName = "Raymond"},
        new Employee { FirstName = "Dinah", LastName = "Lance"},
        new Employee { FirstName = "Arthur", LastName = "Curry"},
        new Employee { FirstName = "Shayera", LastName = "Hol"}
    };

    var employeesSortedByNameDesc = employees.OrderBy(SelectEmployeeName).ToArray();

    var reversedEmployees = employeesSortedByNameDesc.Reverse().ToArray();

    Sort(employees, employees.Length, 1);
    Sort(employeesSortedByNameDesc, employeesSortedByNameDesc.Length, 1);
    Sort(reversedEmployees, reversedEmployees.Length, 1);

    string SelectEmployeeName(Employee e) => e.GetName();
}

Console.Write 输出(在上面的示例代码中被注释掉了)

【讨论】:

    猜你喜欢
    • 2016-03-03
    • 2015-10-09
    • 2012-11-08
    • 2023-03-07
    • 1970-01-01
    • 2015-03-09
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多