Mathematical calculations using ArrayLists - java

I'd like to add (using the mathematical term) two Integer ArrayLists in Java, as well as divide them.
How would I go about this algorithmically? I can't for the life of me think of something, perhaps having to do with two's complements.
Okay, so let's say that I have large integers that are put into an ArrayLists, so to start off like 1233 and 1245. How would I divide those two with ArrayLists? a.get(i)? I could easily do it with an integer or a long, but if it had thousands of digits, that wouldn't work so well.
And yes, I'd like to add/divide the contents of the ArrayLists. If I used the get method and added them, I'd get something like [6,8,10,12] instead of that. But I guess I need to have single digits in each slot of the ArrayList. Does that explain it a bit better? It's supposed to work similarly to BigInteger class in Java.
ArrayList a = [1,2,3,4,3,4,3,5,1,3];
ArrayList b = [9,9,9,9,9,9,9,9,9,9,9];
How do I add those two into an ArrayList that should look like
ArrayList c = [1,0,1,2,3,4,3,4,3,5,1,2];
or look like c = [1,2,3,4,3,4,3,5,1,2,9,8,7,6,5,6,5,6,4,8,7];

I'm assuming you have ArrayLists of the same length and you want to use integer addition between the elements?
for (int i = 0; i < arr1.size(); ++i) {
arr1.set(i, arr1.get(i) + arr2.get(i));
}
Or you could make a 3rd array instead of adding to the first ArrayList in-place
ArrayList<Integer> arr3 = new ArrayList<Integer>();
for (int i = 0; i < arr1.size(); ++i) {
arr3.add(arr1.get(i) + arr2.get(i));
}

Java has a class BigInteger that can do math with arbitrarily long numbers. Consider this instead of re-inventing.
http://docs.oracle.com/javase/1.7.0/docs/api/java/math/BigInteger.html

Related

Pick a number randomly from two numbers

I have two integers, let them be
int a = 35:
int b = 70;
I want to pick one of them randomly at runtime and assign to another variable. I.e.
int c = a or b:
One of the ways that come into my mind is to create an array with these two integers and find a random integer between 0 and 1 and use it as the index of the array to get the number..
Or randomize boolean and use it in if-else.
My question is that is there a better and more efficient way to achieve this? I.e. pick a number from two previously defined integers?
Is there a specific reason you are asking for a more efficient solution? Unless this functionality sits in a very tight inner loop somewhere (e.g. in a ray tracer), you might be trying to prematurely optimize your code.
If you would like to avoid the array, and if you don't like the "bloat" of an if-statement, you can use the ternary choice operator to pick between the two:
int a = 35;
int b = 70;
int c = random.nextBoolean() ? a : b;
where random is an instance of java.util.Random. You can store this instance as a final static field in your class to reuse it.
If you don't require true randomness, but just want to switch between the two numbers in each invocation of the given block of code, you can get away with just storing a boolean and toggling it:
...
int c = toggle ? a : b;
toggle = !toggle;
Since I can't comment on other answers, I'd like to point out an issue with some of the other answers that suggest generating a random integer in a bigger range and making a decision based on whether the result is odd or even, or if it's lower or greater than the middle value. This is in effect the exact same thing as generating a random integer between 0 and 1, except overly complicated. The nextInt(n) method uses the modulo operator on a randomly generated integer between -2^31 and (2^31)-1, which is essentially what you will be doing in the end anyway, just with n = 2.
If you are using the standard library methods like Collections.shuffle(), you will again be overcomplicating things, because the standard library uses the random number generator of the standard library.
Note that all of the suggestions (so far) are less efficient than my simple nextBoolean() suggestion, because they require unnecessary method calls and arithmetic.
Another way to do this is, store the numbers into a list, shuffle, and take the first element.
ArrayList<Integer> numbers=new ArrayList<Integer>();
numbers.add(35);
numbers.add(70);
Collections.shuffle(numbers);
numbers.get(0);
In my opinion, main problem here is entropy for two numbers rather than making use of that entropy. Indexed array or boolean are essentially the same thing. What else you can do (and, hopefully, it will be more random) is to make Java give you a random number between limits say 0 to 100. Now, if the chosen random number is odd, you pick int c = a. Pick b otherwise. I could be wrong, but picking random between 0 to 100 seems more random as compared to picking random between two numbers.
You can simply use secure random generator(java.security.SecureRandom ).
try {
r = SecureRandom.getInstance("SHA1PRNG");
boolean b1 = r.nextBoolean();
if (b1) {
c = a;
} else {
c = b;
}
} catch (NoSuchAlgorithmException nsae) {
// Process the exception in some way or the other
}
Refer this link for more information
Randomize an integer between 1 and 10, if it's more than 5 then take the value of b other wise go with a. As far as I know there are no other ways to select from integers.
int a=1;
int b=2;
int get = new Random().nextBoolean()? a : b;

