java how do i read a negative int as a positive one - java

The question at hand is:
The method should compute for each row the sum of the absolute values
of the elements of that row. The method should return the maximum of
these sums. For example, if applied to the test array, the method
should return the value max (3+1+4+0,5+9+2+6, 5+3+7+8) = max (8,22,23)
= 23.
The test array:
3 -1 4 0
5 9 -2 6
5 3 7 -8
so far i have made a method that gets the value of all the rows and returns to me the sum in a list; however, i want it to turn negative integers into positive ones.
here's my code so far:
public static int[] rowSums(int[][]array) {
int[] a = new int[array.length];
for (int i = 0;i<array.length;i++){
int sum = IntStream.of(array[i]).sum();
a[i]=sum;
} return a;}
Output:
[6,18,7]

You can use Math#abs(standing for absolute value) which converts any negative number into a positive number:
int sum = IntStream.of(array[i]).map(Math::abs).sum();
If you'd like to lose those for-loops, you can even just stick with streams:
public static int[] rowSums(int[][] array) {
return Arrays.stream(array)
.mapToInt(i -> Arrays.stream(i).map(Math::abs).sum())
.toArray();
}

Here you can use the Map. So The code will be like this.
public static int[] rowSums(int[][]array) {
int[] a = new int[array.length];
for (int i = 0;i<array.length;i++){
int sum = IntStream.of(array[i]).map(n->{
if(n<0) {
return n*-1;
}
else {
return n;
}
}).sum();
a[i]=sum;
} return a;}
Here I just make all the negative Integers into Positive.

Update this line
int sum = IntStream.of(array[i]).sum();
to
int sum = IntStream.of(array[i]).map(Math::abs).sum();
And solution for whole matrix (this snippet will return 23):
Optional<Integer> maxVal = Arrays.stream(matrix)
.map(array -> Arrays.stream(array).map(Math::abs).sum())
.reduce(Integer::max);
And without Optional
int maxVal = Arrays.stream(matrix)
.map(array -> Arrays.stream(array).map(Math::abs).sum())
.reduce(Integer::max).get();

