Java - 对字符串列表中的字符串子集进行性能搜索

时间:2014-08-19 12:56:27

标签: java android string search

我想搜索字符串列表并返回包含搜索字符串的值。

列表可能如下所示(最多可包含1000个条目)。虽然不保证它总是字母然后是数字。它可能只是数字,只有单词,甚至两者都混合起来:

entry 1
entry 2
entry 3
entry 4
test 1
test 2
test 3
tst 4

如果用户搜索1,则应返回以下内容:

entry 1
test 1

情况是用户有一个搜索栏并可以输入搜索字符串。此搜索字符串用于搜索列表。

如何才能完成这项工作?

目前,我有:

for (String s : strings) {
    if (s.contains(searchedText))   result.add(s);
}

是O(N),真的很慢。特别是如果用户一次输入多个字符。

4 个答案:

答案 0 :(得分:0)

取决于字符串中数字的上限,如果您不关心空间,请使用ArrayLists数组,其中数组索引是字符串的数字:

ArrayList<String>[] data = new ArrayList<String>[1000];
for ( int i = 0; i < 1000; i++ )
  data[i] = new ArrayList<String>();

//inserting data
int num = Integer.parseInt(datastring.substring(datastring.length-1));
data[i].add(datastring);

//getting all data that has a 1
for ( String s: data[1] )
  result.add(s);

在尝试将新值放入其中时,使用Hashmap会覆盖先前的映射值。
即如果1映射到条目,那么您尝试添加1个映射以进行测试,该条目将被替换为test。

另外一个想法是,你可以只计算每个数字的字符串数量,所以当你进行搜索时,你知道要查找多少个字符串,所以一旦找到所有这些字符串,你就会停止搜索:

int[] str_count = new int[1000];
for ( int i = 0; i < 1000; i++ )
  str_count[i] = 0;

//when storing data into the list:
int num = Integer.parseInt(datastring.substring(datastring.length-1));
str_count[i]++;

//when searching the list for 1s:
int count = str_count[1];
for (String s : strings) {
  if (s.contains(searchedText))   
    result.add(s);
  if (result.size() == count)
    break;
}

虽然第一个想法会快得多,但会占用更多空间。然而,第二个想法占用的空间更少,最糟糕的情况是仍会搜索O(N)。

答案 1 :(得分:0)

也许我不明白你的问题,但正如你所知,Java对象是String不可变的,但也可以表示chars的集合(数组)。因此,您可以做的一件事就是使用更好的算法执行搜索binary_searchAho-CorasickRabin–KarpBoyer–Moore string searchStringSearchone of these 。此外,您可以考虑使用Abstract_data_types以获得更好的性能(哈希,树木等)。

答案 2 :(得分:0)

如果您使用流,这非常简单:

final List<String> items = Arrays.asList("entry 1", "entry 2", "entry 3", "test 1", "test 2", "test 3");
final String searchString = "1";
final List<String> results = items.parallelStream()  // work in parallel
        .filter(s -> s.contains(searchString))       // pick out items that match
        .collect(Collectors.toList());               // and turn those into a result list
results.forEach(System.out::println);

注意parallelStream(),它将导致使用所有可用CPU过滤和遍历列表。

在您的情况下,当用户展开搜索字词(在输入时)时,您可以使用results来减少需要过滤的项目数量,因为如果&#39;匹配结果中的所有项目,所有那些匹配&#39; se&#39;将是结果的子列表。

答案 3 :(得分:0)

如果您不使用任何其他结构,则无法比查看数据更快地执行。这需要O(N)。 如果您可以做一些准备工作,比如构建文本索引,则可以提高搜索性能。一般信息:http://en.wikipedia.org/wiki/Full_text_search。如果你可以对你的数据做一些假设(比如最后一个符号就是数字而你只能用它来搜索),那么创建这样的索引就很容易了。