查找包含子字符串的Arraylist的所有字符串的有效方法

时间:2015-05-06 10:37:12

标签: java regex string arraylist

我有一个字符串,说a="1.1"和一个arraylist,比如list,其中包含字符串:"1.1.1.1", "1.1.2.4","1.2,1.3","1.5.1.1"

现在,我想从这个arraylist中获取字符串,它在开头包含字符串a =“1.1”,这意味着a是这些字符串的子字符串,需要从头开始匹配。

因此,对于这种情况,答案将是1.1.1.11.1.2.4,而不是1.5.1.1,因为此处1.1不在开头。

我知道,如何实现这一点,但我认为我的解决方案效率不高,对于大型的arraylist,它需要更多的处理时间。

我的方法: 为arraylist和每个字符串运行for循环,从头开始用a的长度裁剪字符串,并检查裁剪的字符串是否等于a。

但是如果我想为一个大型的arraylist重复几个字符串,我认为这不是一个好的解决方案。

有什么想法吗?我将非常感谢你的帮助。

7 个答案:

答案 0 :(得分:6)

此方法可行:

.l-region--navigation{
  position: fixed;
  top: 0px;
  right: 0px;
  visibility: hidden;
  background-color: #cccccc; // Old browsers
  @include filter-gradient(#cccccc, #cccccc, vertical); // IE6-9
  @include background-image(linear-gradient(top,  #cccccc 0%,#ededed 62%,#cccccc 100%));
  transition: 0.5s ease;
  -webkit-transition: 0.5s ease;
  -moz-transition: 0.5s ease;
  @include span (6 of 9);
  @include bleed($grid-padding);
 }

 .l-region--navigation.show{
  visibility: visible;
  transition: 0.5s ease;
  -webkit-transition: 0.5s ease;
  -moz-transition: 0.5s ease;
 }

如果你可以使用Java 8,它会更短:

public static List<String> findWithPrefix(List<String> list, String prefix) {
    List<String> result = new ArrayList<>();
    for(String s : list)
        if(s.startsWith(prefix))
            result.add(s);
    return result;
}

答案 1 :(得分:3)

您可以随时使用startsWith(String s)类中的String方法。

e.g。

for(String s : list){
 if(s.startsWith(a)){
    System.out.println(s);
 }
}

答案 2 :(得分:3)

如果您想浏览列表并提取所有以1.1开头的字符串,那么使用startsWith(String subString)应该可以满足您的需求。您可以使用Java 8 Collection.parallelStream().forEach...

另一方面,如果你想进行多次搜索,每次看到哪个字符串以不同的子字符串开头开头为关键字在这里),你可以看一下suffix trees

后缀树将以树的方式索引所有字符串。这样,您可以从根节点开始搜索树,然后,一旦找到满足条件的节点,您只需继续浏览它的子节点即可获得字符串。

                root
              / |  \
             1  2   3
          / |
         .  0
    /   |
   1    2
   |    |
   [1.1] [1.2]

方括号中的值表示找到的子字符串的位置,在您的情况下,它将包含整个字符串。

答案 3 :(得分:1)

这是一个想法,但我不知道它是否足够有效。如何以某种方式连接所有元素,以便您可以找出哪个项目: 例如:

{0:1.1.2.4},{1:1.2.1.3},...

然后对字符串运行一个正则表达式查询,该字符串返回以{开头并以}结尾的所有子字符串,并以1.1开头。您可以定义一个命名组以包含索引号,这样您就可以拥有所有子字符串一次运行中的索引。

答案 4 :(得分:1)

List<String> result=new ArrayList<String>():
for(String s : list){
 if(s.startsWith("1.1")){
    result.add(s);
 }
}
for(String s : list){
System.out.println(s);
}

答案 5 :(得分:1)

你想要一些优化的解决方案,所以你可以试试这个:

  
      
  1. 借助Collections.sort(list);
  2. 对列表进行排序   
  3. 在二进制搜索的帮助下找到第一个匹配的字符串,并标记带有此前缀的字符串。
  4.   
  5. 现在如果下一个字符串与此前缀不匹配,则意味着没有下一个列表字符串将匹配此前缀,因为我们已对集合进行了排序
  6.   

试试这段代码:

package test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class T { 
    static int count=0;     
    public static void main(String[] args) {    
        List<String> list = new ArrayList<String>();

       // for testing purpose only i am making this list and putting this data
        for (int i = 101; i < 501; i++) {
            list.add(i + "");
        }
        boolean matchedSuffix = false;
        String prefix = "30";

        Collections.sort(list);

        int startFrom = T.binarySerchOverList(list, prefix);

        if (startFrom == -1) {
            System.out.println("no data found");
        } else {
                for (int i = startFrom;; i++) {
                String s = list.get(i);
                if (s.startsWith(prefix)) {                     
                    //here you will get matching strings                    
                    System.out.println(s);
                    matchedSuffix = true;
                } else {
                    if (matchedSuffix) {
                        break;
                    }
                }

            }
        }    
    }

    public static int binarySerchOverList(List<String> input, String prefix) {    
        count++;
        System.out.println( "iteration count is "+count);       
        int size = input.size();
        int midpoint = size / 2;
        int startPoint = 0;

        String stringToTest = input.get(midpoint);
        if (stringToTest.startsWith(prefix)) {
            startPoint = midpoint - 1;
            while (true) {

                if (!input.get(startPoint).startsWith(prefix)) {
                    startPoint++;
                    break;
                }
                if (startPoint == 0) {
                    break;
                }   
                startPoint--;
            }   
            return startPoint;
        }

        if (stringToTest.compareTo(prefix) > 0) {
            List<String> sublist = input.subList(0, midpoint);
            return binarySerchOverList(sublist, prefix);
        }

        if (stringToTest.compareTo(prefix) < 0) {    
            if (input.get(input.size() - 1).compareTo(prefix) < 0) {
                return -1;
            }
            List<String> sublist = input.subList(midpoint, input.size());
            return binarySerchOverList(sublist, prefix);
        }    
        return 0;    
    }    
}

问我是否对代码有疑问

答案 6 :(得分:0)

是否必须是ArrayList?你能把字符串放到像NavigableSet这样的TreeSet

TreeSet<String> strings = ...;

Set<String> startWith1_1 = strings.subSet("1.1", "1.2");