compare 2 string in jave with special character - java

how to compare 2 string with special character?
I have the string as below, may I know how to compare both?
strA = "AC-11234X-DD+++1"
strB = "AC-11234X-DD+++1"
I tested matches(), equals(), equalsIgnoreCase() all not working.
if (strA.matches(strB)){
...
} else {
..
}

This code checks if those two strings are equal or not
String strA = "AC-11234X-DD+++1" ;
String strB = "AC-11234X-DD+++1";
if(strA.equals(strB))
//they are equal
else
//they are not

why dont you try for
System.out.println(strA.hashCode()==strB.hashCode());
if matches(), equals(), equalsIgnoreCase() are not working.
incase you are not satisfied with this result also, you could try to overwrite the compareTo method and have your own logic.

public static void main(String[] args)
{
String strA = "AC-11234X-DD+++1";
String strB = "AC-11234X-DD+++1";
System.out.println(strA.equals(strB));
}
This works perfectly.

Must use the compareTo method.
The value returned by this method is an int:
if it is > 0 means that the second string precedes the first in alphabetical order
if it is = 0 means that two string are equal;
if it is < 0 means that the fisrt string precedes the second in alphabetical order
An example (very rough) about your problem might be this:
int r = A.compareTo(B);
if(r > 0) {
System.out.println("B comes before A in alphabetical order");
} else if(r < 0) {
System.out.println("A comes before B string in alphabetical order");
} else {
System.out.println("The two strings are equal");
}

Related

how to compare two strings to find common substring

