【问题标题】:java- removing substring in a list of stringsjava-删除字符串列表中的子字符串
【发布时间】:2016-07-12 05:11:45
【问题描述】:

考虑字符串列表的情况 例如:list=['apple','bat','cow,'dog','applebat','cowbat','dogbark','help']

java 代码必须检查 string 的任何元素是否是另一个元素的子集,如果是,则必须删除更大的 string 元素。

所以在这种情况下,字符串“applebat”、“cowbat”、“dogbark”被删除了。

我采用的方法是获取两个列表并以下列方式遍历它们,

ArrayList<String> list1 = new ArrayList<String>(strings);
ArrayList<String> list2 = new ArrayList<String>(strings);
for(int i = 0; i<list1.size();i++)
    {
        String curr1 = list1.get(i);

        for(int j = 0;j<list2.size();j++)
        {
            String curr2 = list2.get(j);

            if(curr2.contains(curr1)&&!curr2.equals(curr1))
            {
                list2.remove(j);
                j--;
        }
        }
    }

重要提示 我有 200K 到 400K 元素大小的列表。我想找到一种方法来提高性能。我什至尝试过哈希集,但它们并没有太大帮助。我遇到了程序花费的时间问题。

任何人都可以建议对我的代码或 java 中的任何其他方法进行任何改进以提高性能吗?

【问题讨论】:

  • 我认为您不能在迭代时简单地删除它们。您可以做的是取一个否定条件,然后将其添加到另一个 arrayList
  • 尝试HashSet 并检查contains 并删除使用remove 方法。Set 将给我们O(1)(假设的)运行时。
  • 我尝试了一小部分字符串并且代码很好,但是当列表变得非常大时,它需要花费大量时间来处理,我不想重复它 n 次开机 n 次两个列表。我想动态减少这两个列表,以便我可以删除很多比较。

标签: java arraylist hashset


【解决方案1】:
import java.util.ArrayList;
import java.util.*;
// our main class becomes a file but the main method is still found
public class HelloWorld
{
  public static void main(String[] args)
  {
    String[] strings = {"apple","bat","cow","dog","applebat","cowbat","dogbark","help"};
    ArrayList<String> list1 = new ArrayList<String>(Arrays.asList(strings));
ArrayList<String> list2 = new ArrayList<String>(Arrays.asList(strings));
ArrayList<String> result = new ArrayList<String>(Arrays.asList(strings));
for(int i = 0; i<8;i++)
{

    String curr1 = list1.get(i);
    System.out.println(curr1);
    int flag = 0;
    for(int j = i+1;j<8;j++)
    {
        String curr2 = list2.get(j);

        if((curr2.contains(curr1)&&!curr2.equals(curr1)))
        {

            result.remove(curr2);
        }
    }

}
 System.out.println(result);

  }
}

【讨论】:

  • 解释一下就好了
  • 我已经检查了否定条件,即它是否等于或不包含任何子字符串标志将变为 1。经过一次迭代,我们将其添加到结果中。最后你可以删除 list1 和 list2 对象
【解决方案2】:

如果您愿意实现如此复杂的逻辑,我认为您需要 sort 和 string searching algorithm(例如 Aho–Corasick algorithm)的组合来全面提升大量单词的性能。

首先,按长度对单词进行排序。

然后按字长顺序构建 Aho–Corasick 词典。对于每个单词,首先检查字典中是否存在子字符串。如果是,则跳过该词,否则将该词添加到字典中。

完成后,转储字典,如果字典不容易/可能转储,则转储并行维护的列表。

【讨论】:

    【解决方案3】:

    我想 set 在这里会更快。 您可以使用 java8 流 api 轻松做到这一点。

    试试看:

    private Set<String> delete() {
            Set<String> startSet = new HashSet<>(Arrays.asList("a", "b", "c", "d", "ab", "bc", "ce", "fg"));
            Set<String> helperSet = new HashSet<>(startSet);
    
            helperSet.forEach(s1 -> helperSet.forEach(s2 -> {
                if (s2.contains(s1) && !s1.equals(s2)) {
                    startSet.remove(s2);
                }
            }));
    
            return startSet;
        }
    

    不要从您正在迭代的集合中删除任何元素,否则您将遇到 ConcurrentModificationException。

    【讨论】:

      【解决方案4】:
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.Date;
      import java.util.List;
      import java.util.Random;
      
      public class SubStrRmove {
          public static List<String> randomList(int size) {
              final String BASE = "abcdefghijklmnopqrstuvwxyz";
              Random random = new Random();
              List<String> list = new ArrayList<>();
              for (int i = 0; i < size; i++) {
                  int length = random.nextInt(3) + 2;
                  StringBuffer sb = new StringBuffer();
                  for (int j = 0; j < length; j++) {
                      int number = random.nextInt(BASE.length());
                      sb.append(BASE.charAt(number));
                  }
                  list.add(sb.toString());
                  sb.delete(0, sb.length());
              }
              return list;
          }
      
          public static List<String> removeListSubStr(List<String> args) {
              String[] input = args.toArray(new String[args.size()]);
              Arrays.parallelSort(input, (s1, s2) -> s1.length() - s2.length());
              List<String> result = new ArrayList<>(args.size());
              for (int i = 0; i < input.length; i++) {
                  String temp = input[i];
                  if (!result.stream().filter(s -> temp.indexOf(s) >= 0).findFirst().isPresent()) {
                      result.add(input[i]);
                  }
              }
              return result;
          }
      
          public static List<String> removeListSubStr2(List<String> args) {
              String[] input = args.toArray(new String[args.size()]);
              Arrays.parallelSort(input, (s1, s2) -> s1.length() - s2.length());
              List<String> result = new ArrayList<>(args.size());
              for (int i = 0; i < input.length; i++) {
                  boolean isDiff = true;
                  for (int j = 0; j < result.size(); j++) {
                      if (input[i].indexOf(result.get(j)) >= 0) {
                          isDiff = false;
                          break;
                      }
                  }
                  if (isDiff) {
                      result.add(input[i]);
                  }
              }
              return result;
          }
      
          public static void main(String[] args) throws InterruptedException {
              List<String> list = randomList(20000);
              Long start1 = new Date().getTime();
              List<String> listLambda = removeListSubStr(list);
              Long end1 = new Date().getTime();
              Long start2 = new Date().getTime();
              List<String> listFor = removeListSubStr2(list);
              Long end2 = new Date().getTime();
              System.out.println("mothod Labbda:" + (end1 - start1) + "ms");
              System.out.println("mothod simple:" + (end2 - start2) + "ms");
              System.out.println("" + listLambda.size() + listLambda);
              System.out.println("" + listFor.size() + listFor);
      
          }
      
      }
      

      【讨论】:

        【解决方案5】:

        我已经在小数据上进行了测试,希望它可以帮助您找到解决方案...

        import java.util.ArrayList;
        import java.util.Arrays;
        
        public class Main {
            public static void main(String[] args){
                String []list = {"apple","bat","cow","dog","applebat","cowbat","dogbark","help","helpless","cows"};
                System.out.println(Arrays.toString(list));
                int prelenght = 0;
                int prolenght = 0;
                long pretime = System.nanoTime();
                for(int i=0;i<list.length;i++){
                    String x = list[i];
                    prelenght = list[i].length();
                    for(int j=i+1;j<list.length;j++){               
                        String y = list[j];
                        if(y.equals(x)){
                            list[j] = "0";
                        }else if(y.contains(x)||x.contains(y)){
                            prolenght = list[j].length();                   
                            if(prelenght<prolenght){
                                list[j] = "0";
                            }                       
                            if(prelenght>prolenght){
                                list[i] = "0";
                                break;
                            }
                        }
                    }
                }       
                long protime = System.nanoTime();
                long time = (protime - pretime);
                System.out.println(time + "ns");
                UpdateArray(list);      
            }
        
            public static void UpdateArray(String[] list){
                ArrayList<String> arrayList = new ArrayList<>();
                for(int i=0;i<list.length;i++){
                    if(!list[i].equals("0")){
                        arrayList.add(list[i]);
                    }
                }
                System.out.println(arrayList.toString());
            }
        }
        

        输出:

        [apple, bat, cow, dog, applebat, cowbat, dogbark, help, helpless, cows]
        time elapsed : 47393ns
        [apple, bat, cow, dog, help]
        

        【讨论】:

          猜你喜欢
          • 2021-06-24
          • 2023-04-09
          • 2015-04-23
          • 2013-08-20
          • 2021-12-28
          • 2015-11-20
          • 2012-04-18
          相关资源
          最近更新 更多