sort array positive negative distance value - java

I have an array of distances calculated using (distance to) method
which contain both negative and positive values looks like this
float num[] = {-123.81944, 34.56723, -133.40782};
when trying to use
Arrays.sort(num);
the result is
-123.81944
-133.40782
34.56723
which is incorrect since -133.40782 location is closer than -123.81944
how can i sort the array to result like this
-133.40782
-123.81944
34.56723

If you want to use float as data type, then you should declare the array as follows. Otherwise, you can use double as data type to avoid adding a suffix f to the numbers.
float[] num = {-123.81944f, 34.56723f, -133.40782f};
// or, double[] num = {-123.81944, 34.56723, -133.40782};
Arrays.sort(num);
System.out.println(Arrays.toString(num));
Output
[-133.40782, -123.81944, 34.56723]
See a live demo.

Suppose there is an arrayA containing negative numbers, zero and positive numbers. You need to sort them, how would you do it. Ofcourse you would consider the natural ordering and would sort as negative numbers followed by zero followed by positive numbers. This is what Arrays.sort() does.
If you wish to sort the distances from a reference point , I feel your expected result is not correct. If we consider a line, a reference point and then on its left the negative distance and on its riggt the positive distance then sorting should be based on absolute value.
Your business requirement is to do a custom sorting. For any sorting to work you need to have a logic for comparision. For this java provides Comparator. You need to implement your business logic based comparision for sorting. [HINT : while comparing you can just compare the absolute value, Math.abs may help]
Floats end with f so apending f with each of your array elements is better.
For reference you can see another related question
How to sort an array of ints using a custom comparator?

For me, with a standard Java JRE it works like (you) expected, but I had to turn the numbers in float literals. Otherwise it did not compile:
float num[] = new float[] {-123.81944f, 34.56723f, -133.40782f};
Arrays.sort(num);
for (int i = 0; i < num.length; i++) {
System.out.print(" " + num[i]);
}
prints -133.40782 -123.81944 34.56723

Related

How to sort numbers in an array into different arrays based off of their last two digits

