对字符串进行排序以匹配第二个字符串的最快方法 - 仅允许相邻交换

2024-04-22

我想获得将一个字符串转换为匹配第二个字符串所需的最小字母交换次数。仅允许相邻交换。

输入为:字符串长度、string_1、string_2

一些例子:

Length | String 1 | String 2 | Output
-------+----------+----------+-------
   3   | ABC      | BCA      |   2 
   7   | AABCDDD  | DDDBCAA  |  16
   7   | ZZZAAAA  | ZAAZAAZ  |   6

这是我的代码:

def letters(number, word_1, word_2):

    result = 0

    while word_1 != word_2:
        index_of_letter = word_1.find(word_2[0])
        result += index_of_letter
        word_1 = word_1.replace(word_2[0], '', 1)
        word_2 = word_2[1:]

    return result

它给出了正确的结果,但计算时间应保持在 20 秒以内。

以下是两组输入数据(1 000 000 个字符长的字符串):https://ufile.io/8hp46 https://ufile.io/8hp46 and https://ufile.io/athxu https://ufile.io/athxu.

在我的设置中,第一个命令在大约 40 秒内执行,第二个命令在 4 分钟内执行。

如何在不到20秒的时间内计算出结果?


@KennyOstrom 的 90% 都在那里。倒数计数确实是看待这个问题的正确角度。

唯一缺少的一点是我们需要一个“相对”反转计数,这意味着反转的数量不是达到正常的排序顺序,而是达到另一个单词的顺序。因此,我们需要计算将 word1 稳定映射到 word2(或相反)的排列,然后计算其反转计数。稳定性在这里很重要,因为显然会有很多非唯一的字母。

这是一个 numpy 实现,对于您发布的两个大型示例,只需一两秒钟。我没有对其进行广泛的测试,但它确实与@trincot 在所有测试用例上的解决方案一致。对于它发现的两个大对1819136406 and 480769230766.

import numpy as np

_, word1, word2 = open("lit10b.in").read().split()
word1 = np.frombuffer(word1.encode('utf8')
                      + (((1<<len(word1).bit_length()) - len(word1))*b'Z'),
                      dtype=np.uint8)
word2 = np.frombuffer(word2.encode('utf8')
                      + (((1<<len(word2).bit_length()) - len(word2))*b'Z'),
                      dtype=np.uint8)
n = len(word1)

o1 = np.argsort(word1, kind='mergesort')
o2 = np.argsort(word2, kind='mergesort')
o1inv = np.empty_like(o1)
o1inv[o1] = np.arange(n)

order = o2[o1inv]

sum_ = 0
for i in range(1, len(word1).bit_length()):
    order = np.reshape(order, (-1, 1<<i))
    oo = np.argsort(order, axis = -1, kind='mergesort')
    ioo = np.empty_like(oo)
    ioo[np.arange(order.shape[0])[:, None], oo] = np.arange(1<<i)
    order[...] = order[np.arange(order.shape[0])[:, None], oo]
    hw = 1<<(i-1)
    sum_ += ioo[:, :hw].sum() - order.shape[0] * (hw-1)*hw // 2

