如何在十六进制字符串中交换相邻字节(使用或不使用正则表达式)
给定一个字符串(或者任何长度的字符串,只要它的单词对数是偶数):
"12345678"
我想知道怎么交换相邻的“单词”?
我想要的结果是:
"34127856"
而且,当这个操作完成后,我还需要交换长的部分。
我想要的最终结果是:
"78563412"
6 个回答
这里是针对字符串 "12345678" 的内容。
from textwrap import wrap
s="12345678"
t=wrap(s,len(s)/2)
a,b=wrap(t[0],len(t[0])/2)
c,d=wrap(t[1],len(t[1])/2)
a,b=b,a
c,d=d,c
print a+b+c+d
你可以把它做成一个通用的函数,这样就可以处理不同长度的字符串了。
输出结果
$ ./python.py
34127856
在编程中,有时候我们需要处理一些数据或者信息,这时候就会用到“数据结构”。简单来说,数据结构就是用来组织和存储数据的一种方式。想象一下,如果你有很多书,想要把它们放在一个书架上,你可能会按照作者的名字、书的类型或者出版日期来分类,这就是一种数据结构的应用。
在编程里,常见的数据结构有数组、链表、栈、队列、树和图等。每种数据结构都有自己的特点和适用场景。例如,数组就像一个整齐的书架,书本按顺序排列,查找某本书很方便;而链表则像一串珠子,每颗珠子都指向下一颗,适合频繁插入和删除的情况。
了解这些数据结构可以帮助你更有效地管理和操作数据,让你的程序运行得更快、更顺畅。
import re
re.sub(r'(..)(..)', r'\2\1', '12345678')
re.sub(r'(....)(....)', r'\2\1', '34127856')
这里介绍了一种使用正则表达式的方法:
import re
twopairs = re.compile(r'(..)(..)')
stringwithswappedwords = twopairs.sub(r'\2\1', basestring)
twoquads = re.compile(r'(....)(....)')
stringwithswappedlongs = twoquads.sub(r'\2\1', stringwithswappedwords)
补充说明:不过,这绝对不是在Python中最快的方法——那么我们怎么知道这些呢?首先,把所有“竞争”的方法写到一个模块里,这里我叫它 'swa.py'
……:
import re
twopairs = re.compile(r'(..)(..)')
twoquads = re.compile(r'(....)(....)')
def withre(basestring, twopairs=twopairs, twoquads=twoquads):
stringwithswappedwords = twopairs.sub(r'\2\1', basestring)
return twoquads.sub(r'\2\1', stringwithswappedwords)
def withoutre(basestring):
asalist = list(basestring)
asalist.reverse()
for i in range(0, len(asalist), 2):
asalist[i+1], asalist[i] = asalist[i], asalist[i+1]
return ''.join(asalist)
s = '12345678'
print withre(s)
print withoutre(s)
注意我设置了 s
,并尝试这两种方法,快速检查一下它们是否计算出相同的结果——对于这种“性能对比赛”,这样做是个好习惯!
然后,在命令行中,你可以使用 timeit
,方法如下:
$ python -mtimeit -s'import swa' 'swa.withre(swa.s)'
78563412
78563412
10000 loops, best of 3: 42.2 usec per loop
$ python -mtimeit -s'import swa' 'swa.withoutre(swa.s)'
78563412
78563412
100000 loops, best of 3: 9.84 usec per loop
……这样你就会发现,在这种情况下,不使用正则表达式的方法大约快4倍,这样的优化是很有价值的。一旦你有了这样的“测量工具”,如果需要“真正的超快速度”,也可以轻松尝试其他替代方案和调整。
补充说明:例如,这里有一个更快的方法(添加到同一个 swa.py
中,最后一行当然是 print faster(s)
;-):
def faster(basestring):
asal = [basestring[i:i+2]
for i in range(0, len(basestring), 2)]
asal.reverse()
return ''.join(asal)
这样得到:
$ python -mtimeit -s'import swa' 'swa.faster(swa.s)'
78563412
78563412
78563412
100000 loops, best of 3: 5.58 usec per loop
大约5.6微秒,比最简单的不使用正则表达式的方法的9.8微秒要快,是另一个可能值得的微优化。
当然,这样的优化还有很多——有个老话(伪定理)说,任何程序都可以缩短至少一个字节,并且至少快一纳秒……;-)
补充说明:为了“证明”这个伪定理,这里有一个完全不同的方法(替换掉 swa.py
的结尾)……:
import array
def witharray(basestring):
a2 = array.array('H', basestring)
a2.reverse()
return a2.tostring()
s = '12345678'
# print withre(s)
# print withoutre(s)
print faster(s)
print witharray(s)
这样得到:
$ python -mtimeit -s'import swa' 'swa.witharray(swa.s)'
78563412
78563412
100000 loops, best of 3: 3.01 usec per loop
可能会有进一步值得的加速。