Compare two long Strings - java

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

Related

How to handle the time complexity for permutation of strings during anagrams search?

I have a program that computes that whether two strings are anagrams or not.
It works fine for inputs of strings below length of 10.
When I input two strings whose lengths are equal and have lengths of more than 10 program runs and doesn't produce an answer .
My concept is that if two strings are anagrams one string must be a permutation of other string.
This program generates the all permutations from one string, and after that it checks is there any matching permutation for the other string. In this case I wanted to ignore cases.
It returns false when there is no matching string found or the comparing strings are not equal in length, otherwise returns true.
public class Anagrams {
static ArrayList<String> str = new ArrayList<>();
static boolean isAnagram(String a, String b) {
// there is no need for checking these two
// strings because their length doesn't match
if (a.length() != b.length())
return false;
Anagrams.permute(a, 0, a.length() - 1);
for (String string : Anagrams.str)
if (string.equalsIgnoreCase(b))
// returns true if there is a matching string
// for b in the permuted string list of a
return true;
// returns false if there is no matching string
// for b in the permuted string list of a
return false;
}
private static void permute(String str, int l, int r) {
if (l == r)
// adds the permuted strings to the ArrayList
Anagrams.str.add(str);
else {
for (int i = l; i <= r; i++) {
str = Anagrams.swap(str, l, i);
Anagrams.permute(str, l + 1, r);
str = Anagrams.swap(str, l, i);
}
}
}
public static String swap(String a, int i, int j) {
char temp;
char[] charArray = a.toCharArray();
temp = charArray[i];
charArray[i] = charArray[j];
charArray[j] = temp;
return String.valueOf(charArray);
}
}
1. I want to know why can't this program process larger strings
2. I want to know how to fix this problem
Can you figure it out?
To solve this problem and check whether two strings are anagrams you don't actually need to generate every single permutation of the source string and then match it against the second one. What you can do instead, is count the frequency of each character in the first string, and then verify whether the same frequency applies for the second string.
The solution above requires one pass for each string, hence Θ(n) time complexity. In addition, you need auxiliary storage for counting characters which is Θ(1) space complexity. These are asymptotically tight bounds.
you're doing it in very expensive way and the time complexity here is exponential because your'e using permutations which requires factorials and factorials grow very fast , as you're doing permutations it will take time to get the output when the input is greater than 10.
11 factorial = 39916800
12 factorial = 479001600
13 factorial = 6227020800
and so on...
So don't think you're not getting an output for big numbers you will eventually get it
If you go something like 20-30 factorial i think i will take years to produce any output , if you use loops , with recursion you will overflow the stack.
fact : 50 factorial is a number that big it is more than the number of sand grains on earth , and computer surrender when they have to deal with numbers that big.
That is why they make you include special character in passwords to make the number of permutations too big that computers will not able to crack it for years if they try every permutations , and encryption also depends on that weakness of the computers.
So you don't have to and should not do that to solve it (because computer are not good very at it), it is an overkill
why don't you take each character from one string and match it with every character of other string, it will be quadratic at in worst case.
And if you sort both the strings then you can just say
string1.equals(string2)
true means anagram
false means not anagram
and it will take linear time,except the time taken in sorting.
You can first get arrays of characters from these strings, then sort them, and then compare the two sorted arrays. This method works with both regular characters and surrogate pairs.
public static void main(String[] args) {
System.out.println(isAnagram("ABCD", "DCBA")); // true
System.out.println(isAnagram("𝗔𝗕𝗖𝗗", "𝗗𝗖𝗕𝗔")); // true
}
static boolean isAnagram(String a, String b) {
// invalid incoming data
if (a == null || b == null
|| a.length() != b.length())
return false;
char[] aArr = a.toCharArray();
char[] bArr = b.toCharArray();
Arrays.sort(aArr);
Arrays.sort(bArr);
return Arrays.equals(aArr, bArr);
}
See also: Check if one array is a subset of the other array - special case

String method to return the first string from a string array by alphabetic order

