【问题标题】:insertion sort is skipping last element插入排序正在跳过最后一个元素
【发布时间】:2015-10-12 21:22:46
【问题描述】:

这种插​​入排序错误地对除最后一个元素之外的所有元素进行了排序。这很奇怪,因为我有一个相同的函数,可以按不同的属性对所有元素进行排序。我尝试复制、粘贴和更改工作函数,但这似乎是徒劳的。

for i in range(1, len(metals)):
   index = i
   while index != 0 and metals[index].weightPerBar > metals[index - 1].weightPerBar:
       metals[index], metals[index - 1] = metals[index - 1], metals[index]
       index -= 1

谢谢

这是模块的其余部分:

    class Metal(struct):
        """
        Represents a single metal type, composed of:
        :slot name (str): The name of the metal
        :slot totalBars (int): The total number of bars
        :slot weightPerBar (int): The weight of a single bar
        :slot valuePerBar (int): The value of a single bar
        :slot valuePerWeight (float): The value per weight of the metal
        :slot barsTaken (int): The number of bars added to the satchel
        """
        _slots = ((str, "name"), (int, "totalBars"), (int, "weightPerBar"), (int, "valuePerBar"), (float, "valuePerWeight"), (int, "barsTaken"))

        pass


    def createMetal(name, totalBars, weightPerBar, valuePerBar):
        """
        Create and return a new Metal object.
        :param name (str): The name of the metal
        :param totalBars (int): The total number of bars
        :param weightPerBar (int): The weight of a single bar
        :param valuePerBar (int): The value of a single bar
        :return: A newly initialized Metal object
        :rtype: Metal
        """

        new_metal = Metal(name, totalBars, weightPerBar, valuePerBar)
        return new_metal

        pass

    def readMetals(fileName):
        """
        Read the metals from a file whose format is:
            metalName totalBars weightPerBar valuePerBar
        :param fileName (str): The name of the file
        :return: A list of Metal objects
        :rtype: list
        """
        metal_list = []
        file = open(fileName)
        for line in file:
            line = line.split()
            weight_per_bar = float(line[3])/float(line[2]) # creating derived value
            new_metal = Metal(line[0], int(line[1]), int(line[2]), int(line[3]), weight_per_bar, 0)

            metal_list += [new_metal]
        return metal_list

        pass


    def sortMetalsByValuePerBar(metals):
        """
        Sort the metals by value per bar using insertion sort.  The list of
        metals is modified in place to be ordered by value per bar.
        :param metals (list of Metal): The list of metals
        :return: None
        :rtype: NoneType
        """

        for i in range(1, len(metals)):
            index = i
            while index != 0 and metals[index].valuePerBar > metals[index - 1].valuePerBar:
                metals[index], metals[index - 1] = metals[index - 1], metals[index]
                index -= 1


        pass

    def sortMetalsByValuePerWeight(metals):
        """
        Sort the metals by value per weight using insertion sort.  The list of
        metals is modified in place to be ordered by value per weight.
        :param metals (list of Metal): The list of metals
        :return: None
        :rtype: NoneType
        """
        for i in range(1, len(metals)):
            index = i
            while index != 0 and metals[index].weightPerBar > metals[index - 1].weightPerBar:
                metals[index], metals[index - 1] = metals[index - 1], metals[index]
                index -= 1
        pass

【问题讨论】:

    标签: python for-loop insertion-sort


    【解决方案1】:

    如果 .weightPerBar 都是相同类型并且是数字(不是字符串或其他对象),它应该可以工作。如果 weight 是一个字符串,它可能会出现“2”、“6”、“4”、“10”排序为“6”、“4”、“2”、“10”的情况。根据需要而不是 10、6、4、2。

    【讨论】:

    • 我强制类强制转换为整数
    【解决方案2】:

    您的代码在我的机器上运行良好,但您为什么要自己实现排序算法?您可以使用:

    metals.sort(key=lambda metal: metal.weightPerBar, reverse=True)

    【讨论】:

    • 将 [150, 400, 125, 166] 排序为 [166, 150, 125, 400] 时
    • weight_per_bar = int(line[3])/int(line[2]) # 创建派生值 new_metal = Metal(line[0], int(line[1]), int(line[ 2]), int(line[3]), float(weight_per_bar), 0)
    • 不过,您还没有给我足够的代码来确定您的问题出在哪里。然而,当我用 metal[index] 替换 metal[index].weightPerBar 并用 metal[index - 1] 替换 metal[index - 1].weightPerBar 并将金属作为数组或时,您的代码是插入排序的完美实现整数。这意味着您的问题一定出在其他地方,如果不获取更多代码,我将无法解决它。
    • 我的声誉比评论他的原始帖子所需的声誉要低一些,但我想帮助他。无论如何,我编辑了我的答案,所以它现在很有帮助,即使我仍然不知道原始代码哪里错了。
    猜你喜欢
    • 1970-01-01
    • 2019-05-05
    • 1970-01-01
    • 2015-01-16
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 2019-01-01
    • 1970-01-01
    相关资源
    最近更新 更多