Negative key in binary search method in Java - java

What does it mean when the second argument is negative. I'm looking at a piece of code that searches for a key in an array. But what does a negative key mean ?
for (int i = 0; i < N; i++) {
int j = Arrays.binarySearch(a, -a[i]);
}

It means its look for a number which it the negative of a number in the array already.
This could be a positive key. For example, if a[0] is -10, it will look for 10 in the same array.

As described in the documentation, key is the value (in the array) to be searched for. Negating the argument just searches for its negation within the array!

Related

max value of iterator in for loop in java

Is long allowed inside of for loop in java? If yes, why does eclipse shows an error while putting a long value, If no, what is the maximum value that can be used inside a for loop as iterator?
Yes it is allowed. This works just fine
for(long l=0;l<Long.MAX_VALUE;l++){
System.out.println(l);
}
It is allowed, look:
for (long lng = 1L; lng < Long.MAX_VALUE; lng++) {
// your code
}
To see max long value that you can assign, you can use:
System.out.println(Long.MAX_VALUE);
Notice that I put L after literal 1 (it's 1L) when assigning value to long, to avoid error when trying to assign value exceeding Integer range (this error would occur when if you tried to assign value greater than Integer.MAX_VALUE to variable of type long without using long literal (this literal is upper- or lowercase 'L' character after digits, without 'L' it's integer literal and compiler checks that this number is currently out of int range).
When for 1 in my example this L was redundant, for numbers greater than Integer.MAX_VALUE it's necessary.
Without any code I can only guess, but I assume you're trying to use a value that's too big to fit into an int literal where you want a long.
For example:
for(long x = 0; x < 9876543210; x++) {
...
}
This code will produce The literal 9876543210 of type int is out of range because although you defined x to be of type long, the literal you're using here is interpreted as int and is therefore too big.
To fix this, you need to explicitly tell the compiler, that you mean a long literal by appending a l or L to the value (upper-case L is preferred, because you can better tell it apart from a 1):
for(long x = 0; x < 9876543210L; x++) {
... ^- notice the 'L'
}

Why am I receiving negative values for my hash function?

I have this hash function that calculates a key based on the product of a words ASCII values. It was working fine when I tested it with small words, but then I tried words from a whole text file and some of them get negative values while others are positive. I understand that this is overflow, but how would I fix it?
EDIT:
Ok, so people are saying that negative hash values are valid. My problem is that I implemented the hash table using an array and I am getting an index out of bounds error due to the negative numbers. What would be the best way to fix this?
public int asciiProduct(String word) {
// sets the calculated value of the word to 0
int wordProductValue = 1;
// for every letter in the word, it gets the ascii value of it
// and multiplies it to the wordProductValue
for (int i = 0; i < word.length(); i++) {
wordProductValue = wordProductValue * (int) word.charAt(i);
}
// the key of the word calculated by this function will be set
// to the modulus of the wordProductValue with the size of the array
int arrayIndex = wordProductValue % (hashArraySize-1);
return arrayIndex;
}
You can just take the absolute value of the result of your integer multiplication - which will overflow to a negative number when the integer value gets too big.
wordProductValue = Math.abs(wordProductValue * (int) word.charAt(i));
However, your hash function using modulo via the % operator should still work even with a negative number.
A negative hash code is perfectly valid. There is nothing wrong with it. No need to "fix".
But may I ask why are you doing this?
word.hashCode() should give you a much better hash value, than this ...

Counting isomorphic cyclic shifts in a string