I have a problem in understanding how the following code is executed. I am seeking an example for 1/2 executions.
Code is:
public class StringArray {
public static String getFirstString(String[] values) {
if (values.length == 0) {
return "";
}
String result = values[0];
for (int i=1; i<values.length; i++) {
if (result.compareTo(values[i]) > 0) {// i.e. result > values[i]
result = values[i];
}
}
return result;
}
public static void main(String[] args) {
String[] nume= {"Andrei", "Andreea", "Andrea",
"Marius", "Marcus", "Marcel", "Florin"};
System.out.println(getFirstString(nume));
}
}
Basically, is the first item processed?
First is Andrei.
1.Andrei will get into the first If? values.length should not be 7?
1.1 "value" being the reference of the parameter, should point to the array[] name which is given in the main method, right?
Therefore, Andrei will be compared to Andreea, but from here, why is Andrei bigger than Andreea? I have a hard time with the if (result.compareTo(values[i]) > 0).
The key element here: understanding the "contract" of the compareTo() method.
Start by looking at the javadoc:
Compares two strings lexicographically. The comparison is based on the Unicode value of each character in the strings. The character sequence represented by this String object is compared lexicographically to the character sequence represented by the argument string. 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; compareTo returns 0 exactly when the equals(Object) method would return true.
This is the definition of lexicographic ordering. If two strings are different, then either they have different characters at some index that is a valid index for both strings, or their lengths are different, or both. If they have different characters at one or more index positions, let k be the smallest such index; then the string whose character at position k has the smaller value, as determined by using the < operator, lexicographically precedes the other string. In this case, compareTo returns the difference of the two character values at position k in the two string -- that is, the value:
this.charAt(k)-anotherString.charAt(k)
If there is no index position at which they differ, then the shorter string lexicographically precedes the longer string. In this case, compareTo returns the difference of the lengths of the strings -- that is, the value:
this.length()-anotherString.length()

compare 2 string in jave with special character

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");
}

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.

Why my parsing doesn't work?

I was asked for my homework to make a program wherein the user inputs a Roman numerals between 1-10 and outputs the decimal equivalent. Since I'll be getting a string in the input and an integer in the output, I parsed it, but it won't work. Any ideas why?
import java.util.Scanner ;
class Romans {
static Scanner s = new Scanner(System.in) ;
static String val = null ;
public static void main (String [] args)
{
System.out.print ("Enter a roman numeral between I to X: ");
String val = s.nextLine();
int e = Integer.parseInt(val);
}
static int getRoman (int e)
{
if (val = "I"){
System.out.print ("1") ;
}else if (val = "II" ){
System.out.print ("2") ;
}else if (val = "III") {
System.out.print ("3") ;
} else if (val = "IV") {
System.out.print ("4") ;
} else if (val = "V"){
System.out.print ("5");
} else if (val = "VI") {
System.out.print ("6");
} else if (val = "VII") {
System.out.print ("7");
} else if (val = "VIII") {
System.out.print ("8");
} else if (val = "IX") {
System.out.print ("9");
} else if (val = "X") {
System.out.print ("10") ;
}
return val ;
}
}
Two points:
= is the assignment operator, not the equality-testing operator (==)
You shouldn't use == to test for string equality anyway, as it will only test for reference equality; use equals to test whether two string references refer to equal (but potentially distinct) string objects.
Additionally, you're trying to return a String variable as an int, and you're not even calling getRoman...
I think we can tell you that the correct way to compare Strings is using equals().
You're doing assignments, to compare primitive types you've to use ==, to compare String the equals method.
Example:
if (val.equals("I"))
But also val is not present in the method getRoman().
You are trying to parse val as an int, but its not, its a character.
For such a small sample of chars, its probably easiest to simply create a lookup table, index it on the char.
Are you getting any errors?
In your code, you never call the getRoman function. Also, you're using the assignment operator = instead of the comparison operator "I".equals(val) for example.
String comparsion should be done with equals(String str) method instead of == comparison.
PS. You have = instead of == anyway.
The following statement is an assignment:
val = "I"
That is definitely not what you want to do here.
A comparison is done with the double equals, but double equals (==) compares references but you do not want to do that here either.
You want to use the equals method.
if (val.equals("I")) ...
Make those change everywhere and see how it works for you.
ACtually your main trouble comes from string comparison. In java, = is meant to assign values to variables, == is meant to compare values of primitive types and equals is the way to compare objects, especially for strings.
An alternative to using equals can be to use the JDK internal pool of strings, in this case, you could use == as a comparator.
In your case of parsing roman language numbers, you could also consider using a hashmap to store and retrieve effectively the parsed values of numbers. If you have thousands of comparisons like this to make, then go for identityhashmap.
And last, if you want to do real parsing for all roman numbers, not only the first ones, then you should considering using an automata, i.e. a state machine to parse numbers in a somewhat recursive way, that would be the more efficient model to apply to your problem.
The last 2 remarks are more oriented towards software algorithms, the first two ones are more oriented towards java syntax. You should start to know the syntax before going higher level optimizations.
Regards,
StΓ©phane
Aside from what was said above about how your String comparison should use the equals( ... ) function - for example,
if ( val.equals("VII") )
you also need to provide a return value for your function called getRoman. This function was declared as a function that returns an integer value to the caller, but in the implementation that you have provided, there are no return values (only System.out.println( ... )).
Also, you aren't inputting the correct parameter type - from what it looks like, your function is checking a String to see if it is a certain Roman numeral. So the correct function header would look like this:
public static int getRoman(String val)
Also, make sure you are actually calling this function in your main() - from what it looks like right now, you aren't even using the getRoman() function.
Hope this helps!

Categories