Simple Number to Array with Individual Digits

I am exceptionally new to programming, but I am working on improving my skills as a programmer. Currently, I am working on a problem I gave myself where I am trying to take a variable number and make each of its digits a separate number in an array. I don't care about the order of the digits, so if they are reversed, then it doesn't matter to me. I know people have asked this question numerous times, but they always seem to use a lot of things that I don't understand. Since my school doesn't offer any Java courses, I only know what I have learned on my own, so if you could explain any terms you use in the code that aren't extremely trivial, that would be wonderful. Right now, I have written:
int number = 1234567890;
while (number > 0) {
System.out.println(number%10);
number = number/10;
This works fine for printing the digits individually, but I can't figure out how to add them to the array. I greatly appreciate any help you can give, and please keep in mind that I much prefer simplicity over small size. Thank you in advance!
P.S. Some responses I've seen for similar questions include what I think are arrays of strings. In order for the part of the program that I have working to still work, I think that I need to use an array of integers. If you're curious, the rest of the code is used to determine if the numbers in the array are all different, in order to achieve the final result of determining if a number's digits are all distinct. It looks like this:
int repeats=0;
int[] digitArray;
digitArray = new int[10];
for (int i = 0; i < digitArray.length; i++)
for (int j = 0; j < digitArray.length; j++)
if ((i != j) && (digitArray[i]==digitArray[j])) unique = unique+1;
System.out.println(unique==0);
Method number.toString().length() will return the number of digits. That is the same as the length of your needed array. Then you use your code as before, yet instead of printing you add the digit to the array.
int number = 1234567890;
int len = Integer.toString(number).length();
int[] iarray = new int[len];
for (int index = 0; index < len; index++) {
iarray[index] = number % 10;
number /= 10;
}
I would rather suggest you to use an ArrayList, since to use an array, you would have to allocate the size in advance, for which you need to know the number of digits in your number, which you don't know.
So, either work with an array, and do the iteration over the number twice - once for finding size, and next for doing actual work. Else, move ahead with an ArrayList.
Adding an element to an ArrayList is quite simple. You just need to call - List#add(E) method with appropriate parameter.
So, here's an extension of your solution: -
// Declare a List<Integer>, since it will store integers only.
List<Integer> digits = new ArrayList<Integer>():
int number = 1234567890;
while (number > 0) {
int digit = number % 10; // Store digit in a variable
number = number/10;
// Add digit to the list
digits.add(digit);
}
Alternatively, if you want to have only unique digits in your List, then you should use a HashSet, which automatically removes the duplicates.
With Java 8:
Integer.toString(n).chars().map(a->a-'0').toArray()
char [] arr = scan.next().toCharArray();
This code will read a number from scan.next() and then it is going to give it as an input to char array which will have the number at its indices as single digit by digit.
Hope this will help.

Randomly generated numbers in a basic array

I simply need to know what i should do to make so that a basic array is filled with randomly generated numbers. now i know how to do that, what i don't know how to to do is to make it so that the randomly generated numbers are bigger than the last number generated all the way through to the end of the array.
Just generate for the list, and then sort them smallest to largest.
for(int i = 0; i < arr.length; ++i) {
arr[i] = Random.nextInt(100);
}
Arrays.sort(arr);
Generate random numbers, and then sort the array.
You can sort the array using Arrays.sort()
It doesn't make sure that each number is strictly bigger then the previous numbers [it only gurantees <=], so if it is an issue - you will have to make sure you have no dupes in the generated numbers.
You can generate an array of random numbers, and then sort it using Array sort.
There was a comment on the question, I lost the author's name, that recommended adding the randomly generated number to the previous number, which I thought was an interesting approach.
arr[0] = Random.nextInt(100);
for(int i = 1; i < arr.length; ++i) {
arr[i] = arr[i-1] + Random.nextInt(100);
}
This removes the need to sort your result array.
You can have your own algorithm of generating incremental...
For example...
Random each time and add that number to the last one :)
Random class in java does not allow you to have a minim limit where to start.. only one...
For example:
myArray[0] = Random.nextInt(10000);
for(int i=1; i<myArray.length; i++)
{
myArray[i] = myArray[i-1]+Random.nextInt(10000);
}
So.. it's random and you don't have to sort it.. try keeping everything simple...
I'm surprised no one mentioned that we can use SecureRandom API to easily generate random arrays without manually populating it.
For ex. generating a random array of size 100:
SecureRandom random = new SecureRandom();
int arr[] = random.ints(100).toArray();
BTW this should be possible from java 8 onwards.