i get termination due to timeout error when i compile. Please help me
Given two strings, determine if they share a common substring. A substring may be as small as one character.
For example, the words "a", "and", "art" share the common substring "a" . The words "be" and "cat" do not share a substring.
Input Format
The first line contains a single integer , the number of test cases.
The following pairs of lines are as follows:
The first line contains string s1 .
The second line contains string s2 .
Output Format
For each pair of strings, return YES or NO.
my code in java
public static void main(String args[])
{
String s1,s2;
int n;
Scanner s= new Scanner(System.in);
n=s.nextInt();
while(n>0)
{
int flag = 0;
s1=s.next();
s2=s.next();
for(int i=0;i<s1.length();i++)
{
for(int j=i;j<s2.length();j++)
{
if(s1.charAt(i)==s2.charAt(j))
{
flag=1;
}
}
}
if(flag==1)
{
System.out.println("YES");
}
else
{
System.out.println("NO");
}
n--;
}
}
}
any tips?
Below is my approach to get through the same HackerRank challenge described above
static String twoStrings(String s1, String s2) {
String result="NO";
Set<Character> set1 = new HashSet<Character>();
for (char s : s1.toCharArray()){
set1.add(s);
}
for(int i=0;i<s2.length();i++){
if(set1.contains(s2.charAt(i))){
result = "YES";
break;
}
}
return result;
}
It passed all the Test cases without a time out issue.
The reason for the timeout is probably: to compare two strings that each are 1.000.000 characters long, your code needs 1.000.000 * 1.000.000 comparisons, always.
There is a faster algorithm that only needs 2 * 1.000.000 comparisons. You should use the faster algorithm instead. Its basic idea is:
for each character in s1: add the character to a set (this is the first million)
for each character in s2: test whether the set from step 1 contains the character, and if so, return "yes" immediately (this is the second million)
Java already provides a BitSet data type that does all you need. It is used like this:
BitSet seenInS1 = new BitSet();
seenInS1.set('x');
seenInS1.get('x');
Since you're worried about execution time, if they give you an expected range of characters (for example 'a' to 'z'), you can solve it very efficiently like this:
import java.util.Arrays;
import java.util.Scanner;
public class Whatever {
final static char HIGHEST_CHAR = 'z'; // Use Character.MAX_VALUE if unsure.
public static void main(final String[] args) {
final Scanner scanner = new Scanner(System.in);
final boolean[] characterSeen = new boolean[HIGHEST_CHAR + 1];
mainloop:
for (int word = Integer.parseInt(scanner.nextLine()); word > 0; word--) {
Arrays.fill(characterSeen, false);
final String word1 = scanner.nextLine();
for (int i = 0; i < word1.length(); i++) {
characterSeen[word1.charAt(i)] = true;
}
final String word2 = scanner.nextLine();
for (int i = 0; i < word2.length(); i++) {
if (characterSeen[word2.charAt(i)]) {
System.out.println("YES");
continue mainloop;
}
}
System.out.println("NO");
}
}
}
The code was tested to work with a few inputs.
This uses a fast array rather than slower sets, and it only creates one non-String object (other than the Scanner) for the entire run of the program. It also runs in O(n) time rather than O(n²) time.
The only thing faster than an array might be the BitSet Roland Illig mentioned.
If you wanted to go completely overboard, you could also potentially speed it up by:
skipping the creation of a Scanner and all those String objects by using System.in.read(buffer) directly with a reusable byte[] buffer
skipping the standard process of having to spend time checking for and properly handling negative numbers and invalid inputs on the first line by making your own very fast int parser that just assumes it's getting the digits of a valid nonnegative int followed by a newline
There are different approaches to solve this problem but solving this problem in linear time is a bit tricky.
Still, this problem can be solved in linear time. Just apply KMP algorithm in a trickier way.
Let's say you have 2 strings. Find the length of both strings first. Say length of string 1 is bigger than string 2. Make string 1 as your text and string 2 as your pattern. If the length of the string is n and length of the pattern is m then time complexity of the above problem would be O(m+n) which is way faster than O(n^2).
In this problem, you need to modify the KMP algorithm to get the desired result.
Just need to modify the KMP
public static void KMPsearch(char[] text,char[] pattern)
{
int[] cache = buildPrefix(pattern);
int i=0,j=0;
while(i<text.length && j<pattern.length)
{
if(text[i]==pattern[j])
{System.out.println("Yes");
return;}
else{
if(j>0)
j = cache[j-1];
else
i++;
}
}
System.out.println("No");
return;
}
Understanding Knuth-Morris-Pratt Algorithm
There are two concepts involved in solving this question.
-Understanding that a single character is a valid substring.
-Deducing that we only need to know that the two strings have a common substring — we don’t need to know what that substring is.
Thus, the key to solving this question is determining whether or not the two strings share a common character.
To do this, we create two sets, a and b, where each set contains the unique characters that appear in the string it’s named after.
Because sets 26 don’t store duplicate values, we know that the size of our sets will never exceed the letters of the English alphabet.
In addition, the small size of these sets makes finding the intersection very quick.
If the intersection of the two sets is empty, we print NO on a new line; if the intersection of the two sets is not empty, then we know that strings and share one or more common characters and we print YES on a new line.
In code, it may look something like this
import java.util.*;
public class Solution {
static Set<Character> a;
static Set<Character> b;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
for(int i = 0; i < n; i++) {
a = new HashSet<Character>();
b = new HashSet<Character>();
for(char c : scan.next().toCharArray()) {
a.add(c);
}
for(char c : scan.next().toCharArray()) {
b.add(c);
}
// store the set intersection in set 'a'
a.retainAll(b);
System.out.println( (a.isEmpty()) ? "NO" : "YES" );
}
scan.close();
}
}
public String twoStrings(String sOne, String sTwo) {
if (sOne.equals(sTwo)) {
return "YES";
}
Set<Character> charSetOne = new HashSet<Character>();
for (Character c : sOne.toCharArray())
charSetOne.add(c);
Set<Character> charSetTwo = new HashSet<Character>();
for (Character c : sTwo.toCharArray())
charSetTwo.add(c);
charSetOne.retainAll(charSetTwo);
if (charSetOne.size() > 0) {
return "YES";
}
return "NO";
}
This must work. Tested with some large inputs.
Python3
def twoStrings(s1, s2):
flag = False
for x in s1:
if x in s2:
flag = True
if flag == True:
return "YES"
else:
return "NO"
if __name__ == '__main__':
q = 2
text = [("hello","world"), ("hi","world")]
for q_itr in range(q):
s1 = text[q_itr][0]
s2 = text[q_itr][1]
result = twoStrings(s1, s2)
print(result)
static String twoStrings(String s1, String s2) {
for (Character ch : s1.toCharArray()) {
if (s2.indexOf(ch) > -1)
return "YES";
}
return "NO";
}

