Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以在Python3中使用类似缓冲区(基于指针)的字符串比较进行排序?_Python_Python 3.x - Fatal编程技术网

是否可以在Python3中使用类似缓冲区(基于指针)的字符串比较进行排序?

是否可以在Python3中使用类似缓冲区(基于指针)的字符串比较进行排序?,python,python-3.x,Python,Python 3.x,考虑对字符串的所有后缀进行排序的问题,其中后缀是从某个索引i到字符串末尾的子字符串。我们可以创建一个索引列表,对应于已排序后缀的起点,而不是创建已排序后缀的列表。然后我们可以这样做: text = ... some text string ... sortedIndices = sorted([i for i in range(len(text))], key = lambda i: text[i:]) indexes = sorted(in

考虑对字符串的所有后缀进行排序的问题,其中后缀是从某个索引i到字符串末尾的子字符串。我们可以创建一个索引列表,对应于已排序后缀的起点,而不是创建已排序后缀的列表。然后我们可以这样做:

text = ... some text string ...
sortedIndices = sorted([i for i in range(len(text))], 
                       key = lambda i: text[i:])  
indexes = sorted(indexes, key = functools.cmp_to_key(lambda x,y:suffixArrayCompare(x, y)))
这适用于短字符串,但如果字符串足够长,我们将耗尽内存,因为key函数会生成后缀的副本,并且所有键都是从一开始生成的。在python 2.7中,有一种巧妙的解决方法,即buffer()函数:

sortedIndices = sorted([i for i in range(len(text))], 
                       key = lambda i: buffer(text, i))  

在本例中,键只是指向文本字符串的指针,因此所需的总内存要少得多(O(n)vs O(n*n))。因此,它将使用更长的字符串。这在2.7中运行得很好,但在3.x中,buffer()函数被删除,取而代之的是memoryview,它与buffer不同——AFAIK——不支持基于指针的字符串比较(即,不使用tobytes方法,该方法创建字符串的副本)。我的问题是:在Python3.x中有没有类似的方法

在我看来,memoryview并不能做到这一点。这实际上可能是件好事

您仍然可以使用更面向对象的类执行此操作:

#!/usr/local/cpython-3.3/bin/python

import sys
import functools

@functools.total_ordering
class Suffix_comparison:
    def __init__(self, string, starting_position):
        self.string = string
        self.starting_position = starting_position

    def __lt__(self, other):
        if self.string[self.starting_position:] < other.string[other.starting_position]:
            return True
        else:
            return False

    def __eq__(self, other):
        if self.string[self.starting_position:] == other.string[other.starting_position]:
            return True
        else:
            return False

    def __str__(self):
        return self.string

    __repr__ = __str__

def main():
    list_ = []
    for line in sys.stdin:
        stripped_line = line.rstrip('\n')
        list_.append(Suffix_comparison(stripped_line, 5))

    list_.sort()

    for line in list_:
        print(line)

main()
#/usr/local/cpython-3.3/bin/python
导入系统
导入功能工具
@functools.total_排序
类后缀\u比较:
定义初始位置(自身、字符串、起始位置):
self.string=string
自启动位置=启动位置
定义(自身、其他):
如果self.string[self.starting_position:][other.string[other.starting_position]:
返回真值
其他:
返回错误
定义(自身、其他):
如果self.string[self.starting_position:][==other.string[other.starting_position]:
返回真值
其他:
返回错误
定义(自我):
返回self.string
__repr\uuuuu=\uuuuuu str__
def main():
列表\=[]
对于sys.stdin中的行:
stripped_line=line.rstrip('\n')
列表附加(后缀比较(剥离行,5))
list.sort()
对于列表中的行:
打印(行)
main()

我也一直在研究这个问题

我刚刚从Python2.7转换到了3。WinPython,它有一个非常酷的编辑器,顺便说一句,叫做Spyder

据我所知,memoryview对象是完全无用的

我还尝试了itertools.islice函数,但也看不出如何运行它

所以决定写我自己的小比较函数:

def后缀组合(x,y): 全球文本

 i = 0
 end = len(globalText) - max(x, y)
 while i < end:
     if globalText[x+i] < globalText[y+i]:
         return -1
     elif globalText[x+i] > globalText[y+i]:
         return 1

     i += 1

 return 0
这是我跑得最快的速度了。它仍然没有2.7中的缓冲方式快,但也不太远。它不会复制任何东西

这个


运行速度几乎与您提到的一样快,但内存有问题。

您似乎在解决与我提出的问题不同的问题。您正在对一组输入字符串中的固定长度后缀进行排序。我感兴趣的问题是对单个n字符输入字符串的所有后缀集(从长度1到长度n)进行排序。此外,您正在列表中存储所有类实例(每个实例都包含字符串),因此您将遇到相同的内存问题。仅考虑
后缀\u比较
,在
lt\uuuuuu
eq\uu
函数中存在错误。它可以通过与
other.string[other.start\u position:][/code>进行比较来修复。
#indexes = sorted(indexes, key = lambda x: globalText[x:])