Iterate array if index range is in long - java

how to iterate through array/ list in Java. if index range is in long. As array/list only accept integer in position index.
eg
long arr[]=new long[5];
for(long i=0l;i<5l;i++)
arr[i]=i; // throw an error as arr[i] only accept integer
here arr[i] will throw an error because i is of type long and array takes input as integer in index location.
Can anyone help me out with this?

The size limit1 on arrays is Integer.MAX_VALUE so an array index that is a long makes no sense.
A List can have more than Integer.MAX_VALUE elements, but indexing it will be problematic because List::get takes an int argument.
So, you will struggle to use either arrays or lists (implemented using List) for really large data structures.
The solution ... if you really need one ... would be to implement your own List class with overload or alternative for operations that expose the size and indexing. It would not be trivial.
Another (possibly simpler) approach would be to represent your long[] as a long[][] and map the subscripts.
Finally, if you are using long as a subscript unnecessarily (i.e. the indexes don't need to go beyond Integer.MAX_VALUE), then:
long arr[] = new long[5];
for (long i = 0l; i < 5l; i++) {
arr[(int) i] = i;
}
1 - This is the theoretical maximum size. 1) You may get an OutOfMemoryError if you attempt to allocate an array that large. The JVM needs at least length * size(<type>) bytes of free contiguous storage to allocate an array of <type> of length length, where size(<type>) is the size of a primitive type or a reference. 2) In a 32 bit JVM, you are also limited by the address space dimensions. 3) In recent Hotspot JVMs, the largest array that you can allocate is actually Integer.MAX_VALUE - 5 elements: see Do Java arrays have a maximum size?

You don't need the index to be long even if your array consists of long's. Change it to
for(int i = 0; ....)

Two solutions:
Narrow the long to an integer by a cast arr[(int)i] = i;
Change the type of i to an integer and let the compiler widen it for you when it is assigned for(int i = 0; i < 5; i++) arr[i] = i;
As you cannot map all long values to a integer the compiler will not automatically narrow a variable. As you can map all integer values to a long the compiler will widen a variable automatically for you.

Related

Array declaration to allow any int value as index

Is there any way to declare an int array (arr), such that
an index i can represent any number <= Integer.MAX_VALUE, which cannot be known ahead of time.
So arr[i] will never return an error, as long as the value is <= Integer.MAX_VALUE
I tried int[] arr = new int[Integer.MAX_VALUE], but that requires too much space and is not feasible.
In Java it is not possible to declare array without size. You don't need to occupy memory for all unused indices using an array. What you need is a Map, which is space efficient for your use case.
Map<Integer, Object> index = new HashMap<>();
//store
index.put(1, "Value 1");
index.put(2, "Value 2");
//retrieve
index.get(1); //returns: Value 1

Get max length of row and column in java two dimensional array

