如何最好地比较这两个字符串的值,即使它们是随机顺序的?

How to best compare these two strings for values even though they are in random order?

我的数据库中有一个长度为四个字符的字符串,例如 A487。用户可以通过键入四个字符来搜索该数据库。由于这些因素,我很难概念化如何优雅地实现它:

  1. 用户的输入可以是任意顺序。例如,用户可能键入 2345,这需要与 5432.
  2. 的数据库条目相匹配
  3. 输入需要考虑数字对。例如,一个条目可能是 2245。如果用户输入4252,则需要找到这个条目。

简而言之,我需要搜索 return 所有结果,其中存在用于字符匹配的精确字符,而不管字符本身的顺序如何。有什么想法吗?

解法:

我决定采用在导入时创建排序列的方法,这样我就可以使用相同的方法对用户的输入进行排序并比较确切的字符串。为此:

我使用了 PHP 的自然排序算法(实际上如何排序并不重要,只要它在数据库值和用户输入之间保持一致即可)。

$hand = "AT77";    

// Create an array with each card in it.
$cards = [$hand[0], $hand[1], $hand[2], $hand[3]];

// Sort the array using natural sort algorithim
natsort($cards);

// Create a string out of array
$sortedHand = implode($cards);

我将这个值插入到 hand_sorted 下的数据库中,然后我可以简单地在包含用户输入的数组上使用相同的 natsort 来比较精确的字符串。对于我的确切项目,在导入时间方面没有明显的损害,用户上传的 CSV 行长在 40k 到 100k 之间。最终成为完美的解决方案。

您的应用程序应针对每个排列执行查询匹配。

对于 4 个字符的字符串,这将是 24 个选项。 (4!= 4*3*2*1 = 24)

假设您使用的是 SQL,它看起来像这样:

SELECT * FROM my_table WHERE my_column IN ('4252', '4525', ...)

既然你含糊地指定了这个字符串将是字母数字,一旦掌握了它应该是一个很容易编程的概念。

我能推荐的逻辑上最简单的方法是简单地将每个字符设置为它自己的变量,然后遍历你的数据库并检查每个条目,说“这个数据库条目是否包含每个字符一次?"如果条目中存在每个字符变量,那么您就找到了匹配项。

假设您要搜索用户输入的 2235,并且您的程序将每个分配给以下内容:

int num1 = 2;
int num2 = 2;
int num3 = 3;
int num4 = 5;

你可以遍历数据库,如果遇到 2235,它应该可以说 "is the first integer in this entry equal to num1?" 如果没有,那么它可以将第一个整数与 num2 进行比较,并且很快。如果没有匹配项,这意味着数据库条目包含用户输入的 none,因此您可以继续。如果确实匹配,那么您可以继续说 "does the second integer in this entry match num1?" 等等。这应该可以满足您以任何顺序找到匹配项的第一个要求。

该逻辑的缺陷在于 2225 之类的测试用例会通过,因为前三个整数会匹配 num1。为了解决这个问题,您可以使用布尔值或其他 if 语句来表示 "if num1 matched any of the integers of the database entry, stop comparing it with the other integers." 这样,所有 num 变量都应该与条目中的一个字符匹配,以找到任何顺序的完全匹配。

或者,您可以将用户的搜索查询填充到数组或其他数据结构中,然后执行类似的过程。两者都应该给你类似的结果。

为了便于查询,我建议您在数据库中添加一个新列 table 以存储 4 个字符的字符串,每个字母按字母顺序排列。然后你可以简单地按字母顺序排列你的输入字符串并寻找精确匹配。这样应该效率很高。

----------------------------------
col1 | unsorted  | sorted | col2 |
----------------------------------
blah | 3542      | 2345   | blah |
blah | 4533      | 3345   | blah |
blah | 4253      | 2345   | blah |
----------------------------------

这样可以保证您的数据真实,也便于查询。您只需要查询 sorted 列值。

好吧,当涉及排列时,它会变得非常昂贵。也许两步法是一种选择。首先用一种相当粗略但快速的方法过滤,然后用精确但更昂贵的方法过滤较少的结果。

例如为这样的字符串计算标量值,如果字符串相等则该标量值相等。只是快速拍摄,可能有更好的方法,添加每个字符的 ASCII 值。您可以在数据库 table 中具体化,例如使用触发器。可能索引它。然后根据此值查询 table ,您将获得一部分可能的候选人。然后通过精确比较过滤该子集。它至少会减少您必须应用更昂贵的精确方法的搜索 space。

对于不需要任何架构更改(但不允许索引进行优化)的临时解决方案,您还可以将用户输入拆分为单个字符,让它们命名为 abcd。然后你可以像

这样查询
SELECT *
       FROM your_table
       WHERE substring(your_column, 1, 1) IN (a, b, c, d)
             AND substring(your_column, 2, 1) IN (a, b, c, d)
             AND substring(your_column, 3, 1) IN (a, b, c, d)
             AND substring(your_column, 4, 1) IN (a, b, c, d);

然后像上面那样继续使用确切的方法进一步检查该结果。

只是一个想法...