Java double[][] Issue

I'm doing the following on my code:
double[][] temp=new double[0][2];
The program will run with no runtime exceptions. When I get the length of the temp like this temp.length it returns 0 and when I tried accessing the length of the inner arrays like this temp[0].length it always throws an ArrayIndexOutOfBoundsException. (That was only a test.)
Now I am wondering, Java did create a array with 0 length and at the same time an inner array with a length of 2 in an array with 0 length?
Did this kind of declaration has implications on memory management?
Will it develop complications on the coding and running the code?
Did Java really permit this kind of declaration?
In what sense did they permit this kind of declaration or did they just overlook this kind of situation?
And if they permit this declaration does it also has some special uses?
I was just exploring the possibility of doing this kind of declaration and had been questioning myself if this is really permissible.
Your opinions are gladly appreciated.
It is equivalent to
double[][] temp = new double[0][]; // a zero length array of double[]
for(int d=0; d<0; d++)
temp[d] = new double[2]; // whose each element is a new double[2]
of course the loop isn't executed, so there's no waste from "inner array"
see 15.10.1 Run-time Evaluation of Array Creation Expressions (JLS 3 - CHAPTER 15 Expressions)
If an array creation expression
contains N DimExpr expressions, then
it effectively executes a set of
nested loops of depth N-1 to create
the implied arrays of arrays. For
example, the declaration:
float[][] matrix = new float[3][3];
is equivalent in behavior to:
float[][] matrix = new float[3][];
for (int d = 0; d < matrix.length; d++)
matrix[d] = new float[3];
,so
double[][] temp=new double[0][2];
will be equivalent to
double[][] matrix = new double[0][];
for (int d = 0; d < 0; d++)
matrix[d] = new double[2];//would newer hepened
The only valid scenario ,I can think of is where you want to send and empty 2 dimensional array.
double[][] temp = new double[0][0];
return temp;
The above is a valid requirement in many matrix calculations.
Did this kind of declaration has
implications on memory management?
Not sure. And might also depends on the JVM to JVM implementations.
Will it develop complications on the
coding and running the code?
It should not if you are accessing the array in a loop like this
for(int i = 0; i<temp.length;i++)
for(int j=0; j<temp[i].length;j++)
{
// your code
}
Otherwise if you are accessing directly by using index then you should first check the index bounds.
Did Java really permit this kind of
declaration?
Yes. As I have said in the first statement.
In what sense did they permit this
kind of declaration or did they just
overlook this kind of situation?
As said before: A valid scenario is where you want to send and empty 2 dimensional array
There might be other scenarios.
And if they permit this declaration
does it also has some special uses?
Other than the my last answer I am not sure of any other scenario. But would love to know if they exist.