Comparing Strings lexicographically new approach fails for one test case

I was asked to check whether String a is lexicographically larger String b. So even before thinking about compareTo() method I got a new idea.
Take the minimum of the lengths of both a & b.
Iterate a for loop till that minimum length and store the sum of ascii's of each characters in both a & b separately.
Compare the ascii's to print the result.
Here is my code
private static void isInLexicographicOrder(String a, String b) {
char[] arr1 = a.toCharArray();
int asciCount1 = 0;
char[] arr2 = b.toCharArray();
int asciCount2 = 0;
long asciLength = (a.length() < b.length()) ? a.length() : b.length();
for(int i=0; i<asciLength; i++) {
asciCount1 += arr1[i];
asciCount2 += arr2[i];
}
if(asciCount1 < asciCount2) {
System.out.println("In Lexicographic Order");
}
else {
System.out.println("Not In Lexicographic Order");
}
}
It is working fine for many inputs I provided, then I found this link String Comparison in Java, so for confirmation I used compare to method in my code.
System.out.println((a.compareTo(b)) < 0 ? "In Lexicographic Order" : "Not In Lexicographic Order");
Now when I submitted the code the other website is saying that the code is failing for one test case
Sample input
vuut
vuuuuu
They are want output to come as No ie, Not In Lexicographic Order. But my logic and the compareTo() logic says In Lexicographic Order. So whats wrong, Is my logic is completely correct?
This is the link where I got the Question. Sorry if I'm wrong
The comareTo method iterates over the characters of the two strings until it reaches a position where the two characters differ. The return-value is the difference between the two codepoint values.
Your implemenation adds all the codepoints to a sum and returns the difference of the result of this addition.
Try your method with the values abcd and dcba. I expect your method to return 0instead of a negative number
Your logic is not correct. Comparing the sums of the characters is wrong, since "bab", "abb" and "bba" will have the same value, but that tells you nothing regarding which of them comes first lexicographicaly.
You should compare each pair of characters separately. The first time you encounter a pair of characters not equal to each other, the one with the lower value belongs to the String that should come first.
for(int i=0; i<asciLength; i++) {
if (arr1[i] > arr2[i]) {
System.out.println("Not In Lexicographic Order");
return;
} else if (arr1[i] < arr2[i]) {
System.out.println("In Lexicographic Order");
return;
}
}
// at this point we know that the Strings are either equal or one
// is fully contained in the other. The shorter String must come first
if (arr1.length <= arr2.length) {
System.out.println("In Lexicographic Order");
} else {
System.out.println("Not In Lexicographic Order");
}

Java String Contains

