Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I find the characters common to two strings in Java using single replaceAll?

So suppose I have:

String s = "1479K";
String t = "459LP";

and I want to return

String commonChars = "49";

the common characters between the two strings.

Obviously it is possible to do with a standard loop like:

String commonChars = "";
for (i = 0; i < s.length; i++)
{
    char ch = s.charAt(i);
    if (t.indexOf(ch) != -1)
    {
        commonChars = commonChars + ch;
    }
}

However I would like to be able to do this in one line using replaceAll. This can be done as follows:

String commonChars = s.replaceAll("["+s.replaceAll("["+t+"]","")+"]","");

My question is: is it possible to do this using a single invocation of replaceAll? And what would be the regular expression? I presume I have to use some sort of lookahead, but my brain turns to mush when I even think about it.

like image 949
Adam Burley Avatar asked Nov 17 '10 11:11

Adam Burley


People also ask

How do you find the common character between two strings?

Approach: Count the frequencies of all the characters from both strings. Now, for every character if the frequency of this character in string s1 is freq1 and in string s2 is freq2 then total valid pairs with this character will be min(freq1, freq2). The sum of this value for all the characters is the required answer.

How do I check if two strings have the same characters Java?

equals()method compare two Strings for content equality. So if two string contains the same letters, in the same order and in some case they will be equals by equals() method. equals() method is defined in Object class and String class overrides that for character-based comparison.

What do the replaceAll () do?

The replaceAll() method returns a new string with all matches of a pattern replaced by a replacement . The pattern can be a string or a RegExp , and the replacement can be a string or a function to be called for each match.

How do you know if two strings s1 and s2 have the same value?

Using String. equals() :In Java, string equals() method compares the two given strings based on the data/content of the string. If all the contents of both the strings are same then it returns true. If any character does not match, then it returns false.


2 Answers

String commonChars = s.replaceAll("[^"+t+"]","");

Note that you may need to escape special characters in t, e.g. using Pattern.quote(t) instead of t above.

like image 145
vitaut Avatar answered Oct 19 '22 22:10

vitaut


The accepted answer:

String commonChars = s.replaceAll("[^"+t+"]","");

has a bug!!!

What if the string t has a regex meta-character? In that case the replaceAll fails.

See this program as an example where the string t has ] in it and ] is a regex meta-character which marks the end of the character class. Clearly the program does not produce the expected output.

Why?

Consider:

String s = "1479K";
String t = "459LP]";

Now the regex will become(just substitute t):

String commonChars = s.replaceAll("[^459LP]]","");

Which says replace any character other than 4,5,9,L,P followed by a ] with nothing. Which is clearly not what you want.

To fix these you need to escape the ] in t. You can do it manually as:

String t = "459LP\\]";

and the regex works fine.

This is a common problem when using regex, so the java.util.regex.Pattern class provides a static method named quote which can be used to do exactly this: quote the regex-metacharacters so that they are treated literally.

So before using t in replaceAll you quote it as:

t = Pattern.quote(t);

Program using quote method works as expected.

like image 44
codaddict Avatar answered Oct 19 '22 21:10

codaddict