What is the best and efficient way to get the maximum i, which is the number of rows and j, which is the number of columns, in a two dimensional array?
Hopefully, the time complexity can be lower than O(n) for every case. No loop here and can still find the maximum j.
For example, if I have an array like this one
[
[18,18,19,19,20,22,22,24,25,26],
[1,2,3],
[0,0,0,0]
]
Then I want to get i = 3 and j = 10 here as a result.
Can anyone help me?
You can avoid writing the loop yourself, but you can't avoid having a runtime of at least O(n), since "someone" needs to loop the source array.
Here is a possible way to do that in Java 8:
Arrays.stream(arr).map(row -> row.length).max(Integer::compare).get();
This returns the maximum length of a "row" in your 2d array:
10
Another version which avoids using the Comparator and therefore might be a bit easier to read:
Arrays.stream(arr).mapToInt(row -> row.length).max().getAsInt();
arr is supposed to be your source array.
Edit: the older version used .max(Integer::max), which is wrong and causes wrong results. See this answer for an explanation.
Assuming your array does not contain null values, you could write something like this:
private static final Comparator<int[]> lengthComparator = new Comparator<int[]> () {
#Override
public int compare(int[] o1, int[] o2) {
return o1.length - o2.length;
}
};
#Test
public void soArrayMaxLength() {
int[][] array = new int[][] {
{18,18,19,19,20, 22, 22, 24, 25,26},
{1,2,3},
{0,0,0,0}
};
int i = array.length;
Optional<int[]> longestArray =
Arrays.stream(array)
.max(lengthComparator);
int j = longestArray.isPresent() ? longestArray.get().length : 0;
System.out.println(String.format("i=%d j=%d", i, j));
}
If you happen to create a parallel stream from the array instead, you could speed up this even further.
Another option is to sort the array by length, the quicksort usually has an average complexity of O(n*log(n)) therefore this isn't faster;
int i = array.length;
Arrays.parallelSort(array, lengthComparator);
int j = array[i-1].length;
System.out.println(String.format("i=%d j=%d", i, j));
Your i is the number of rows, which is simply the length of the 2-D array (assuming you are OK with including empty/null rows in this count).
The max row length j, however, would require iterating over all the rows to find the row i having the maximum arr[i].length.
There will always be a loop1, even though the looping will be implicit in solutions that use Java 8 streams.
The complexity of getting the max number of columns is O(N) where N is the number of rows.
Implicit looping using streams probably will be less efficient than explicit looping using for.
Here's a neat solution using a for loop
int max = o;
for (int i = 0; i < array.length; i++) {
max = Math.max(max, array[i].length);
}
This works in the edge-case where array.length == 0, but if array or any array[i] is null you will get a NullPointerException. (You could modify the code to allow for that, but if the nulls are not expected, an NPE is probably a better outcome.)
1 - In theory, you could unroll the loops for all cases of array.length from 0 to Integer.MAX_VALUE, you would not need a loop. However, the code would not compile on any known Java compiler because it would exceed JVM limits on bytecode segments, etcetera. And the performance would be terrible for various reasons.
You could try this way: loop on the array and find the max length of the arrays which is in this array
byte[][] arrs = new byte[3][];
int maxLength = 0;
for (byte[] array : arrs) {
if (maxLength < array.length) {
maxLength = array.length;
}
}

repeated element in Array

I have an array of N elements and contain 1 to (N-1) integers-a sequence of integers starting from 1 to the max number N-1-, meaning that there is only one number is repeated, and I want to write an algorithm that return this repeated element, I have found a solution but it only could work if the array is sorted, which is may not be the case.
?
int i=0;
while(i<A[i])
{
i++
}
int rep = A[i];
I do not know why RC removed his comment but his idea was good.
With the knowledge of N you easy can calculate that the sum of [1:N-1]. then sum up all elementes in your array and subtract the above sum and you have your number.
This comes at the cost of O(n) and is not beatable.
However this only works with the preconditions you mentioned.
A more generic approach would be to sort the array and then simply walk through it. This would be O(n log(n)) and still better than your O(n²).
I you know the maximum number you may create a lookup table and init it with all zeros, walk through the array and check for one and mark the entries with one. The complexity is also just O(n) but at the expense of memory.
if the value range is unknown a simiar approach can be used but instead of using a lookup table a hashset canbe used.
Linear search will help you with complexity O(n):
final int n = ...;
final int a[] = createInput(n); // Expect each a[i] < n && a[i] >= 0
final int b[] = new int[n];
for (int i = 0; i < n; i++)
b[i]++;
for (int i = 0; i < n; i++)
if (b[i] >= 2)
return a[i];
throw new IllegalArgumentException("No duplicates found");
A possible solution is to sum all elements in the array and then to compute the sym of the integers up to N-1. After that subtract the two values and voila - you found your number. This is the solution proposed by vlad_tepesch and it is good, but has a drawback - you may overflow the integer type. To avoid this you can use 64 bit integer.
However I want to propose a slight modification - compute the xor sum of the integers up to N-1(that is compute 1^2^3^...(N-1)) and compute the xor sum of your array(i.e. a0^a1^...aN-1). After that xor the two values and the result will be the repeated element.

create an array of long