Use Math.abs() It'll take any number and return it as a positive number. You need it on this line:
int sum = IntStream.of(array[i]).sum();
to take array[i] and make it absolute. So
IntStream.of(Math.abs(array[i]).sum();

Just use:
Math.abs(var)
This will turn var to a positive if it is negative.
Therefore the full answer is as follows:
public static int[] rowSums(int[][]array) {
int[] a = new int[array.length];
for (int i = 0;i<array.length;i++){
int sum = IntStream.of(array[i]).map(Math::abs).sum();
a[i]=sum;
} return a;}

Change all numbers to positive numbers. This can be done using Math.abs(int).Check the link.

Related

How do I simplify/combine these two methods for finding the smallest and largest int in an array? [duplicate]

This question already has answers here:
Is it possible to pass arithmetic operators to a method in java?
(9 answers)
Closed 4 months ago.
I've written two methods to find the smallest and largest int in an array, but they're nearly identical, so I feel like there should be some way to simplify this, perhaps as one method?
private int findMin(){
int min = arr[0];
for(int num : arr){
if(num<min) {
min = num;
}
}
return min;
}
private int findMax(){
int max = arr[0];
for(int num : arr){
if(num>max){
max = num;
}
}
return max;
}
I'm not sure how to approach this sort of issue, so I'd love to see your responses!
While this question on how to pass arithmetic operators to a method and this question on how to get both min and max value of Java 8 stream answer the literal programming problem, my question is on a more fundamental level about to how to approach the problem of methods doing similar things, and ways to compare arrays in general. The answers to this post have been significantly more helpful to me than the answers to those questions.
You can implement just one, say findMax, and pass it a Comparator that indicates how comparisons should be done:
private int findMax(Comparator<Integer> comparator) {
int max = arr[0];
for (int num : arr) {
if (comparator.compare(num, max) > 0) {
max = num;
}
}
return max;
}
Pass Comparator.naturalOrder() for the natural ordering of integers, so you get the maximum.
Pass Comparator.reverseOrder() for the reverse ordering, so you get the minimum.
Your methods are already available in IntStream that also deals with empty arrays (indeterminate extremes).
private OptionalInt findMin() {
return IntStream.of(arr).min();
}
private OptionalInt findMax() {
return IntStream.of(arr).max();
}
And like your choice of throwing exceptions:
private int findMin() {
return IntStream.of(arr).min().get();
}
private int findMax() {
return IntStream.of(arr).max().get();
}
Or as method reference:
Function<IntStream, OptionalInt> extreme = IntStream::max;
Also consider the parallel feature:
IntStream.of(arr).parallel().min();
#Yay295 reminded us of IntSummaryStatistics:
IntSummaryStatistics stats = new IntSummaryStatistics();
IntStream.of(arr).stream()
.forEach(stats); // stats is an int consumer too.
or when doing more
IntSummaryStatistics stats = IntStream.of(arr)
.collect(Collectors.summarizingInt(IntSummaryStatistics::new,
IntSummaryStatistics::accept,
IntSummaryStatistics::combine);
and then several numbers can be asked:
int min = stats.getMin();
int max = stats.getMax();
int avg = stats.getAverage();
int sum = stats.getSum();
Feedback of #draspa44
You can end any IntStream, LongStream or DoubleStream simply with .summaryStatistics(). I think this is easier to read than mutating stats or using accept and combine
IntSummaryStatistics stats = IntStream.of(arr)
.summaryStatistics();
I would not recommend combine two responsibilities into one method
Instead, I would make two methods (max and min) that share same lines of code through a third method.
public int min(int[] array){
return most(array, (a, b) -> a < b)
}
public int max(int[] array){
return most(array, (a, b) -> a > b)
}
private int most(int[] array, Fuction2 compare){
int most = array[0];
for (int num : array) {
if (compare(num, most)) {
most = num;
}
}
return most;
}
This way you can easily change logic for one method, without changing another
Also, it is easier to use and more readable, than using one method with parameter like "max=true"
If the number of int's is big and you most of the time need both min and max values, it probably makes sense to go through the list only once and evaluate both min and max at the same time.
Then there is just the question how to communicate two numbers when a function can only have one return value. So we create a special result class for this.
class MinMaxResult {
public int min = 0;
public int max = 0;
}
MinMaxResult findMinMax() {
MinMaxResult result = new MinMaxResult();
result.min = arr[0];
result.max = arr[0];
for (int num: arr) {
if (num < result.min) {
result.min = num;
} else if (num > result.max) {
result.max = num;
}
}
return result;
}
You can also call the class methods Math.min and Math.max as follows and return the results in a record. Records are immutable classes and were introduced in Java 14.
record MinMax(int min, int max) {
};
public static void main(String[] args) {
int[] v = { 1, 1, 20, 3, 3, 10 };
MinMax result = findMinMax(v);
System.out.println(result);
// or
System.out.println(result.min + ", "+ result.max);
}
prints
MinMax[min=1, max=20]
1, 20
Just iterate over the array and apply the methods to each value and the current value of min or max.
public static MinMax findMinMax(int[] values) {
int max = values[0];
int min = max;
for (int i = 1; i < values.length; i++) {
max = Math.max(max, values[i]);
min = Math.min(min, values[i]);
}
return new MinMax(min, max);
}
Since there is really only one difference, you can pass a boolean to determine which value (min or max) you want.
Something like this:
private int findExtreme(boolean findMin) {
int solution = arr[0];
for(int num : arr){
if (findMin){
if(num<min){
solution = num;
}
} else {
if(num>max){
solution = num;
}
}
}
return solution;
}
You can pass in a boolean that is true to find the minimum or false to find the maximum. The trick is to compare the result of (num < best), which is either true or false, to the boolean argument.
If isMinimum is true then when (num < best) is true we have a new minimum.
If isMinimum is false then when (num < best) is false we have a new maximum (or a tie for maximum).
private int findExtreme(bool isMinimum) {
int best = arr[0];
for (int num: arr) {
if ((num < best) == isMinimum) {
best = num;
}
}
return best;
}
Even better would be to use an enum. Boolean arguments can be hard to decipher just seeing a bare true or false in a function call. That would look like:
public enum Extreme {
MINIMUM,
MAXIMUM
}
private int find(Extreme extreme) {
int best = arr[0];
for (int num: arr) {
if ((num < best) == (extreme == Extreme.MINIMUM)) {
best = num;
}
}
return best;
}

Code Optimize : Shifting a List of Integers in Java

Requirement : There's an input List and an input shift no.
The first line contains two space-separated integers that denote :
n, the number of integers, and
d, the number of left rotations to perform.
The second line contains space-separated integers that describe arr[].
Constraints
1 <= n <= 10^5
1 <= d <= n
1 <= arr[i] <= 10^6
Sample Input
5 , 4
1 2 3 4 5
Sample Output
5 1 2 3 4
I have written this code which is working correctly but getting timeout while large operation. So I need to optimize my code to successfully run all the test cases. How to achieve that.
public static List<Integer> rotateLeft(int d, List<Integer> arr) {
int size = arr.size();
while(d>0) {
int temp = arr.get(0);
for(int i = 0; i<size; i++){
if(i != size-1){
arr.set(i,arr.get(i+1));
} else {
arr.set(i,temp);
}
}
d--;
}
return arr;
}
Failing for this input :
n = 73642
d = 60581
And a huge Integer List of size 73642.
Instead of using nested loops, this can be done in one loop. The final index of an element at index i after n shifts, can be calculated as (i + n) % listLength, this index can be used to populate a shifted list. Like this:
import java.util.*;
class HelloWorld {
public static void main(String[] args) {
List<Integer> arr = Arrays.asList(1,2,3,4,5);
System.out.println(rotateLeft(4, arr));
}
public static List<Integer> rotateLeft(int d, List<Integer> arr) {
List<Integer> rotatedList = new ArrayList<>(arr.size());
int i=0;
for(i=0; i< arr.size(); i++) {
int rotatedElementIndex = ((i+d) % arr.size());
rotatedList.add(arr.get(rotatedElementIndex));
}
return rotatedList;
}
}
Never liked hackerrank puzzles. What does "and a huge Integer array" mean? May we create a new list or we need to modify existing one? If we ought to modify existing one why our method is not void?
If we may create new list the optimal solution would be creating new Integer[] array and call System.arraycopy() twice.
In case of inline modifications the solution is:
public static List<Integer> rotateLeft(int d, List<Integer> arr) {
int i = 0, first = arr.get(0);
int n = arr.size();
while (true) {
int source = (i + d) % n;
if (source == 0) {
arr.set(i, first);
break;
}
arr.set(i, arr.get(source));
i = source;
}
return arr;
}
For an in-place solution:
reverse the subarrays arr[0, d) and arr[d, n) in-place. This is done by swapping the elements in symmetric pairs.
reverse the whole array.
E.g., abcdefghijk, d=4
abcd|efghijk -> dcba|kjihgfe -> efghijk|abcd

Getting incorrect sort order

Failing test case:
Input:
[-2147483648,1,1]
Output:
-2147483648
Expected:
1
Why is the output expected as 1 when -2147483648 is the 2nd max number here?
public int thirdMax(int[] nums) {
PriorityQueue<Integer> pq = new PriorityQueue(new Comparator<Integer>(){
public int compare(Integer a, Integer b){return b-a;}
});
int res=0;
for(int num : nums){
if(!pq.contains(num) )
pq.add(num);
}
if(pq.size()<=2){
for(int i=0; i<pq.size(); i++){
res=pq.poll();
}
}
else {
for(int i=0; i<3; i++){
res=pq.poll();
}
}
return res;
}
Your method of comparing isn't correct for int.
Rather than:
return b - a;
you should do:
return Integer.compare(b, a);
An int can only hold values of up to Integer.MAX_VALUE. But if you do 1 - -2147483648, the result is greater than Integer.MAX_VALUE, which makes it negative again - and you get wrong sort orders as a result. Basically, return b - a; is only safe if you know that all numbers are positive (or if the numbers won't be further apart than Integer.MAX_VALUE).
In other cases, you can use the API method Integer.compare.
Note that, since you are comparing by the inverse of the natural order of integers, you can also shorten your code with:
PriorityQueue<Integer> pq = new PriorityQueue<>(Comparator.reverseOrder());

Comparing Two Arrays & Get the Percent that Match - Java

Background: Very new at Java, have little understanding. Would prefer a "point in the right direction" with explanation, if possible, than a copy/paste answer without explanation. If I want to stop being a novice, I need to learn! :)
Anyway, my goal is, as simply as possible, to be given 2 arrays numberList and winningNumbers, compare them, and return the percentage that numberList matches winningNumbers. Both array lengths will always be 10.
I have no idea where to start. I have been googling and going at this for 2 hours. My idea is to write a for loop that compares each individually integer in a string to one in the other, but I am not sure how to do that, or if there is a simpler method. I have little knowledge of arrays, and the more I google the more confused I become.
So far the only thing I have is
public double getPercentThatMatch(int[] winningNumbers) {}
numberList is preset.
one way you could approach it is to:
1) convert both lists to sets.
2) subtract one from the other. ie if 4 are the same, the resulting set will have the 6 values not the same
3) 10 - (size of resulting set) * 100 = %
Here's a runnable example of how you would compare the two arrays of ints to get a percent match.
public class LotteryTicket {
int[] numberList;
LotteryTicket(int... numbers) {
numberList = numbers;
}
public int getPercentThatMatch(int[] winningNumbers) {
Arrays.sort(numberList);
Arrays.sort(winningNumbers);
int i = 0, n = 0, match = 0;
while (i < numberList.length && n < winningNumbers.length) {
if (numberList[i] < winningNumbers[n]) {
i++;
} else if (numberList[i] > winningNumbers[n]) {
n++;
} else {
match++;
i++;
n++;
}
}
return match * 100 / winningNumbers.length;
}
public static void main(String[] args)
{
int[] winningNumbers = { 12, 10, 4, 3, 2, 5, 6, 7, 9, 1 };
LotteryTicket ticket = new LotteryTicket(5, 2, 6, 7, 8, 4, 3, 1, 9, 0);
int percentMatching = ticket.getPercentThatMatch(winningNumbers);
System.out.println(percentMatching + "%");
}
}
Output:
80%
Since you wanted to be pointed in the right direction, rather than havving proper code, and assuming you want to use arrays to solve the problem, try to put something like this in your method:
(loop through arrayA){
(loop through arrayB){
if (current arrayA number is equal to current arrayB number){
then increase match counter by one, since this exists.
also break out of current arrayB loop. (Check next arrayA now.)
}
}
}
When done: return 100*matchCount/totalCount, as a double
So for every index in one array, you check against every other index of the other array. Increase a counter each time there's a match, and you'll be able to get a ratio of matches. If you use an integer as a counter, remember that division with integers acts funky, so you'd need to throw to a double:
double aDoubleNumber = (double) intNumber / anotherIntNumber
The problem would be easier if we consider them set. Let you have two set -
Set<Integer> s1 = //a HashSet of Integer;
Set<Integer> s2 = //a HashSet of Integer;
Now make a copy of s1 for example s11 and do the following thing -
s1.retainAll(s2);
Now s1 contains only element of both sets - that is the intersection.
After that you can easily calculate the percentage
Edit: You can convert the array to a set easily by using the following code snippet (I am assuming you have array of int) -
Set<Integer> s1 = new HashSet<Integer>(Arrays.asList(somePrimiteiveIntArray));
I think this trick will works for other primitive type also.
Hope this will help.
Thanks a lot.
I am going to attempt to beat a dead horse and explain the easiest (conceptual) way to approach this problem I will include some code but leave a lot up to interpretation.
You have two arrays so I would change the overall method to something like this:
public double getPercentage(int[] arrayA, int[] arrayB) {
double percentage=0;
for(/*go through the first array*/) {
for(/*go through second array*/) {
if(arrayA[i]==arrayB[j]) { /*note the different indices*/
percentage++; /*count how many times you have matching values*/
/* NOTE: This only works if you don't have repeating values in arrayA*/
}
}
}
return (percentage/arrayA.length)*100; /*return the amount of times over the length times 100*/
}
You are going to move through the first array with the first loop and the second array with the second loop. So you go through every value in arrayB for each value in arrayA to check.
In my approach I tried storing the winning numbers in a Hashset (one pass iteration, O(n) )
And when iterating on the numberList, I would check for presence of number in Hashset and if so, I will increment the counter. (one pass iteration, so O(n) )
The percentage is thus calculated by dividing the counter with size of array.
See if the sample code makes sense:
import java.util.HashSet;
public class Arraycomparison {
public static void main(String ... args){
int[] arr0 = {1,4,2,7,6,3,5,0,3,9,3,5,7};
int[] arr1 = {5,2,4,1,3,7,8,3,2,6,4,4,1};
HashSet set = new HashSet();
for(int j = 0; j < arr1.length; j++){
set.add(arr1[j]);
}
double counter = 0;
for(int i = 0; i < arr0.length; i++){
if(set.contains(arr0[i])){
counter++;
}
}
System.out.println("Match percentage between arrays : " + counter/arr0.length*100);
}
}
You should use List over array, because that's a convenient way, but with array:
public class Winner {
public static void main(String... args) {
double result = getPercentThatMatch(new int[]{1,2,3,4,5}, new int[]{2,3,4,5,6});
System.out.println("Result="+result+"%");
}
public static double getPercentThatMatch(int[] winningNumbers,
int[] numberList) { // it is confusing to call an array as List
int match = 0;
for (int win : winningNumbers) {
for (int my : numberList ){
if (win == my){
System.out.println(win + " == " + my);
match++;
}
}
}
int max = winningNumbers.length; // assume that same length
System.out.println("max:"+max);
System.out.println("match:"+match);
double devide = match / max; // it won't be good, because the result will be intm so Java will trunc it!
System.out.println("int value:"+devide);
devide = (double) match / max; // you need to cast to float or double
System.out.println("float value:"+devide);
double percent = devide * 100;
return percent;
}
}
Hope this helps. ;)
//For unique elements
getpercentage(arr1, arr2){
res = arr1.filter(element=>arr2.includes(element))
return res.lenght/arr2.lenght * 100;
}
//For duplicate elements
getpercentage(arr1, arr2){
const setA = Set(arr1);
const setB = Set(arr2);
Let res = [ ];
for(let i of setB){
if(setA.has(i)){
res.push(i);
}
}
return res.lenght/setA.size* 100;

Finding closest number in an array

In an array first we have to find whether a desired number exists in that or not?
If not then how will I find nearer number to the given desired number in Java?
An idea:
int nearest = -1;
int bestDistanceFoundYet = Integer.MAX_INTEGER;
// We iterate on the array...
for (int i = 0; i < array.length; i++) {
// if we found the desired number, we return it.
if (array[i] == desiredNumber) {
return array[i];
} else {
// else, we consider the difference between the desired number and the current number in the array.
int d = Math.abs(desiredNumber - array[i]);
if (d < bestDistanceFoundYet) {
// For the moment, this value is the nearest to the desired number...
bestDistanceFoundYet = d; // Assign new best distance...
nearest = array[i];
}
}
}
return nearest;
Another common definition of "closer" is based on the square of the difference. The outline is similar to that provided by romaintaz, except that you'd compute
long d = ((long)desiredNumber - array[i]);
and then compare (d * d) to the nearest distance.
Note that I've typed d as long rather than int to avoid overflow, which can happen even with the absolute-value-based calculation. (For example, think about what happens when desiredValue is at least half of the maximum 32-bit signed value, and the array contains a value with corresponding magnitude but negative sign.)
Finally, I'd write the method to return the index of the value located, rather than the value itself. In either of these two cases:
when the array has a length of zero, and
if you add a "tolerance" parameter that bounds the maximum difference you will consider as a match,
you can use -1 as an out-of-band value similar to the spec on indexOf.
//This will work
public int nearest(int of, List<Integer> in)
{
int min = Integer.MAX_VALUE;
int closest = of;
for (int v : in)
{
final int diff = Math.abs(v - of);
if (diff < min)
{
min = diff;
closest = v;
}
}
return closest;
}
If the array is sorted, then do a modified binary search. Basically if you do not find the number, then at the end of search return the lower bound.
Pseudocode to return list of closest integers.
myList = new ArrayList();
if(array.length==0) return myList;
myList.add(array[0]);
int closestDifference = abs(array[0]-numberToFind);
for (int i = 1; i < array.length; i++) {
int currentDifference= abs(array[i]-numberToFind);
if (currentDifference < closestDifference) {
myList.clear();
myList.add(array[i]);
closestDifference = currentDifference;
} else {
if(currentDifference==closestDifference) {
if( myList.get(0) !=array[i]) && (myList.size() < 2) {
myList.add(array[i]);
}
}
}
}
return myList;
Array.indexOf() to find out wheter element exists or not. If it does not, iterate over an array and maintain a variable which holds absolute value of difference between the desired and i-th element. Return element with least absolute difference.
Overall complexity is O(2n), which can be further reduced to a single iteration over an array (that'd be O(n)). Won't make much difference though.
Only thing missing is the semantics of closer.
What do you do if you're looking for six and your array has both four and eight?
Which one is closest?
int d = Math.abs(desiredNumber - array[i]);
if (d < bestDistanceFoundYet) {
// For the moment, this value is the nearest to the desired number...
nearest = array[i];
}
In this way you find the last number closer to desired number because bestDistanceFoundYet is constant and d memorize the last value passign the if (d<...).
If you want found the closer number WITH ANY DISTANCE by the desired number (d is'nt matter), you can memorize the last possibile value.
At the if you can test
if(d<last_d_memorized){ //the actual distance is shorter than the previous
// For the moment, this value is the nearest to the desired number...
nearest = array[i];
d_last_memorized=d;//is the actual shortest found delta
}
A few things to point out:
1 - You can convert the array to a list using
Arrays.asList(yourIntegerArray);
2 - Using a list, you can just use indexOf().
3 - Consider a scenario where you have a list of some length, you want the number closest to 3, you've already found that 2 is in the array, and you know that 3 is not. Without checking the other numbers, you can safely conclude that 2 is the best, because it's impossible to be closer. I'm not sure how indexOf() works, however, so this may not actually speed you up.
4 - Expanding on 3, let's say that indexOf() takes no more time than getting the value at an index. Then if you want the number closest to 3 in an array and you already have found 1, and have many more numbers to check, then it'll be faster to just check whether 2 or 4 is in the array.
5 - Expanding on 3 and 4, I think it might be possible to apply this to floats and doubles, although it would require that you use a step size smaller than 1... calculating how small seems beyond the scope of the question, though.
// paulmurray's answer to your question is really the best :
// The least square solution is way more elegant,
// here is a test code where numbertoLookFor
// is zero, if you want to try ...
import java.util.* ;
public class main {
public static void main(String[] args)
{
int[] somenumbers = {-2,3,6,1,5,5,-1} ;
ArrayList<Integer> l = new ArrayList<Integer>(10) ;
for(int i=0 ; i<somenumbers.length ; i++)
{
l.add(somenumbers[i]) ;
}
Collections.sort(l,
new java.util.Comparator<Integer>()
{
public int compare(Integer n1, Integer n2)
{
return n1*n1 - n2*n2 ;
}
}
) ;
Integer first = l.get(0) ;
System.out.println("nearest number is " + first) ;
}
}
int[] somenumbers = getAnArrayOfSomenumbers();
int numbertoLookFor = getTheNumberToLookFor();
boolean arrayContainsNumber =
new HashSet(Arrays.asList(somenumbers))
.contains(numbertoLookfor);
It's fast, too.
Oh - you wanted to find the nearest number? In that case:
int[] somenumbers = getAnArrayOfSomenumbers();
int numbertoLookFor = getTheNumberToLookFor();
ArrayList<Integer> l = new ArrayList<Integer>(
Arrays.asList(somenumbers)
);
Collections.sort(l);
while(l.size()>1) {
if(numbertoolookfor <= l.get((l.size()/2)-1)) {
l = l.subList(0, l.size()/2);
}
else {
l = l.subList(l.size()/2, l.size);
}
}
System.out.println("nearest number is" + l.get(0));
Oh - hang on: you were after a least squares solution?
Collections.sort(l, new Comparator<Integer>(){
public int compare(Integer o1, Integer o2) {
return (o1-numbertoLookFor)*(o1-numbertoLookFor) -
(o2-numbertoLookFor)*(o2-numbertoLookFor);
}});
System.out.println("nearest number is" + l.get(0));

Categories