Call all elements in an array at the same time - java

I am trying to make a program to apply an operation between all values in an array or string, however the operation is a bitwise ^ operation between all the elements. Is there anything that can do this? Between my knowledge of lists and arrays I don't even know where to start.
EX:
int[] n = {0,1,2,3,4,6}
// program that can do the operation for 0^1^2^3^4^6

You can't do that with arrays but you can achieve what you wanna do with the list using streams;
List<Integer> l = Arrays.asList(1,2,3,4,6);
int res = l.stream().reduce(0, (m,k) -> m +k);

Related

Pseudo code: Random Permutation

I have a pseudo code that I have translated into java code but anytime I run the code, I get an empty arraylist as a result but it is supposed to give me a random list of integers.
Here is the pseudo code:
Algorithm 1. RandPerm(N)
Input: Number of cities N
1) Let P = list of length N, (|P|=N) where pi=i
2) Let T = an empty list
3) While |P| > 0
4) Let i = UI(1,|P|)
5) Add pi to the end of T
6) Delete the ith element (pi) from P
7) End While
Output: Random tour T
Here is the java code:
public static ArrayList<Integer> RandPerm(int n)
{
ArrayList<Integer> P = new ArrayList<>(n);
ArrayList<Integer> T = new ArrayList<>();
int i;
while(P.size() > 0)
{
i = CS2004.UI(1, P.size());// generate random numbers between 1 and the size of P
T.add(P.get(i));
P.remove(P.get(i));
}
return T;
}
I don't know what I am doing wrong.
ArrayList<Integer> p = new ArrayList<>(n);
... creates an empty list with an initial capacity of n.
All this does is tell the ArrayList what size array to initialise as backing store - most of the time you achieve nothing useful by specifying this.
So your while(p.size() > 0) runs zero times, because p.size() is zero at the start.
In the pseudocode "where pi=i" suggests to me that you want to initialise the list like this:
for(int i=0;i<n;i++) {
p.add(i)
}
(I have lowercased your variable name - in Java the convention is for variables to startWithALowerCaseLetter -- only class names StartWithUpperCase. It's also the Java convention to give variables descriptive names, so cityIdentifiers perhaps)
You may want to know that, even if you fix the problem that P is always empty, there are 2 more issues with your implementation.
One is that P.remove(P.get(i)) does not necessarily remove the ith item if the list has equal value items. It scans from the beginning and removes the first occurrence of the item. See ArrayList.remove(Object obj). You should use P.remove(i) instead for the correct results.
Then the performance is O(n^2). The reason is that ArrayList remove an item by shifting all the subsequent items one slot to the left, which is an O(n) operation. To get a much better performance, you can implement your own "remove" operation by swapping the item to the end. When you generate the next random index, generate it within the range [0, beginning index of the removed items at the end). Swapping is O(1) and the overall performance is O(n). This is called Knuth Shuffle by the way.

How to generate random array of ints using Stream API Java 8?

I am trying to generate random array of integers using new Stream API in Java 8. But I haven't understood this API clearly yet. So I need help. Here is my code.
Random random = new Random();
IntStream intStream = random.ints(low, high);
int[] array = intStream.limit(limit) // Limit amount of elements
.boxed() // cast to Integer
.toArray();
But this code returns array of objects. What is wrong with it?
If you want primitive int values, do not call IntStream::boxed as that produces Integer objects by boxing.
Simply use Random::ints which returns an IntStream:
int[] array = new Random().ints(size, lowBound, highBound).toArray();
To generate random numbers from range 0 to 350, limiting the result to 10, and collect as a List. Later it could be typecasted.
However, There are no guarantees on the type, mutability, serializability, or thread-safety of the List returned.
List<Object> numbers = new Random().ints(0,350).limit(10).boxed().collect(Collectors.toList());
and to get thearray of int use
int[] numbers = new Random().ints(0,350).limit(10).toArray();
There's no reason to boxed(). Just receive the Stream as an int[].
int[] array = intStream.limit(limit).toArray();
tl;dr
ThreadLocalRandom // A random number generator isolated to the current thread.
.current() // Returns the current thread's `ThreadLocalRandom` object.
.ints( low , high ) // Pass the "origin" (inclusive) and "bound" (exclusive).
.limit( 100 ) // How many elements (integers) do you want in your stream?
.toArray() // Convert the stream of `int` values into an array `int[]`.
ThreadLocalRandom
You can do it using ThreadLocalRandom.
The ints method generates an IntStream within your specified bounds. Note the the low is inclusive while the high is exclusive. If you want to include your high number, just add one while calling the ints method.
int[] randInts = ThreadLocalRandom.current().ints( low , high ).limit(100).toArray();
See this code run live at IdeOne.com.

Java 8 Stream and operation on arrays

I have just discovered the new Java 8 stream capabilities. Coming from Python, I was wondering if there was now a neat way to do operations on arrays like summing, multiplying two arrays in a "one line pythonic" way ?
Thanks
There are new methods added to java.util.Arrays to convert an array into a Java 8 stream which can then be used for summing etc.
int sum = Arrays.stream(myIntArray).sum();
Multiplying two arrays is a little more difficult because I can't think of a way to get the value AND the index at the same time as a Stream operation. This means you probably have to stream over the indexes of the array.
//in this example a[] and b[] are same length
int[] a = ...
int[] b = ...
int[] result = new int[a.length];
IntStream.range(0, a.length).forEach(i -> result[i] = a[i] * b[i]);
Commenter #Holger points out you can use the map method instead of forEach like this:
int[] result = IntStream.range(0, a.length).map(i -> a[i] * b[i]).toArray();
You can turn an array into a stream by using Arrays.stream():
int[] ns = new int[] {1,2,3,4,5};
Arrays.stream(ns);
Once you've got your stream, you can use any of the methods described in the documentation, like sum() or whatever. You can map or filter like in Python by calling the relevant stream methods with a Lambda function:
Arrays.stream(ns).map(n -> n * 2);
Arrays.stream(ns).filter(n -> n % 4 == 0);
Once you're done modifying your stream, you then call toArray() to convert it back into an array to use elsewhere:
int[] ns = new int[] {1,2,3,4,5};
int[] ms = Arrays.stream(ns).map(n -> n * 2).filter(n -> n % 4 == 0).toArray();
Be careful if you have to deal with large numbers.
int[] arr = new int[]{Integer.MIN_VALUE, Integer.MIN_VALUE};
long sum = Arrays.stream(arr).sum(); // Wrong: sum == 0
The sum above is not 2 * Integer.MIN_VALUE.
You need to do this in this case.
long sum = Arrays.stream(arr).mapToLong(Long::valueOf).sum(); // Correct
Please note that Arrays.stream(arr) create a LongStream (or IntStream, ...) instead of Stream so the map function cannot be used to modify the type. This is why .mapToLong, mapToObject, ... functions are provided.
Take a look at why-cant-i-map-integers-to-strings-when-streaming-from-an-array

Confusing regarding .get and .set in an ArrayList

(I'm new at Java, coming over from Python ---)
I'm going through a tutorial and they've created a program which counts how many times a number appears in a file, then returns that number. One particular part of the program is somewhat mysterious to me and deals with the ArrayList's .get and .set (methods? functions?). The program goes like this:
// (Scan a file with the numbers, say, 2 2 3 4, and put it into data1 variable.)
// (Make An Empty ArrayList with a bunch of 0's)
Scanner data1 = null;
ArrayList<Integer> count = new ArrayList<Integer>();
Integer idx;
while(data1.hasNextInt()){
idx = data1.nextInt();
System.out.println(idx);
System.out.println(count.get(idx)+1);
count.set(idx,count.get(idx)+1);
}
//Then prints out all the values; the ArrayList contains the number of times the number n occurs in the n-th index.
My question comes at the "while" part. For concrete, let's assume data1 has the numbers 2 2 3 4. It seems that it takes idx = 2, then puts a 1 in count[2], which is reasonable. It then takes idx = 2 again (the next integer in data1) and puts a 2 in count[2], which is also reasonable. At this point, the next number in data1 makes idx = 3, but it occurs at the index 2 in the ArrayList, so it should put a 3 in count[3], which is incorrect.
So, what is .get and .set doing here? Do they pop the elements off of the list when they're done with it? Am I overlooking something?
A .get() will not automagically get elements from a List which does not have that many elements. Note: list indices, like arrays, start at 0.
If you do:
final List<Integer> = new ArrayList<Integer>();
list.get(0);
this is a runtime error (IndexOutOfBoundsException) because your list has no elements.
You have to fill it:
list.add(1); // append an element
list.get(0); // returns element at index 0
list.get(1); // IndexOutOfBoundsException!
The .set() method takes an index and a value at an argument. In a similar vein, you cannot set an element which does not already exist, except at the very end of the list:
// start from an empty list
list.set(1, 32); // IndexOutOfBoundsException!
list.set(0, 32); // OK
Final note: try not to use list[i], bracket indices are used for arrays ;) Note that arrays are not resizabe in Java. Lists (which are an implementation of a Collection), however, are. But you must append to them.
So, what this line does:
count.set(idx, count.get(idx) + 1);
is take the value at index idx, add 1 to it, and sets back this value at the same index.
In your specific case, what you are looking for is a sparse array. In Java we use a HashMap<Integer, Integer> for that purpose. You don't need any initialization with zeros, but you do need to check for null:
final Integer curr = count.get(idx);
count.put(idx, curr == null? 1 : curr+1);
You are currently using an ArrayList, which acts like an array, but makes it easier to expand it - for example, add elements to it.
What you want is the java equivalent of the python dict, a key/value storage, in java, this is called a HashMap<K,V> (docs).
Scanner data1 = null;
HashMap<Integer, Integer> count = new HashMap<Integer, Integer>();
Integer idx;
while(data1.hasNextInt()) {
idx = data1.nextInt();
System.out.println(idx);
Integer g = count.get(idx)+1;
if(g == null) {
g = 0;
}
g++;
System.out.println(g);
count.put(idx, g);
}

Mathematical calculations using ArrayLists

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

Categories