Trying to write a program that takes a set of doubles and then sorts these values into different arrays based on their tenths and hundredths places after the decimal. So for an array [1.25, 2.25, 3.5, 10.5, 7.75, 4.75] sort the .25's .5's .75's into separate arrays so that calculations may be done.
You use the term 'sort' but I think you are really talking about grouping the values into collections based on their first 2 decimal values. If that's correct then you can use:
values.stream().collect(Collectors.groupingBy(v -> (int)(v % 1 * 100));
This will generate a map from each fraction (expressed as a /100 int) to a list of values that have that fraction. If you particularly need arrays you can use .toArray().
My solution is a little grouping algorithm:
public static List<List<Float>> getSortedArrays(float[] array){
List<List<Float>> result = new ArrayList<>();
HashMap<Float, Integer> createdArrays= new HashMap<>();
for (float f : array) {
float ending = f-((int)f);
if(createdArrays.containsKey(ending)){
result.get(createdArrays.get(ending)).add(f);
}else{
createdArrays.put(ending, result.size());
List<Float> newList = new ArrayList<>();
newList.add(f);
result.add(newList);
}
}
return result;
}
I am basically looping through the float array and with this trick float ending = f-((int)f); I am separating just the numbers after the decimal. Than I am checking if there is already created array for that ending, if yes I add currently processed float, if not I create it and also add that float there. HashMap is there to keep track of already created Arrays.
Again use .toArray() if you need array...

Is there an approach to finding the ASCII distance between two strings of 5 characters

I am trying to find a way to calculate and print the Ascii distance between a string from user input
Scanner scan = new Scanner(System.in);
System.out.print("Please enter a string of 5 uppercase characters:");
String userString = scan.nextLine();
and a randomly generated string
int leftLimit = 65; // Upper-case 'A'
int rightLimit = 90; // Upper-case 'Z'
int stringLength = 5;
Random random = new Random();
String randString = random.ints(leftLimit, rightLimit + 1)
.filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
.limit(stringLength)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
Is there a way to calculate the distance without having to separate each individual character from the two strings, comparing them and adding them back together?
Use Edit distance (Levenshtein distance)
You can
Implement your own edit distance based on the algorithm on wikipedia,
you can use an existing source code, for that look at rosetta code.
use an existing library like apache LevenshteinDistance
you can also check
Levenshtein Distance on stackoverflow
Streams are, well, as the name says, streams. They don't work very well unless you can define an operation strictly on the basis of one input: One element from a stream, without knowing its index or referring to the entire collection.
Here, that is a problem; after all, to operate on, say, the 'H' in your input, you need the matching character from your random code.
I'm not sure why you find 'separate each individual character, compare them, and add them back together' is so distasteful to you. Isn't that a pretty clean mapping from the problem description to instructions for your computer to run?
The alternative is more convoluted: You could attempt to create a mixed object that contains both the letter as well as its index, stream over this, and use the index to look up the character in the second string. Alternatively, you could attempt to create a mix object containing both characters (so, for inputs ABCDE and HELLO, an object containing both A and H), but you'd be writing far more code to get that set up, then the simple, no-streams way.
So, let's start with the simple way:
int difference = 0;
for (int i = 0; i < stringLength; i++) {
char a = inString.charAt(i);
char b = randomString.charAt(i);
difference += difference(a, b);
}
You'd have to write the difference method yourself - but it'd be a very very simple one-liner.
Trying to take two collections of some sort, and from them create a single stream where each element in the stream is matching elements from each collection (so, a stream of ["HA", "EB", "LC", "LD", "OE"]) is generally called 'zipping' (no relation to the popular file compression algorithm and product), and java doesn't really support it (yet?). There are some third party libraries that can do it, but given that the above is so simple I don't think zipping is what you're looking for here.
If you absolutely must, I guess i'd look something like:
// a stream of 0,1,2,3,4
IntStream.range(0, stringLength)
// map 0 to "HA", 1 to "EB", etcetera
.mapToObj(idx -> "" + inString.charAt(idx) + randomString.charAt(idx))
// map "HA" to the difference score
.mapToInt(x -> difference(x))
// and sum it.
.sum();
public int difference(String a) {
// exercise for the reader
}
Create an 2D array fill the array with distances - you can index directly into the 2D array to pull out the distance between the characters.
So one expression that sums up a set of array accesses.
Here is my code for this (ASCII distance) in MATLAB
function z = asciidistance(input0)
if nargin ~= 1
error('please enter a string');
end
size0 = size(input0);
if size0(1) ~= 1
error ('please enter a string');
end
length0 = size0(2);
rng('shuffle');
a = 32;
b = 127;
string0 = (b-a).*rand(length0,1) + a;
x = char(floor(string0));
z = (input0 - x);
ascii0 = sum(abs(z),'all');
ascii1 = abs(sum(z,'all'));
disp(ascii0);
disp(ascii1);
disp(ascii0/ascii1/length0);
end
This script also differentiates between the absolute ASCII distance on a per-character basis vs that on a per-string basis, thus resulting in two integers returned for the ASCII distance.
I have also included the limit of these two values, the value of which approaches the inverse of the length of strings being compared. This actually approximates the entropy, E, of every random string generation event when run.
After standard error checking, the script first finds the length of the input string. The rnd function seeds the random number generator. the a and b variables define the ASCII table minus non-printable characters, which ends at 126, inclusively. 127 is actually used as an upper bound so that the next line of code can generate a random string of variables of input length. The following line of code turns the string into the alphanumeric characters provided by the ASCII table. The following line of code subtracts the two strings element-wise and stores the result. The next two lines of code sum up the ASCII distances in the two ways mentioned in the first paragraph. Finally, the values are printed out, as well as providing the entropy, E, of the random string generation event.

Return set of numbers in recursion

following code searches for one zero point of a polynomial function. It uses recursion technique:
private static double funktion(int[] koef, double x){
return koef[0] * Math.pow(x,4) + koef[1] * Math.pow(x,3) +
koef[2] * Math.pow(x,2) + koef[3]*x + koef[4];
}
private static double nullstelle(double a, double b, int[] koef){
double middle = (a + b)/2;
double result = middle;
if(Math.abs(a-b) > 0.00001){
double sin = funktion(koef, middle);
if(sin == 0){
result = middle;
}else if(Math.signum(funktion(koef, a)) ==
Math.signum(funktion(koef, middle))){
result = nullstelle(middle, b, koef);
}else{
result = nullstelle(a, middle, koef);
}
}
return result;
}
I am wondering how to return all zero points. My ideas is to use an array but I am not sure how to do that. Any ideas?
I am not allowed to use anything else than arrays (e.g. hash tables or sets are not allowed)
I would pass in a Collection such as a HashSet to your functions and put all the numbers you discover into it.
As you say you can only use arrays, then you know the maximum number of zero-points that can be found, presumably, so create an array of that size, assigned NaN to every element, then pass in that array and the maximum current index of it to every function call. You will need to return the new size of the array as the result so that you always know how many numbers have been found.
Here is some explanation as this is homework:
1) We need to create an array of the data type you will be using to store zero points. My guess is double.
2) The array will need some type of starting size, lets say 10 for the sake of discussion
3) In the nullstelle method we will add an element to the array created in step 1
4) If the array has size LIMIT -1 we copy the array to a new array with size equal to LIMIT * 2
5) We now return this array.
If it needs to be sorted we can walk over the list utilizing whatever sort technique is to be decided on.
First of all your solution as it stands suffers from one of the same problems as your previous question in that you can't guarantee that you'll get the zero calculation exactly correct. Unfortunately, this time you can't use the simple solution of checking that a and b have opposite signs because, for an arbitrary polynomial, a zero need not imply the function crosses the y = 0 line e.g. y = x^4.
Anyway, to answer your question:
create an array of size 4 of type Double. Use null to denote that an array slot is empty. As your function is a quartic, there is a maximum of four zeroes.
pass the array as a parameter in your function.
when you have detected a zero, fill in the first free slot left in the array with the value of the zero.
No actual Java provided because this is homework.
Math.pow is a very expensive function. You can avoid it entirely using nested expressions. (And its shorter)
private static double funktion(int[] koef, double x){
return (((koef[0] * x + koef[1]) * x +
koef[2]) * x + koef[3]) * x + koef[4];
}
public double[] returnOnlyZeros(int[] whatever1, double whatever2) {
double[] result = new double[/*put the size here*/];
// your math here
// put the values into the result array
return result;
}