I am trying to solve an algorithmic problem for which I have a O(n²) time, O(n) memory solution (see below) instead of a O(n) time and memory solution.
The problem is to count the number of isomorphic cyclic shifts for a given string s. A cyclic shift is a transformation of the initial string such as if 0 <= k < n (where n is the length of the string) :
cyclicShift(0) = s
cyclicShift(k) = s[k-1]...s[n-1]s[0]...s[k] if k > 0
A cyclic shift is said isomorphic if it is equal to the initial string. I have the feeling that a string can have such cycling shift iff it consists in the repetition of a pattern, but I cannot prove it. If it was the case, the problem would then become to find this pattern and then deduce the number of isomorphic cyclic shift, basing on the length of the pattern and the length of the string.
My current solution constructs all the cyclic shifts and compare them to the initial string, which is a O(n) operation in a loop bounded by n, leading to a complexity of O(n²). Here is my code in Java for reference :
public int solution(String S) {
int count = 1;
int n = S.length();
// We represent the string as a LinkedList to construct the next cyclic shift
// from a given one with a O(1) time complexity
List<Character> list = new LinkedList<>();
for (int i=0 ; i<n ; i++)
list.add(S.charAt(i));
Deque<Character> tmp = new LinkedList<>(list);
for (int k=1 ; k<n ; k++) {
tmp.addFirst(tmp.removeLast());
// this test is O(n) so this solution is O(n^2)
if (tmp.equals(list))
count++;
}
return count;
}
Do you have any idea of how I could solve this problem respecting the O(n) requirement ? Answers can be in Java, Scala, or pseudo-code.
I think you are quite right in that an isomorphic cyclic shift means that the string consists of a repeating pattern.
Consider the first k characters of the original string, by definition of the cyclic shift they are equal to the second k characters of the original string.
Now, consider the second k characters of the original string. These will be equal to the third k characters of the original string, and so on until you have shown that the string consists of a pattern of k characters that repeats n/k times.
Now the problem is to identify the string as a repeating pattern in O(n).
One way of doing this is to use the KMP failure function. The failure function tells you the longest proper prefix of a string that matches at position i. If you compute the value of the failure function at the end of the string it will tell you a number T which is the length of a proper prefix that matches the suffix of the string.
For example, consider the string ABCABCABC. The failure function will be:
-1 0 0 0 1 2 3 4 5 6
So the value at the end of the string is 6, and this tells us that the repeating pattern is of length p=n-T, in this case 9-6=3.
Once you have this length of the smallest repeating pattern, you can simply try all multiples and check that they divide the length of the string:
m=p
count=0
while(m<n)
if n%m==0: count+=1
m+=p
Overall this is O(n) in time and space.
I recently came accross a similar problem again, the only difference being that this time the fact that the string was made of a repeated pattern was explicitly specified instead of just deducible from the specification.
I implemented easily a Python function that finds the length of the smallest repeating pattern in the string. I add it here because if is far simpler that using KMP like suggested by Peter de Rivaz, however his answer also brings a proof that the existence of an isomorphic cyclic shift implies that the string is made of a repeated pattern and also the way to solve the problem once the smallest pattern was found.
Even if it is written in Python, I believe this code is fairly easy to understand :
def smallestPattern(s)
(count,res) = (0,1)
for i,ch in enumerate(s):
if ch != line[count]:
count = 0
res += 1
else:
count += 1
return res

How to get the value of Integer.MAX_VALUE in Java without using the Integer class

