【问题标题】:String matching with tokenizing the key of a map与标记化地图键的字符串匹配
【发布时间】:2019-03-01 09:59:39
【问题描述】:

我的 Dynamo DB 中有一张地图,存储方式如下:

"A|1,2,3,4|B" : "[some data]"
"C|5,6|D" : "[some data]"
"X|7,8,9,10,11,12,13|Y" : "[some data]"
 ..

为了便于讨论,假设上图中的每个键都是 LEFT、MIDDLE 和 RIGHT 三个字符串的串联结果,如:“LEFT|MIDDLE|RIGHT”。

我想知道给定的字符串是否是上图中的键。但是,中间字符串应该按此匹配的逗号值拆分。 示例:“A|1|B”和“A|3|B”都应该与第一个条目匹配。类似地,“C|5|D”匹配第二个条目,依此类推。

假设:MIDDLE 字符串可以是 1 到 200 个数字的串联(存储为字符串)。该地图有大约 35,000 个条目。

我想一种直接的方法是“扩展”原始映射并分解中间字符串上的每个条目以创建多个具有重复值的新键值对。但是,我的数据量很大,因此这种方法会花费大量的时间和空间复杂性。有没有一种优雅的方法可以在生产环境中解决这个问题?

【问题讨论】:

  • 我们是否可以假设第一行中的[某些数据]通常不等于第二行和第三行中的[某些数据]等?
  • “LEFT”和“RIGHT”总是“A”和“B”吗?
  • 中键使用trie 怎么样?
  • MIDDLE 是否总是整数的连续区间?
  • @Boris 是的,“[某些数据]”对于所有条目都是唯一的。

标签: java algorithm data-structures


【解决方案1】:

我会用一些随机字符串替换 MIDDLE,例如

"A|4806369425|B" : "[some data M]"
"A|0848833569|B" : "[some data N]"
"A|5514390566|B" : "[some data P]"

添加另一个映射

"1" : "4806369425"
"2" : "4806369425"
"3" : "4806369425"
"4" : "4806369425"
"5" : "0848833569"
"6" : "0848833569"
"7" : "5514390566"
"8" : "5514390566"
"9" : "5514390566"
...
"13" : "5514390566"

当获取一个值时,我会去第二个映射找到中间的键。它应该在 O(1) 中执行,然后将左右连接并在 O(1) 中再次从第一个映射中获取一些数据

【讨论】:

  • 请注意:使用UUID.randomUUID().toString()可以实现随机字符串
【解决方案2】:

您可以尝试类似的方法(未经测试的代码):

String testString = "A|1,2,3,4|B"

String primarySeparator = "|";
String secondarySeparator = ",";

public boolean contains(String key) {
  String[] parts = testString.split(primarySeparator);
  List<String> values = Arrays.asList(parts[1].split(secondarySeparator)); // Point 1

  String[] keyParts = key.split(primarySeparator);

  if (keyParts[0].equals(parts[0])
    && keyParts[2].equals(parts[2]
    && values.contains(keyParts[1])) { // Point 2
    return true;
  } else {
    return false;
  }
}

标记为“Point 1”的行使用“|”分割字符串分隔符,选择第二个值,这是您的数字列表,使用“,”分隔符将其拆分并将其转换为列表。因此,您会得到一个列表,其中包含您在“MIDDLE”中的所有值。

然后,在“第 2 点”,我们测试匹配。

请记住,此代码未经测试,不关心意外情况,例如如果您的字符串没有正确数量的由“|”分隔的部分或者如果您的值列表不包含任何值。您可能需要调整以将这些情况考虑在内。

如果你想测试大量的行,你当然应该只拆分一次密钥。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多