I'm trying to create an array of long in java, but eclipse is showing me an error as shown below:
Below is my code:
How can I resolve this?
Can't i create a long size array in java?
Arrays of longs are fine: long[]. But all arrays are int-indexed. So just change long n to int n in the method parameter declaration, and you'll be all set.
For index you have to use int but not long
i need an array of 10^9 elements
You can create an array of one billion using an int value. Make n an int, and you can create an array with new long[n] Note: this will use 8 GB of heap.
Since you are building all the elements using a formula, you should be able to give all the values dynamically. i.e. create a component which is a "virtual" array which would save you having to generate an array of them all.
The reason I point this out is that the second loop is likely to take minutes at best if k is very small, or could easily take days.
BTW: I can't see all the code, but it appears you never need more than k+1 values which can be allocated once instead of n-k times.
n (the array capacity) has to be an integer not long
You have my sympathy. We go through this every time memory sizes increase. There is a strange expectation that this time array sizes will not need to increase in parallel with memory sizes.
Your best solution is probably to write your own class with long get(long index) and void set(long value, long index) methods. It could represent the data as a long[10][1000000000], and encapsulate the mapping between the natural long index and the actual pair of int indices.
Please note that array size is always equal to int size.
if you specify the array size more than 2147483647 you will get error.
long n;
long a[]=new long[n];
this will create error because long n exceeds 2147483647.
if int n then no error occurs.
import java.util.*;
public class Main
{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
long[] arr = new long[n];//Just declare the size of array of int type , because we cannot declare the size of array as long type ,rather we can store the long type in it ,This code will fix the error .
for(int i=0;i<n;i++)
{
arr[i]=sc.nextLong();
}
for(long i:arr)
{
System.out.print(i+" ");
}
}
}
The index needs to be int so I convert long to int.
long n = sc.nextLong();
long[] arr = new long[(int)n];

Various ways of accessing an array

Today i did learn two ways of accessing the array, i would like to know the various ways of accessing an array element and the best practice of it. I am a student learning algorithm.
int [] arr;
long [] arr;
Advantages of long datatype declaration over int.
class ArrayApp{
public static void main(final String[] args){
long [] arr;
arr= new long[2];
int i;
arr[0]=112;
arr[1]=111;
**// Way one**
for(long l:arr)
{
System.out.println(l);
}
**// Way Two**
for(i=0;i<arr.length;i++) {
System.out.println(arr[i]);
}
}
}
There is no real difference between the ways here. Way one is just a syntax sugar for not to create an additional interation value.
The first way is preferable as it doesn't require an int i; variable and requires less printing. The second should be used when you don't want to iterate through the all array, but just a part of it.
There is no other ways to access the elements of array in java.
We've one declaration of an array:
long[] values = new long[100];
This creates an array for 100 long type values. Each value has an index (position) inside the array, the first index (an int value!) is 0, the last one is 99.
The traditional for loop increments an integer value to generate index position numbers. Those int values are used to access the long values of the array:
for (int index=0; index < values.length; index++) { // index is int
long value = values[index]; // value is long
// do something with value
}
The "enhanced" for loop simply hides this index and gives access to the long values with less code:
for (long value:values) {
// do something with value
}
That's all. If you don't need the index variable in your code, just use the enhanced for loop (second version in my answer)
The first way
for(long l:arr)
{
System.out.println(l);
}
The java runtime will autobox the l to a Long, as iterating this way requires that the class implement the Iterable interface. This way, also does not provide the current index of the array.
The second way
for(i=0;i<arr.length;i++) {
System.out.println(arr[i]);
}
Requires no casts to Long and you also have access to the current index. You also however have to be careful about iterating past the end of the array or accessing array elements below 0.
An int is shorter as a long. You can make an array of any object or primitive type. int[], Integer[], CustomClass[], whatever.
From java documentation:
int: The int data type is a 32-bit
signed two's complement integer. It
has a minimum value of -2,147,483,648
and a maximum value of 2,147,483,647
(inclusive). For integral values, this
data type is generally the default
choice unless there is a reason (like
the above) to choose something else.
This data type will most likely be
large enough for the numbers your
program will use, but if you need a
wider range of values, use long
instead.
long: The long data type is a 64-bit
signed two's complement integer. It
has a minimum value of
-9,223,372,036,854,775,808 and a maximum value of
9,223,372,036,854,775,807 (inclusive).
Use this data type when you need a
range of values wider than those
provided by int.

Categories