print(sum_)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对字符串进行排序以匹配第二个字符串的最快方法 - 仅允许相邻交换 的相关文章

  • python类型中的__flags__有什么用

    我最近阅读了pickle源代码 以下代码在copy reg让我很困惑 HEAPTYPE 1 lt lt 9 def reduce ex self proto assert proto lt 2 for base in self class
  • 对 java ConcurrentHashMap 中的值进行排序

    我有以下用于对 ConcurrentHashMap 进行排序的代码 ConcurrentHashMap
  • 如何在Python中检查UDF函数中pyspark数据帧列的单元格值为none或NaN以实现前向填充?

    我基本上是在尝试进行前向填充插补 下面是代码 df spark createDataFrame 1 1 None 1 2 5 1 3 None 1 4 None 1 5 10 1 6 None session timestamp id PR
  • Python中非常大的整数的math.pow是错误的[重复]

    这个问题在这里已经有答案了 我试图通过计算一个整数的非常大的幂来打印一个非常大的数字 尽管我的代码是正确的 但我没有观察到所需的输出 一般来说 Python解释器可以打印系统内存支持的非常大的整数 考虑到这个假设 下面是我正在运行的代码 a
  • 将Python嵌入到C中——导入模块

    我在使用嵌入式 Python for C 时遇到问题文档 http docs python org extending embedding html 每当我尝试使用导入的模块时 我都会得到 PythonIncl exe 中 0x1e089e
  • 如果工作表不存在,Pandas 将工作表附加到工作簿,否则覆盖工作表

    我正在使用 pandas 更新现有的 Excel 工作簿 当使用ExcelWriter对象 我可以覆盖工作表 如果存在 否则创建一个新工作表吗 我的代码附加了新工作表 但是当我尝试覆盖现有工作表时 它会附加一个名称略有不同的新工作表 例如
  • Python 的二进制字符串列表

    我有一个像这样的二进制字符串 1100011101 我想将其解析为一个列表 其中每个 1 或 0 块都是列表中的单独值 例如 1100011101 变成 11 000 111 0 1 您可以通过使用正则表达式而不是从中获得一点 次要 性能g
  • 并行磁盘 I/O

    我有几个想要阅读的日志文件 不失一般性 假设日志文件处理如下 def process infilepath answer 0 with open infilepath as infile for line in infile if line
  • 在Python中从整个图像中检测表格部分

    我有一张尺寸为 3500x5000 的图像 现在我只想检测整个图像中的表格部分 如果不能直接进行 OCR 处理 则对其进行裁剪和旋转 经过所有搜索后 我想到了使用裁剪图像中的每个单元格的想法https medium com coinmonk
  • 即使使用标头和 Session 对象,Python requests.get 也会失败并出现 403 禁止

    我正在发出 GET 请求来获取 JSON 它在任何设备上的任何浏览器中都可以正常工作 但不能通过 python 请求 url https angel co autocomplete new tags params query sci tag
  • 使用字体模块的 Tkinter 代码无法从命令行运行?

    我有使用 tkinter 的代码 我可以从 IDLE 运行得很好 但会引发异常AttributeError module object has no attribute font 当它从命令行运行时 其他 tkinter 程序工作正常 但任
  • 有什么理由不在Python中混合使用多处理和线程模块

    我正在考虑使用Python来实现一个需要大量多线程的程序 另一个要求是它将在桌面上运行 因此拥有许多进程将使应用程序显得混乱且难以杀死 在任务管理器中 因此 我正在考虑使用线程和多处理模块来减少进程数量 据我了解 GIL 仅适用于单个进程
  • Python 柯里化任意数量的变量

    我正在尝试使用柯里化在 Python 中进行简单的函数添加 我找到了这个咖喱装饰器here https gist github com JulienPalard 021f1c7332507d6a494b def curry func def
  • 打包布尔数组需要通过 int (numpy 1.8.2)

    我正在寻找更紧凑的方式来存储布尔值 numpy 内部需要 8 位来存储一个布尔值 但是np packbits允许打包 他们 这真是太酷了 问题是要打包在4e6字节数组a32e6字节我们需要首先使用的布尔值数组256e6字节将布尔数组转换为
  • 如何在Python中仅列出顶级目录?

    我希望能够仅列出某个文件夹内的目录 这意味着我不需要列出文件名 也不需要其他子文件夹 让我们看看一个例子是否有帮助 在当前目录中我们有 gt gt gt os listdir os getcwd cx Oracle doc DLLs Doc
  • 将数字 n 拆分为 k 个不同数字的总和

    我有一个数字 n 我必须将它分成 k 个数字 使得所有 k 个数字都是不同的 k 个数字的总和等于 n 并且 k 最大 例如 如果 n 为 9 则答案应为 1 2 6 如果 n 为 15 则答案应为 1 2 3 4 5 这就是我尝试过的 v
  • 编写 CherryPy 装饰器以进行授权

    我有一个cherrypy应用程序 在某些视图上我想开始只允许某些用户查看它们 并将其他任何人发送到需要授权的页面 有没有办法使用自定义装饰器来做到这一点 我认为这将是最优雅的选择 这是我想做的一个基本示例 class MyApp autho
  • PyQt 和 QSignalMapper/lambdas - 多个信号,单槽

    我在 PyQt 的菜单上有一个操作列表 每个操作对应我想要显示的每个不同的提要 所以我有一个 Y 将活动源设置为 Y Z 将其设置为 Z 等等 对于网络漫画阅读程序 我的菜单上都有 并且觉得自动化方法可能更好 而不是每次都打字 类似于将其添
  • 从 Python 访问 802.11 无线管理帧

    我想从 Linux 上的 Python 嗅探 802 11 管理 探测请求 帧 这可以从 Scapy 中实现 如下所示 coding utf 8 from scapy all import def proc p if p haslayer
  • Django 表单中的只读字段

    如何在 Django 表单中将字段设置为只读 我知道如何禁用某个字段 但这不是我想要的 任何帮助 将不胜感激 您可以使用可选的attrs定义时的参数Field 以机智 somefield forms CharField widget for

随机推荐