I have this question that has completely stumped me.
I have to create a variable that equals Integer.MAX_VALUE... (in Java)
// The answer must contain balanced parentesis
public class Exercise{
public static void main(String [] arg){
[???]
assert (Integer.MAX_VALUE==i);
}
}
The challenge is that the source code cannot contain the words "Integer", "Float", "Double" or any digits (0 - 9).
Here's a succinct method:
int ONE = "x".length();
int i = -ONE >>> ONE; //unsigned shift
This works because the max integer value in binary is all ones, except the top (sign) bit, which is zero. But -1 in twos compliment binary is all ones, so by bit shifting -1 one bit to the right, you get the max value.
11111111111111111111111111111111 // -1 in twos compliment
01111111111111111111111111111111 // max int (2147483647)
As others have said.
int i = Integer.MAX_VALUE;
is what you want.
Integer.MAX_VALUE, is a "static constant" inside of the "wrapper class" Integer that is simply the max value. Many classes have static constants in them that are helpful.
Here's a solution:
int ONE = "X".length();
int max = ONE;
while (max < max + ONE) {
max = max + ONE;
}
or lots of variants.
(The trick you were missing is how to "create" an integer value without using a numeric literal or a number wrapper class. Once you have created ONE, the rest is simple ...)
A bit late, but here goes:
int two = "xx".length();
int thirtyone = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".length();
System.out.println(Math.pow(two, thirtyone)-1);
How did I go? :p
I do like that bitshift one though...
The issue is that the answer cannot contain: "Integer", "Float", "Double", and digits (0 - 9)
There are other things in Java which can be represented as an Integer, for example a char:
char aCharacter = 'a';
int asInt = (int) aCharacter;
System.out.println(asInt); //Output: 97
You can also add chars together in this manner:
char aCharacter = 'a';
char anotherCharacter = 'b';
int sumOfCharacters = aCharacter + anotherCharacter;
System.out.println(sumOfCharacters); //Output: 195
With this information, you should be able to work out how to get to 2147483647on your own.
OK, so an Integer can only take certain values. This is from MIN_VALUE to MAX_VALUE where the minimum value is negative.
If you increase an integer past this upper bound the value will wrap around and become the lowest value possible. e.g. MAX_VALUE+1 = MIN_VALUE.
Equally, if you decrease an integer past the lower bound it will wrap around and become the largest possible value. e.g. MIN_VALUE-1 = MAX_VALUE.
Therefore a simple program that instantiates an int, decrements it until it wraps around and returns that value should give you the same value as Integer.MAX_VALUE
public static void main(String [] arg) {
int i = -1
while (i<0) {
i--;
}
System.out.println(i);
}

Checking if value of int[] can be long

I have an array of ints ie. [1,2,3,4,5] . Each row corresponds to decimal value, so 5 is 1's, 4 is 10's, 3 is 100's which gives value of 12345 that I calculate and store as long.
This is the function :
public long valueOf(int[]x) {
int multiplier = 1;
value = 0;
for (int i=x.length-1; i >=0; i--) {
value += x[i]*multiplier;
multiplier *= 10;
}
return value;
}
Now I would like to check if value of other int[] does not exceed long before I will calculate its value with valueOf(). How to check it ?
Should I use table.length or maybe convert it to String and send to
public Long(String s) ?
Or maybe just add exception to throw in the valueOf() function ?
I hope you know that this is a horrible way to store large integers: just use BigInteger.
But if you really want to check for exceeding some value, just make sure the length of the array is less than or equal to 19. Then you could compare each cell individually with the value in Long.MAX_VALUE. Or you could just use BigInteger.
Short answer: All longs fit in 18 digits. So if you know that there are no leading zeros, then just check x.length<=18. If you might have leading zeros, you'll have to loop through the array to count how many and adjust accordingly.
A flaw to this is that some 19-digit numbers are valid longs, namely those less than, I believe it comes to, 9223372036854775807. So if you wanted to be truly precise, you'd have to say length>19 is bad, length<19 is good, length==19 you'd have to check digit-by-digit. Depending on what you're up to, rejecting a subset of numbers that would really work might be acceptable.
As others have implied, the bigger question is: Why are you doing this? If this is some sort of data conversion where you're getting numbers as a string of digits from some external source and need to convert this to a long, cool. If you're trying to create a class to handle numbers bigger than will fit in a long, what you're doing is both inefficient and unnecessary. Inefficient because you could pack much more than one decimal digit into an int, and doing so would give all sorts of storage and performance improvements. Unnecessary because BigInteger already does this. Why not just use BigInteger?
Of course if it's a homework problem, that's a different story.
Are you guaranteed that every value of x will be nonnegative?
If so, you could do this:
public long valueOf(int[]x) {
int multiplier = 1;
long value = 0; // Note that you need the type here, which you did not have
for (int i=x.length-1; i >=0; i--) {
next_val = x[i]*multiplier;
if (Long.MAX_LONG - next_val < value) {
// Error-handling code here, however you
// want to handle this case.
} else {
value += next_val
}
multiplier *= 10;
}
return value;
}
Of course, BigInteger would make this much simpler. But I don't know what your problem specs are.

Categories

Resources