n个字符串的交集

时间:2019-02-07 17:07:35

标签: java string algorithm

我正在开发一个程序来查找n个字符串的交集的字符。我编写以下代码:

import java.util.ArrayList;
import java.util.Scanner;
public class TestJoin {

public static void main(String[] args) {

  Scanner sc=new Scanner(System.in);


      int n=sc.nextInt();  // no of strings
      String s1 =sc.next().toLowerCase();
      ArrayList<Character> set1 = new ArrayList<Character>();
      while(n-->1)
      {
          String s2 =sc.next().toLowerCase();
          ArrayList<Character> set2 = new ArrayList<Character>();
          for(char c : s1.toCharArray()) {
                set1.add(c);
            }
          for(char c : s2.toCharArray()) {
                set2.add(c);
            }
          set1.retainAll(set2);
          for(char c : set1)
          {
              s1=Character.toString(c);
          }
      }
       for(char c :set1)
      System.out.println(c);


  }
}

当我尝试打印字符时,输出错误。

输入-

 3
 aabcde
 abazx
 yuabna

预期输出: aab

实际输出: aabb

2 个答案:

答案 0 :(得分:2)

使用单独的方法通常会使问题更小且更容易解决。

我建议您首先建立一种方法来计算2 String的交点,然后在while循环中使用它来计算输入字符串与当前交点的交点。 / p>

我试图保持您的逻辑,并且由于不确定List.retainAll的作用而写了自己的保留循环

此方法计算2 String的交集:

private static String intersectionOf(String s1, String s2) {
    List<Character> list1 = new ArrayList<>();
    for(char c : s1.toCharArray()) {
        list1.add(c);
    }
    List<Character> list2 = new ArrayList<>();
    for(char c : s2.toCharArray()) {
        list2.add(c);
    }

    StringBuilder intersection = new StringBuilder();
    for(Character c : list1) {
        if(list2.contains(c)) {
            intersection.append(c);
            list2.remove(c); // remove it so it is not counted twice
        }
    }
    return intersection.toString();
}

您现在可以在循环中使用它,逻辑看起来更简单

public static void main(String[] args) {
    Scanner sc=new Scanner(System.in);

    int n = sc.nextInt();  // no of strings

    String result = sc.next().toLowerCase();
    String s;
    while(n-- > 1) {
        s = sc.next().toLowerCase();
        result = intersectionOf(result, s);
    }
    for(char c : result.toCharArray())
        System.out.println(c);
}

答案 1 :(得分:1)

public static void intersect(String... input) {
    HashMap<Character, Integer> mins = new HashMap<Character, Integer>();
    HashMap<Character, Integer> current = new HashMap<Character, Integer>();

    for (String s : input) {
        current.clear();
        char[] chars = s.toCharArray();
        //Next loop remembers how many time every char occurs
        for (char c : chars) {
            Integer value = current.get(c);
            if (value == null) value = 0;
            current.put(c, value + 1);
        }

        if (mins.size() == 0) {
            mins.putAll(current); //First time just copy
        } else {
           //If not the first time then compare with previous results
            for (Character c : mins.keySet()) {
                Integer min = mins.get(c);
                Integer cur = current.get(c);
                if (cur != null) {
                    if (min > cur) {
                        //If has less than all previous
                        mins.put(c, cur);
                    }
                } else {
                    //If doesn't have at all
                    mins.put(c, 0);
                }
            }
        }
    }

    //Output every char that occurs in every string
    //more that 0 times
    for (Character c : mins.keySet()) {
        Integer count = mins.get(c);
        for (int i = 1; i <= count; i++) {
            System.out.print(c);
        }
    }
}

和调用:

public static void main(String[] args) {
   intersect("aabcdeabazx", "abazx", "yuabna");
}

您可以更改参数以将其作为数组传递。该算法的计算复杂度约为O(n)。