__lt__实现排序列表

时间:2016-03-19 02:15:19

标签: python

我不明白为什么我的__lt__实施似乎失败了。

这是我的班级:

import random, string, datetime
from functools import total_ordering


@total_ordering
class Rotation(object):
    """Describes a rotation of an input based on getting the original and then offsetting it."""

    def __init__(self, original, idx):
        self.original = original
        self.idx = idx

    def getOffset(self, offset):
        return self.original[(self.idx + offset) % len(self.original)]

    def __eq__(self, other):
        print("checking equality")
        if self.idx == other.idx:
            return True
        for offset in range(len(self.original)):
            if self.getOffset(offset) is not other.getOffset(offset):
                print("this={} is not that={}".format(self.getOffset(offset), other.getOffset(
                        offset)))
                return False
        return True

    def __lt__(self, other):
        for offset in range(len(self.original)):
            if self.getOffset(offset) < other.getOffset(offset):
                # print("this={} is less than that={}".format(self.getOffset(offset), other.getOffset(
                #         offset)))
                return True
        print("Not less than")
        return False

    def __str__(self):
        return self.getOffset(-1)

    def __repr__(self):
        return "".join(map(lambda x: str(x), [self.getOffset(idx) for idx in range(len(
                self.original))]))

def rotation_sort(input):
    original = list(input)
    rotations = [Rotation(original, idx) for idx in range(len(original))]
    result = sorted(rotations)
    print("original={} rotations={} result={}".format(original, rotations, result))
    return "".join(map(lambda x: str(x), result))

def test(input):
    start = datetime.datetime.now()
    result = rotation_sort(input)
    end = datetime.datetime.now()
    runtime = end - start
    print("input={} runtime={} head={} tail={}".format(input[:5], runtime.seconds, result[:5],
                                                       result[-5:]))

test('bacb')

运行此脚本我得到以下输出:

$ python2 strange_sort.py
original=['b', 'a', 'c', 'b'] rotations=[bacb, acbb, cbba, bbac] result=[bbac, cbba, acbb, bacb]
input=bacb runtime=0 head=cabb tail=cabb

我不明白为什么result没有正确排序。我原以为result=[acbb, bacb, bbac, cbba]

对于上下文:我们的想法是尝试找到一种更快捷的方式来排序&#39;字符串的所有旋转,而不是查找所有排列并单独排序。 (这个想法适用于长度为数百或数千但不是数十万的字符串。)为证明排序,__str__拉出字符串中的最后一个字符。为了实现排序,每次轮换&#39; (它知道它开始的原始位置)将它自己开始的增加偏移与另一个旋转开始的偏移进行比较:

original string: bacb
all rotations:
    index 0: bacb 
    index 1: acbb 
    index 2: cbba 
    index 3: bbac
sorted rotations:
    index 1: acbb
    index 0: bacb
    index 3: bbac
    index 4: cbba
final representation of sorted rotations (last character of each): 
    bbca 

1 个答案:

答案 0 :(得分:4)

问题是,如果__lt__,您只能从self.getOffset(offset) < other.getOffset(offset)中的循环返回,但如果self.getOffset(offset) > other.getOffset(offset)继续循环播放。这很容易解决:

def __lt__(self, other):
    for offset in range(len(self.original)):
        if self.getOffset(offset) < other.getOffset(offset):
            return True
        elif self.getOffset(offset) > other.getOffset(offset):
            return False
    return False