Python Burrows-Wheeler变换(BWT)重复字符串
我正在用Python编写Burrows-Wheeler变换及其反变换。它适用于小弦,但当我测试大弦时,它就崩溃了。在某些点上,字符串似乎在循环。我确信这一定与解码器的最终循环有关,但我遵循不止一个网站上的步骤。我的执行情况如下:Python Burrows-Wheeler变换(BWT)重复字符串,python,compression,burrows-wheeler-transform,inverse-transform,Python,Compression,Burrows Wheeler Transform,Inverse Transform,我正在用Python编写Burrows-Wheeler变换及其反变换。它适用于小弦,但当我测试大弦时,它就崩溃了。在某些点上,字符串似乎在循环。我确信这一定与解码器的最终循环有关,但我遵循不止一个网站上的步骤。我的执行情况如下: class BurrowsWheelerTransform: def __init__(self, data): self.data = data def transform(self): # get data siz
class BurrowsWheelerTransform:
def __init__(self, data):
self.data = data
def transform(self):
# get data size
size = len(self.data)
# get order (by index) of rotations
order = sorted(range(size), key=lambda i: self.data[i:])
# get index of original rotation
index = order.index(0)
# return size appended with last column of (imaginary) rotation table
return chr(255) * (index // 255) + chr(index % 255) + ''.join(self.data[(i - 1 + size) % size] for i in order)
def restore(self):
# get index of end of index
eoi = next(i for i in range(len(self.data)) if ord(self.data[i]) < 255)
# get index
index = 255 * eoi + ord(self.data[eoi])
# get tranformed content
content = self.data[eoi + 1:]
# get lshift array
lshift = [i - 1 for symbol in sorted(set(content)) for i, x in enumerate(self.data) if x == symbol]
# restore
restored = ''
for i in range(len(content)):
index = lshift[index]
restored += content[index]
# return restored
return restored
class BurrowsWheelerTransform:
定义初始化(自身,数据):
self.data=数据
def转换(自):
#获取数据大小
大小=长度(自身数据)
#获取旋转的顺序(通过索引)
顺序=排序(范围(大小),键=lambda i:self.data[i:])
#获取原始旋转的索引
索引=顺序。索引(0)
#返回大小随(假想的)旋转表的最后一列一起追加
返回chr(255)*(索引//255)+chr(索引%255)+''.join(按顺序为i的self.data[(i-1+size)%size]))
def恢复(自我):
#获取索引末尾的索引
如果ord(自数据[i])<255,则eoi=next(i表示范围内的i(len(自数据)))
#获取索引
索引=255*eoi+ord(自身数据[eoi])
#获取转换内容
content=self.data[eoi+1:]
#获取lshift数组
lshift=[i-1表示已排序(集合(内容))中的符号,i,x表示枚举(self.data)中的符号,如果x==symbol]
#恢复
还原=“”
对于范围内的i(len(content)):
索引=lshift[索引]
还原+=内容[索引]
#恢复原状
恢复原状
原始字符串:
罗斯特夫不愿打扰公主,也没有回去
但她仍留在村子里等待她离开。当她
马车驶出了房子,他骑上马车,陪着她走了八个小时
从Boguchrovo到我军占领的道路数英里。在
在扬科沃的旅馆里,他第一次恭敬地向她告别
时间允许他吻她的手
你怎么能这么说!他脸红地回答玛丽公主
表达对她获救的感激之情,正如她所说的那样
发生。任何警察都会做同样的事!如果我们有
只有农民去打仗,我们不应该让敌人走这么远,
他羞愧地说,想换个话题。我是
很高兴有机会认识你。
再见,公主。我祝你幸福、安慰,并希望
在更快乐的环境中再次见到你。如果你不想让我
脸红,请不要谢我
解码字符串:
罗斯特夫不愿打扰公主,也没有回去
但她仍留在村子里等待她离开。当她
马车驶出了房子,他骑上马车,陪着她走了八个小时
从Boguchrovo到我军占领的道路数英里。在
在扬科沃的旅馆里,他第一次恭敬地向她告别
时间允许他吻她的手
你怎么能这么说!不愿意打扰公主,
罗斯特夫没有回到房子里,而是留在了村子里
等待她的离去。当她的马车驶出房子时,他
从Boguchrovo骑上并陪伴她八英里到达
这条路被我们的部队占领了。在扬科沃酒店,他恭敬地说
向她告别,这是他第一次允许自己吻她
手
你怎么能这么说!不愿意打扰公主,
罗斯特夫没有回到房子里,而是留在了村子里
等待她的离去。什么时候
奇怪的是,我在web上找到并测试过的其他实现(如和)似乎也会出现这种情况。发生了什么事?我是否误解了转换的工作原理?或者这个实现是不正确的 找到了答案!该算法基于以下假设:字符串连接到最后一个字符,该字符是唯一的,并且在词典学上比字符串中的任何其他字符都小。但是,由于我打算对任何给定字符使用0-255范围内的任何值,因此我不需要额外的符号。幸运的是,经过一些额外的bug修复,我已经能够稍微修改我的初始实现来解释这个事实。这是:
class BurrowsWheelerTransform:
def __init__(self, data):
self.data = data
def transform(self):
# get data size
size = len(self.data)
# get doubled string
self.data *= 2
# get order (by index) of rotations
order = sorted(range(size), key=lambda i: self.data[i:])
# get index of original rotation
index = order.index(0)
# return index appended with last column of (imaginary) rotation table
return chr(255) * (index // 255) + chr(index % 255) + ''.join(self.data[(i - 1 + size) % size] for i in order)
def restore(self):
# get index of end of index
eoi = next(i for i in range(len(self.data)) if ord(self.data[i]) < 255)
# get index
index = 255 * eoi + ord(self.data[eoi])
# get tranformed content
content = self.data[eoi + 1:]
size = len(content)
# get lshift array
lshift = [i for symbol in sorted(set(content)) for i, x in enumerate(content) if x == symbol]
# restore
restored = ''
for i in range(size):
index = lshift[index]
if index >= size: break
restored += content[index]
# return restored
return restored
class BurrowsWheelerTransform:
定义初始化(自身,数据):
self.data=数据
def转换(自):
#获取数据大小
大小=长度(自身数据)
#获得双倍的字符串
self.data*=2
#获取旋转的顺序(通过索引)
顺序=排序(范围(大小),键=lambda i:self.data[i:])
#获取原始旋转的索引
索引=顺序。索引(0)
#返回索引附加(虚拟)旋转表的最后一列
返回chr(255)*(索引//255)+chr(索引%255)+''.join(按顺序为i的self.data[(i-1+size)%size]))
def恢复(自我):
#获取索引末尾的索引
如果ord(自数据[i])<255,则eoi=next(i表示范围内的i(len(自数据)))
#获取索引
索引=255*eoi+ord(自身数据[eoi])
#获取转换内容
content=self.data[eoi+1:]
大小=长度(内容)
#获取lshift数组
lshift=[i表示已排序(集合(内容))中的符号,如果x==symbol,则表示枚举(内容)中的i,x]
#恢复
还原=“”
对于范围内的i(尺寸):
索引=lshift[索引]
如果索引>=大小:中断
还原+=内容[索引]
#恢复原状
恢复原状
谢谢你,约翰 找到了答案!该算法基于以下假设:字符串连接到最后一个字符,该字符是唯一的,并且在词典学上比字符串中的任何其他字符都小。但是,由于我打算对任何给定字符使用0-255范围内的任何值,因此我不需要额外的符号。幸运的是,还有一些额外的b