How to alter a float by its smallest increment in Java?

I have a double value d and would like a way to nudge it very slightly larger (or smaller) to get a new value that will be as close as possible to the original but still strictly greater than (or less than) the original.
It doesn't have to be close down to the last bit—it's more important that whatever change I make is guaranteed to produce a different value and not round back to the original.
(This question has been asked and answered for C, C++)
The reason I need this, is that I'm mapping from Double to (something), and I may have multiple items with the save double 'value', but they all need to go individually into the map.
My current code (which does the job) looks like this:
private void putUniqueScoreIntoMap(TreeMap map, Double score,
A entry) {
int exponent = 15;
while (map.containsKey(score)) {
Double newScore = score;
while (newScore.equals(score) && exponent != 0) {
newScore = score + (1.0d / (10 * exponent));
exponent--;
}
if (exponent == 0) {
throw new IllegalArgumentException("Failed to find unique new double value");
}
score = newScore;
}
map.put(score, entry);
}
In Java 1.6 and later, the Math.nextAfter(double, double) method is the cleanest way to get the next double value after a given double value.
The second parameter is the direction that you want. Alternatively you can use Math.nextUp(double) (Java 1.6 and later) to get the next larger number and since Java 1.8 you can also use Math.nextDown(double) to get the next smaller number. These two methods are equivalent to using nextAfter with Positive or Negative infinity as the direction double.
Specifically, Math.nextAfter(score, Double.MAX_VALUE) will give you the answer in this case.
Use Double.doubleToRawLongBits and Double.longBitsToDouble:
double d = // your existing value;
long bits = Double.doubleToLongBits(d);
bits++;
d = Double.longBitsToDouble(bits);
The way IEEE-754 works, that will give you exactly the next viable double, i.e. the smallest amount greater than the existing value.
(Eventually it'll hit NaN and probably stay there, but it should work for sensible values.)
Have you considered using a data structure which would allow multiple values stored under the same key (e.g. a binary tree) instead of trying to hack the key value?
What about using Double.MIN_VALUE?
d += Double.MIN_VALUE
(or -= if you want to take away)
Use Double.MIN_VALUE.
The javadoc for it:
A constant holding the smallest positive nonzero value of type double, 2-1074. It is equal to the hexadecimal floating-point literal 0x0.0000000000001P-1022 and also equal to Double.longBitsToDouble(0x1L).

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