I know that there are other questions like this and I did have a look at them but it did not work for me.
String one= "ROLEAWARDS ROLEMOVIES ROLENOMINATIONS";
String two = "ROLENOMINATIONS ROLEAWARDS ROLEMOVIES";
if(one.contains(two) || two.contains(one))
{
System.out.println("Contains");
}
else
System.out.println("Doesn't Contain");
This is my code and even though one contains two and two also contains one, it always prints that string one doesn't contain string two
You could do something like:
String one= "ROLEAWARDS ROLEMOVIES ROLENOMINATIONS";
String two = "ROLENOMINATIONS ROLEAWARDS ROLEMOVIES";
String oneArray[] = one.split("\\s+");
String twoArray[] = one.split("\\s+");
Arrays.sort(oneArray);
Arrays.sort(twoArray);
if(Arrays.equals(oneArray, twoArray))
{
System.out.println("Contains");
}
else
System.out.println("Doesn't Contain");
}
That's because you're comparing the whole String, and apparently you seem to be thinking it checks every substring split at the space which honestly doesn't work that way (it would be unintuitive too).
So,
String one= "ROLEAWARDS ROLEMOVIES ROLENOMINATIONS";
String two = "ROLENOMINATIONS ROLEAWARDS ROLEMOVIES";
String[] oneSplit = one.split(" ");
String[] twoSplit = two.split(" ");
boolean contains = false;
for(int i = 0; i < oneSplit.length; i++)
{
for(int j = 0; j < twoSplit.length; j++)
{
if(oneSplit[i].contains(twoSplit[j])
{
contains = true;
break;
}
}
}
if(contains)
{
System.out.println("Contains");
}
else
{
System.out.println("Doesn't Contain");
}
The contains() method returns true if and only if this string contains the specified sequence of char values. And in your code, the sequence of characters in each string is different from the other hence why in your code it returns false and prints that string one doesn't contain string two. The key thing here is the sequence of characters in each string.
.contains() function did not check they have common words or not.
It's check whether your one string is subset of other.
in your case both strings are not subset of each other
String one= "ROLEAWARDS ROLEMOVIES ROLENOMINATIONS";
String two= "ROLEMOVIES";
if(one.contains(two) || two.contains(one))
{
System.out.println("Contains");
}
else
System.out.println("Doesn't Contain");
Now it will print "Contains".
Plz read here in detail about .contain()
those two string are not same.
String one= "ROLEAWARDS ROLEMOVIES ROLENOMINATIONS";
String two = "ROLENOMINATIONS ROLEAWARDS ROLEMOVIES";
if(one.contains(two) || two.contains(one))
one.contains(two) will be true if two is a subset of one
two.contains(one) will be true if one is a subset of two
So the result is correct . as none of them is a subset of another.

Compare two long Strings

I want to compare two string who have those form
s1="1390785186301"
s2="1390785191301"
Shall I convert them to long and then compare with > or there are methods?
Consider using this natural comparator, in case you are not sure, if there are digits only in your string.
The problem with using a string comparison is that in a string compare 12 comes before 9, not after it.
You will need to convert it to either a long (if it fits within the range of a 64 bit integer) or a BigInteger and then do the comparison using them.
For the long do:
if (Long.parseLong(str1) > Long.parseLong(str2)) {
}
or:
int comparison = Long.compare(Long.parseLong(str1), Long.parseLong(str2));
The final option would be to do your own string comparator which scans from the start of the string comparing one digit at a time but if the strings are not equal length treats the shorter one as though it was left padded with 0.
If you want to compare two strings, just use the compareTo method
if(s1.length() == s2.length()){
if(s1.compareTo(s2) > 0) {//then s1 is greater...}
}
Take a look at the javadoc
String#compareTo
Here full ans
public class Comparetion {
public static void main(String args[]){
String s1="1390785186301";
String s2="1390785191301";
if (s1.compareTo(s2) == 0) {
System.out.println("s1 and S2 its same");
}
if (s1.compareTo(s2) > 0) {
System.out.println("S1 is bigger then s2");
}
if (s1.compareTo(s2) < 0) {
System.out.println("S2 is less then S1");
}
}
}
public class Comparetion {
public static void main(String args[]){
String s1="1390785186301";
String s2="1390785191301";
if (Long.parseLong(s1) < Long.parseLong(s2)) {
System.out.println("s1 is less then s2");
}
else if(Long.parseLong(s1) > Long.parseLong(s2)){
System.out.println("s1 is bigger then s2");
}
else{
System.out.println("s1 and s2 are same.");
}
}
}
two possibilities. but in the case of Compare to will get exceptional cases.
if (new Long(s1) > new Long(s2))
// do your thing
I see no reason for not creating longs for this.
Here's more info: http://docs.oracle.com/javase/6/docs/api/java/lang/Long.html#Long%28java.lang.String%29
Depending on what you need you can check if both strings contains exactly same value with equals method (assuming no leading zeroes and that both numbers are represented using same notation, for instance "101" and "1.01E2" represent same value but strings are not equal).
But if you want to check which string contains bigger value String doesn't provide much help. It has its own compareTo method but it is using alphabetic order, which may fail if
strings are not same length: just like ab will be placed before b in dictionary, same rule applies to "12" "2" which means that 12 < 2 using this order
we are comparing negative values: example 12 < 13 in alphabetic order, but it also means -12 < -13.
It is much easier and safer to convert strings to proper numeric type like Long, BigInteger or even BigDecimal and use appropriate methods, like compareTo.
Demo
String s1 = "1390785186301";
String s2 = "1390785191301";
System.out.println(Long.compare(Long.parseLong(s1), Long.parseLong(s2))); // -1
System.out.println(new BigInteger(s1).compareTo(new BigInteger(s2))); // -1
negative value for a.compareTo(b) indicates that a<b, 0 that a==b, positive that a>b
Demo 2:
BigDecimal bigDecimal = new BigDecimal("101");
BigDecimal bigDecimal2 = new BigDecimal("1.01E2");
System.out.println(bigDecimal.equals(bigDecimal2)); // true
System.out.println(bigDecimal.compareTo(bigDecimal2)); // 0

StringBuffer Append Space (" ") Appends "null" Instead

Basically what I'm trying to do is take a String, and replace each letter in the alphabet inside, but preserving any spaces and not converting them to a "null" string, which is the main reason I am opening this question.
If I use the function below and pass the string "a b", instead of getting "ALPHA BETA" I get "ALPHAnullBETA".
I've tried all possible ways of checking if the individual char that is currently iterated through is a space, but nothing seems to work. All these scenarios give false as if it's a regular character.
public String charConvert(String s) {
Map<String, String> t = new HashMap<String, String>(); // Associative array
t.put("a", "ALPHA");
t.put("b", "BETA");
t.put("c", "GAMA");
// So on...
StringBuffer sb = new StringBuffer(0);
s = s.toLowerCase(); // This is my full string
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
String st = String.valueOf(c);
if (st.compareTo(" ") == 1) {
// This is the problematic condition
// The script should just append a space in this case, but nothing seems to invoke this scenario
} else {
sb.append(st);
}
}
s = sb.toString();
return s;
}
compareTo() will return 0 if the strings are equal. It returns a positive number of the first string is "greater than" the second.
But really there's no need to be comparing Strings. You can do something like this instead:
char c = s.charAt(i);
if(c == ' ') {
// do something
} else {
sb.append(c);
}
Or even better for your use case:
String st = s.substring(i,i+1);
if(t.contains(st)) {
sb.append(t.get(st));
} else {
sb.append(st);
}
To get even cleaner code, your Map should from Character to String instead of <String,String>.
String.compareTo() returns 0 if the strings are equal, not 1. Read about it here
Note that for this case you don't need to convert the char to a string, you could do
if(c == ' ')
use
Character.isWhitespace(c)
that solves the issue. Best practice.
First, of all, what is s in this example? It's hard to follow the code. Then, your compareTo seems off:
if (st.compareTo(" ") == 1)
Should be
if (st.compareTo(" ") == 0)
since 0 means "equal" (read up on compareTo)
From the compareTo documentation: The result is a negative integer if this String object lexicographically precedes the argument string. The result is a positive integer if this String object lexicographically follows the argument string. The result is zero if the strings are equal;
You have the wrong condition in if (st.compareTo(" ") == 1) {
The compareTo method of a String returns -1 if the source string precedes the test string, 0 for equality, and 1 if the source string follows. Your code checks for 1, and it should be checking for 0.

Categories