Sorting matched arrays in Java

Let's say that I have two arrays (in Java),
int[] numbers; and int[] colors;
Each ith element of numbers corresponds to its ith element in colors.
Ex, numbers = {4,2,1}
colors = {0x11, 0x24, 0x01}; Means that number 4 is color 0x11, number 2 is 0x24, etc.
I want to sort the numbers array, but then still have it so each element matches up with its pair in colors.
Ex. numbers = {1,2,4};
colors = {0x01,0x24,0x11};
What's the cleanest, simplest way to do this? The arrays have a few thousand items, so being in place would be best, but not required. Would it make sense to do an Arrays.sort() and a custom comparator? Using library functions as much as possible is preferable.
Note: I know the "best" solution is to make a class for the two elements and use a custom comparator. This question is meant to ask people for the quickest way to code this. Imagine being at a programming competition, you wouldn't want to be making all these extra classes, anonymous classes for the comparator, etc. Better yet, forget Java; how would you code it in C?
You could use sort() with a custom comparator if you kept a third array with the index, and sorted on that, leaving the data intact.
Java code example:
Integer[] idx = new Integer[numbers.length];
for( int i = 0 ; i < idx.length; i++ ) idx[i] = i;
Arrays.sort(idx, new Comparator<Integer>() {
public int compare(Integer i1, Integer i2) {
return Double.compare(numbers[i1], numbers[i2]);
}
});
// numbers[idx[i]] is the sorted number at index i
// colors[idx[i]] is the sorted color at index i
Note that you have to use Integer instead of int or you can't use a custom comparator.
It seems like the cleanest thing to do would be to create a custom property class that implements Comparable. For example:
class Color implements Comparable {
private int number;
private int color;
// (snip ctor, setters, etc.)
public int getNumber() {
return number;
}
public int getColor() {
return color;
}
public int compareTo(Color other) {
if (this.getNumber() == other.getNumber) {
return 0;
} else if (this.getNumber() > other.getNumber) {
return 1;
} else {
return -1;
}
}
}
Then you can separate your sorting algorithm from the ordering logic (you could use Collections.sort if you use a List instead of an array), and most importantly, you won't have to worry about somehow getting two arrays out of sync.
If you'd be willing to allocate some extra space, you could generate another array, call it extra, with elements like this:
extra = [0,1,...,numbers.length-1]
Then you could sort this extra array using Arrays.sort() with custom comparator (that, while comparing elements i and j really compares numbers[extra[i]] and numbers[extra[j]]). This way after sorting the extra array, extra[0] would contain the index of the smallest number and, as numbers and colours didn't move, the corresponding colour.
This isn't very nice, but it gets the job done, and I can't really think of an easier way to do it.
As a side note, in the competition I usually find the C++ templated pairs and nice maps indispensable ;)
Why not introduce an object to represent a number and a color and implement a comparator function for that?
Also, do you really need an array, why not use something derived from Collection?
I like #tovare's solution. Make a pointer array:
int ptr[] = { 1, 2, 3 };
and then when you sort on numbers, swap the values in ptr instead of in numbers. Then access through the ptr array, like
for (int i = 0; i < ptr.length; i++)
{
printf("%d %d\n", numbers[ptr[i]], colors[ptr[i]]);
}
Update: ok, it appears others have beaten me to this. No XP for me.
An example illustrating using a third index array. Not sure if this is the best implementation.
import java.util.*;
public class Sort {
private static void printTable(String caption, Integer[] numbers,
Integer[] colors, Integer[] sortOrder){
System.out.println(caption+
"\nNo Num Color"+
"\n----------------");
for(int i=0;i<sortOrder.length;i++){
System.out.printf("%x %d %d\n",
i,numbers[sortOrder[i]],colors[sortOrder[i]]);
}
}
public static void main(String[] args) {
final Integer[] numbers = {1,4,3,4,2,6};
final Integer[] colors = {0x50,0x34,0x00,0xfe,0xff,0xff};
Integer[] sortOrder = new Integer[numbers.length];
// Create index array.
for(int i=0; i<sortOrder.length; i++){
sortOrder[i] = i;
}
printTable("\nNot sorted",numbers, colors, sortOrder);
Arrays.sort(sortOrder,new Comparator<Integer>() {
public int compare(Integer a, Integer b){
return numbers[b]-numbers[a];
}});
printTable("\nSorted by numbers",numbers, colors, sortOrder);
Arrays.sort(sortOrder,new Comparator<Integer>() {
public int compare(Integer a, Integer b){
return colors[b]-colors[a];
}});
printTable("\nSorted by colors",numbers, colors, sortOrder);
}
}
The output should look like this:
Not sorted
No Num Color
----------------
0 1 80
1 4 52
2 3 0
3 4 254
4 2 255
5 6 255
Sorted by numbers
No Num Color
----------------
0 6 255
1 4 52
2 4 254
3 3 0
4 2 255
5 1 80
Sorted by colors
No Num Color
----------------
0 6 255
1 2 255
2 4 254
3 1 80
4 4 52
5 3 0
One quick hack would be to combine the two arrays with bit shifts. Make an array of longs such that the most significant 32 bits is the number and the least significant 32 is the color. Use a sorting method and then unpack.
Would it suffice to code your own sort method? A simple bubblesort would probably be quick to code (and get right). No need for extra classes or comparators.
Credit to #tovare for the original best answer.
My answer below removes the (now) unnecessary autoboxing via Maven dependency {net.mintern : primitive : 1.2.2} from this answer: https://stackoverflow.com/a/27095994/257299
int[] idx = new int[numbers.length];
for( int i = 0 ; i < idx.length; i++ ) idx[i] = i;
final boolean isStableSort = false;
Primitive.sort(idx,
(i1, i2) -> Double.compare(numbers[i1], numbers[i2]),
isStableSort);
// numbers[idx[i]] is the sorted number at index i
// colors[idx[i]] is the sorted color at index i
I guess you want performance optimization while trying to avoid using array of objects (which can cause a painful GC event).
Unfortunately there's no general solution, thought.
But, for your specific case, in which numbers are different from each others, there might be two arrays to be created only.
/**
* work only for array of different numbers
*/
private void sortPairArray(int[] numbers, int[] colors) {
int[] tmpNumbers = Arrays.copyOf(numbers, numbers.length);
int[] tmpColors = Arrays.copyOf(colors, colors.length);
Arrays.sort(numbers);
for (int i = 0; i < tmpNumbers.length; i++) {
int number = tmpNumbers[i];
int index = Arrays.binarySearch(numbers, number); // surely this will be found
colors[index] = tmpColors[i];
}
}
Two sorted arrays can be replace by Int2IntOpenHashMap, which performs faster run, but memory usage could be double.
You need to sort the colors array by its relative item in the numbers array. Specify a comparator that compares numbers and use that as the comparison for the colors array.
The simplest way to do this in C, would be bubblesort + dual pointers. Ofcourse the fastest would be quicksort + two pointers. Ofcourse the 2nd pointer maintains the correlation between the two arrays.
I would rather define values that are stored in two arrays as a struct, and use the struct in a single array. Then use quicksort on it. you can write a generic version of sort, by calling a compare function, which can then be written for each struct, but then you already know that :)
Use a TreeMap

Categories