Пересечение двух строк в Java - PullRequest
13 голосов
/ 15 декабря 2010

Нужна функция Java, чтобы найти пересечение двух строк.т.е. символы, общие для строк.

Пример:

String s1 = new String("Sychelless");
String s2 = new String("Sydney");

Ответы [ 10 ]

22 голосов
/ 15 декабря 2010

Использование HashSet<Character>:

HashSet<Character> h1 = new HashSet<Character>(), h2 = new HashSet<Character>();
for(int i = 0; i < s1.length(); i++)                                            
{
  h1.add(s1.charAt(i));
}
for(int i = 0; i < s2.length(); i++)
{
  h2.add(s2.charAt(i));
}
h1.retainAll(h2);
Character[] res = h1.toArray(new Character[0]);

Это O(m + n), что является асимптотически оптимальным.

8 голосов
/ 15 декабря 2010

Извлечение символов

String.toCharArray

Положите их в набор Найти пересечение

Set.retainAll
5 голосов
/ 15 декабря 2010

Самый простой подход:

String wordA = "Sychelless";  
String wordB = "Sydney";  
String common = "";  

for(int i=0;i<wordA.length();i++){  
    for(int j=0;j<wordB.length();j++){  
        if(wordA.charAt(i)==wordB.charAt(j)){  
            common += wordA.charAt(i)+" ";  
            break;
        }  
    }  
}  
System.out.println("common is: "+common);  
3 голосов
/ 15 декабря 2010

Более подробно об ответе Саугаты (появился, когда я писал это): -

public static void main(String[] args) {
    String s1 = "Seychelles";
    String s2 = "Sydney";
    Set<Character> ss1 = toSet(s1);
    ss1.retainAll(toSet(s2));
    System.out.println(ss1);
}

public static Set<Character> toSet(String s) {
    Set<Character> ss = new HashSet<Character>(s.length());
    for (char c : s.toCharArray())
        ss.add(Character.valueOf(c));
    return ss;
}
2 голосов
/ 15 декабря 2010

Я думаю, что алгоритм, который вы ищете - это проблема самой длинной общей подпоследовательности

1 голос
/ 12 января 2019

Оптимизированное решение :

public static String twoStrings(String s1, String s2){

    HashSet<Character> stringOne =  new HashSet<Character>(), stringTwo = new HashSet<Character>();  
    int stringOneLength = s1.length();
    int stringTwoLength = s2.length();
    for(int i=0; i<stringOneLength || i<stringTwoLength; i++) {
        if(i < stringOneLength)
            stringOne.add(s1.charAt(i));
        if(i < stringTwoLength)
            stringTwo.add(s2.charAt(i));
    }
    stringOne.retainAll(stringTwo);

    return stringOne.toString();
}
1 голос
/ 15 декабря 2010
0 голосов
/ 23 июля 2017

Я использовал TreeSet. И retainAll() в TreeSet для получения согласованных элементов.

Oracle Doc:

retainAll(Collection<?> c)

Сохраняет только элементы этого набора, которые содержатся в указанная коллекция (необязательная операция).

String s1 = new String("Sychelless");
String s2 = new String("Sydney");

Set<Character> firstSet = new TreeSet<Character>();
for(int i = 0; i < s1.length(); i++) {
    firstSet.add(s1.charAt(i));
}

Set<Character> anotherSet = new TreeSet<Character>();
for(int i = 0; i < s2.length(); i++) {
    anotherSet.add(s2.charAt(i));
}

firstSet.retainAll(anotherSet);
System.out.println("Matched characters are " + firstSet.toString());//print common strings

//output > Matched characters are [S, e, y]
0 голосов
/ 28 марта 2013

С помощью Guava эта задача кажется намного проще:

String s1 = new String("Sychelless");
String s2 = new String("Sydney");
Set<String> setA = Sets.newHashSet(Splitter.fixedLength(1).split(s1));
Set<String> setB = Sets.newHashSet(Splitter.fixedLength(1).split(s2));
Sets.intersection(setA, setB);
0 голосов
/ 15 декабря 2010
s1.contains(s2) returns true;
s1.indexOf(s2) returns 0. 
s1.indexOf("foo") returns -1

Для более сложных случаев используйте класс Pattern.

...