【问题标题】:Sorting array of strings such that substrings of any other string will comes later对字符串数组进行排序,以便稍后出现任何其他字符串的子字符串
【发布时间】:2020-01-31 09:06:15
【问题描述】:

我想找到一种算法,它可以对字符串数组进行排序(或排列),这样如果任何字符串(比如 B)是任何其他字符串(比如 ABAC)的子字符串,那么 B 应该在 ABAC 之后。 例如:

假设字符串是:

abc
bc
zef
abcde

那么订单将是:

abcde, 
abc, 
bc 
and zef can come anywhere in the order.

【问题讨论】:

  • 您喜欢使用哪种编程语言编写代码?此外,如果字符串“bc”是两个字符串的子字符串,您希望“bc”去哪里。例如,有 3 个字符串,“abc”、“dbc”和“bc”。在这种情况下,您希望“bc”去哪里?
  • "bc" 可以放在 "abc" 和 "dbc" 之后的任何位置,但 "abc" 和 "dbc" 的顺序无关紧要。
  • @KevinNg 只要我能够理解 C、C++、python、Java、php 等算法的工作原理,任何编程语言或伪代码都可以工作。
  • 在这里构建一个 trie 似乎是一个不错的方法。

标签: string algorithm sorting optimization


【解决方案1】:

排序算法基于比较成对的值。通常编程语言允许提供带有比较器函数的内置排序方法,该函数应该接受两个参数,并返回一个整数值,指示它们的相对顺序(-1、0 或 1)。

所以定义比较器如下:

compare(a, b):
    if a is substring of b then return 1
    if b is substring of a then return -1
    if a < b then return -1
    if a > b then return 1
    return 0

此子字符串测试应首先检查两个字符串的长度,以避免对字符串进行扫描。因为当a.length &gt; b.length时,那么a不能是b的子串。或者你也可以明确地写:

compare(a, b):
    if a.length <= b.length and a is substring of b then return 1
    if a.length >= b.length and b is substring of a then return -1
    if a < b then return -1
    if a > b then return 1
    return 0

如果目标编程语言不提供这种可能性,那么您应该编写自己的排序函数(如 QuickSort),并确保它可以使用这样的比较器,以便(从标准实现开始)您可以替换:

 if a < b

与:

 if compare(a, b) < 0

...等等。

关系的传递性

让我们暂时假设在比较函数中编码的关系是不传递的,因此我们可以找到三个字符串 a、b 和 c:

  • 比较(a,b)
  • 比较(b,c)
  • 还有:compare(c, a)

首先,请注意这三个字符串的长度:

  • compare(a, b) = b.length
  • compare(b, c) = c.length
  • compare(c, a) = a.length

从前两个我们得出 a.length >= c.length,再结合第三个,我们可以得出所有三个字符串的长度相同的结论。

所以现在我们有:

  • compare(a, b)
  • compare(b, c)
  • compare(c, a)

这导致矛盾。所以我们必须得出结论,这种关系是可传递的。

【讨论】:

  • 我不认为这会起作用,因为您在这里使用比较排序,它使用比较函数不遵循的比较传递属性。;
  • 例如如果三个字符串是 A : "abc" , B : "bc" , C : "bcef" 那么你的比较函数: compare(A,B)
  • @Sagar,你可能有一点,但我在你的例子中看不到。首先,我将返回值反转,将子字符串放在首位,我现在已经更正了,所以它们排在最后。但到目前为止,我认为该算法从早期比较得出的结论没有问题。 compare(A, C) 实际上不是由 OP 的条件决定的:它们可以以任何一种方式排序,因为两者都不是另一个的子字符串。你有另一个反例吗?
  • 查看我添加到答案中的传递性证明。
  • 抱歉造成误会。我也找不到任何反例,所以我将其标记为解决方案。
猜你喜欢
  • 2021-02-04
  • 2012-10-14
  • 2014-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-13
  • 1970-01-01
相关资源
最近更新 更多