Array of Lists or Other Possibilities? - java

So my question starts out as being is it possible to make an array of linked lists in Java?
For some background on why I am asking. I am working on a project in which we are given a file of square matrices. We have to find the determinant of the matrices but they have to be stored in a linked structure. We have previously done this same thing using arrays and so I can reuse a decent bit of my source from that one. Here is what I have though up to do (mostly based on my previous project):
Read each line of the file in as a string
Count the number of matrices and determine where each starts and ends.
* Read each element of each matrix into a multi-linked ListNode (I'll write the class for those)
* Repeat for each matrix
Process the determinant of each.
So the two starred steps are the ones I'm having a tough time figuring out. I want to read in all the matrices at once so I don't lose track of where I am in the file like I would if I read in one matrix, did the determinant, and then went back to the file to get another one. However, I don't know how to store each linked list representation so that I can just iteratively process through each. My only thought is to read each matrix into the linked list structure and store each linked list structure in an array if possible. If not possible, what is a possible alternative?

It is entirely possible to store an array of LinkedLists; arrays can be applied to objects as well as primitive types. However, I would advise creating a Matrix class, because square matrices are not linked lists; they have data in two dimensions, not just one. At the very least, you could use a two-dimensional array of floats to represent a matrix, and store a LinkedList of double[][]s. The closer your representation is to the actual object, the easier it will be for you.

If you are allowed to use the standard LinkedList class what java already has, the here is a possible implementation of reading, and storing your matrices:
int size = 10; //width and height of your matrix.
LinkedList<LinkedList<Integer>> matrix = new LinkedList<LinkedList<Integer>>();
for (int i = 0; i<size; i++)
{
LinkedList<Integer> list = new LinkedList<Integer>();
for (int j = 0; j < size; j++)
{
//read the actual item
}
matrix.add(list);
}
For reading a matrix (probably numbers) i advise to use the class called Scanner. You can create a new Scanner, what will be able to read your file, number by number:
Scanner sc = new Scanner(new File("input.txt"));
And you can read integer values with it, without any conversion like this:
int x = sc.nextInt();

You can make an array of linked lists in Java by declaring LinkedList[], but if you do, your performance will suffer badly. A look at matrix multiplication will illustrate the reason.
If A and B are matrices where the A's column count equals B's row count, then A * B[r, c] is the dot product of row r in A with column c in B. This means we have to extract rows and columns from our matrices.
If we form matrices from lists (of any sort), we can store them row-wise (i.e., where the 0-th list represents row 0), or column-wise (where the 0-th list represents column 0).
Now we run into a problem. In a linked list, the method get(n) starts at the beginning of the list and finds the next member n times -- which makes it run in order n time. A matrix built from linked lists will either extract columns very slowly (if stored row-wise), or extract rows very slowly (if stored column-wise).
I's suggest keeping it simple by using arrays of arrays. You can allocate an n x n array with
int[][] values = new int[n][n];
The value 'n' must be defined, of course.
Hope that this helps.

Related

User defined Array dimensional and size

I have unsolvable task, I have task, where i have insert random number to array. The user can choose if array is 1D, 2D, 3D,size of array is optional . I tried everything but withot success. I can not use ArrayList.
Thank you for help.
double[] array= new double[size];
for ( int i;i<dimensional;i++)
{
double[] array= new double[size];
}
Edit:
I mind if is effective way to create array with 1D and then add to this array one or more dimension.
Multi-dimensional arrays in java are essentially just arrays of arrays. The user provides the number of dimensions and sizes at runtime so you need to dynamically build this array at this point. It's a strange problem, and not one that you would try to solve with arrays in production code, but nevertheless it should be possible. Try the accepted answer for this question, it seems like a pretty good attempt.
So, an "unsolvable" task ... well, as long as you work with primitive types and the dimension can be theoretically any number (only limited by memory available), you may be right.
You can however use some kind of object (Java is an object-oriented language) and solve the task rather easily. Basically, you might want a tree structure with nodes. You can even write a constructor that sets fixed sizes for every level and give no direct accessors to the array as a whole. Start with:
class Node {
double payload;
Node[] children;
}
I don't really understand what do you want to do with that, but it pretty much fits the idea of N-dimensional array.
Another solution: Make the array one-dimensional, but using the sizes of the individual dimensions, you can calculate the correct index. Of course, it will require you to handle the logic.
E.g. in a 2D array of 3x3 size, you can use a 1D array of 9 size and use first three indexes for first row, next three for second row, last three for third row. You can then use a cycle like this:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
//arr[i * 3 + j] = ...
}
}

Fast way to sort really big vector

I have a really big vector that stores 100000 different values,ranging from 0 to 50000.
They represent the cylinders on a hard disk,and I want to sort this vector according to three different algorithms used for disk scheduling.
So far,I read those 100000 values from a file,store them into a vector and then sort them according to the desired algorithm(FCFS,SCAN,SSTF).The problem is,it takes too long,because I'm doing it in the least creative way possible:
public static Vector<Integer> sortSSTF(Vector<Integer> array){
Vector<Integer> positions = new Vector<Integer>(array);
Vector<Integer> return_array = new Vector<Integer>();
int current_pos = 0,minimum,final_pos;
while(positions.size() > 0){
minimum = 999999;
final_pos = current_pos;
for(int i=0 ; i < positions.size() ; i++){
//do some math
}
}
return_array.add(final_pos);
current_pos = final_pos;
positions.removeElement(final_pos);
}
return return_array;
}
My function takes a vector as a parameter,makes a copy of it,does some math to find the desired element from the copied array and store him in the other array,that should be ordered according to the selected algorithm.But in a array with N elements,it is taking N! iterations to complete,which is way too much,since the code should do that at least 10 times.
My question is, how can I make this sorting more efficient?
Java already has built-in methods to sort a List very quickly; see Collections.sort.
Vector is old and incurs a performance penalty due to its synchronization overhead. Use a List implementation (for example, ArrayList) instead.
That said, based on the content of your question, it sounds like you're instead having difficulty implementing the Shortest Seek Time First algorithm.
See related question Shortest seek time first algorithm using Comparator.
I don't think you can implement the SSTF or SCAN algorithm if you don't also supply the current position of the head as an argument to your sorting method. Assuming the initial value of current_postion is always 0 will just give you a list sorted in ascending order, in which case your method would look like this:
public static List<Integer> sortSSTF(List<Integer> cylinders) {
List<Integer> result = new ArrayList<Integer>(cylinders);
Collections.sort(result);
return result;
}
But that won't necessarily be a correct Shortest Seek Time First ordering if it's ever possible for current_pos > 0 when you first enter the method. Your algorithm will then probably look something like this:
Collections.sort(positions);
find the indices in positions that contain the nextLowest and nextHighest positions relative to current_pos (or currentPos, if following Java naming conventions)
whichever position is closer, remove that position from positions and add it to return_array (If it was nextLowest, also decrement nextLowestIndex. If it was nextHighest, increment nextHighestIndex)
repeat step 3 until positions is empty
return return_array.
Of course, you'll also need to check for nextLowestIndex < 0 and nextHighestIndex >= positions.size() in step 3.
Note that you don't need the for loop inside of your while loop--but you would use that loop in step 2, before you enter the while loop.

Linked list of Linked List of Integers, Java.

I first ran into my problem trying to create a int[][] of very large size (7k by 30k) for a dictionary gap list postings program. But alas I run out of space trying to allocate the array. How might I create a 2-d array of integers?
What I want is a list of list in which each list in the list is a list of integers. Here is a sample of my code.
Code:
static final int numberOfTerms = 6782;
static final int numberOfLines = 30383;
byte[][] countMatrix = new byte[numberOfLines][numberOfTerms];
int[][] gapsMatrix = new int[numberOfLines][numberOfTerms]; // To big!!
This list of lists is going to be filled with integers that represent the gaps between two occurrences of the same word in a specific text. So in count matrix I hold a byte indicating whether a word is specified for a specified index. Then in the function I am creating right now I am going through the countMatrix and if I find a byte there, I take the current index minus the last found index and save that number in my 2D-array of integers which gives me the just the gaps between each of the same word in the text.
So how might I create a data structure I need to accomplish this?
I don't know whether this will work for you but you can try Sparse Matrix as option if you want to stick to Array. There are several other options.Map, List ,Weak reference Collections etc
To create an array you need to have enough memory to create it.
An int uses 4-bytes per values and an array uses at least N * M times that.
e.g. 4 * 30383 * 6782 is about 820 MB you need to have free to create this.
This is about $8 worth of memory so this should be a big problem unless you don't have this much or you set your maximum memory too low.
I would increase your maximum memory by 1 GB at least and it should work.
Alternatives include
use a smaller size e.g. char or short or byte which is 2-4 x smaller.
use off heap memory such as a memory mapped file. This doesn't use much heap but does use disk space which is usually cheaper.
increase your maximum memory size.
You simply have insufficient memory to do that.
http://www.javamex.com/tutorials/memory/array_memory_usage.shtml
Sorry I didn't make it clear but, it is unlikely that using another DS is going to change this.
So how might I create a data structure I need to accomplish this?
If is understand correctly, then you want to record gaps between same terms.
Let us say, you have array of terms you need to analyze, then:
String[] terms = ...;
Map<String, List<Integer>> map = new TreeMap<String, <Integer>>();
for (int i = 0; i < terms.length; i++) {
String term = terms[i];
List<Integer> positions = map.get(term);
if (gaps == null) {
positions = new ArrayList<Integer>();
}
positions.add(i);
map.set(term, positions);
}
Later you just look at the positions of each term and may calculate gaps between those. (You may integrate that gaps calculation into this code, but I leave it as exercise for you).

Removing items from a multi dimensional array in Java

I am trying to remove items from a 3 dimensional array.
I understand that one of the best ways to do this is to convert the array to a list and whilst iterating through the original array remove those items from the list then convert the list back to an array and return it.
I tried this but got an type mismatch when coming back to the array. I suspect I have not done something with the dimensions when converting from array to list.
Advice?
import java.util.List;
import java.util.Arrays;
public class RepatitionRemoval {
public float[][][] process(float[][][] data) {
//this method with step through all of the the strokes and remove
//points which occupy the same position. This should help with time
//warping regconition
//Change the array to a list
List points = Arrays.asList(data);
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
for (int k = 0; k < data[i][j].length-1; k++) {
//if the current coordinate is the same as the one next
//then remove it
if (data[i][j][k] == data[i][j][k+1]) {
points.remove(data[i][j][k]);
}
}
}
}
float[][][] returnData = points.toArray();
return returnData;
}
}
First the following method doesn't do what you think it does:
//Change the array to a list
List points = Arrays.asList(data);
Btw a good IDE will automatically transform that for you to:
List<float[][]> points = Arrays.asList(data);
So when you next do a:
points.remove(data[i][j][k])
what happens is that data[i][j][k] primitive gets auto-boxed to the Float wrapper class and then the remove methods checks to see if it contains any element equal to your wrapped Float. It checks the entire list and doesn't find any Float because... You've got a list of float[][]. So basically your code will never remove any element from the list.
But anyway, you should know that should you find an element that would match in the remove method, you'd get an UnsupportedOperationException because Arrays.asList simply wraps your array and your "list" is still backed the float[][][] array. And you cannot resize arrays.
Then, anyway you typically cannot compare floating point numbers using ==:
if (data[i][j][k] == data[i][j][k+1]) {
for it is ususally a terrible way to check if two floating numbers are equal. Floating numbers should be compared using an epsilon (and you should always keep track of the error propagation).
Regarding your last line, you can cast back to a float[][][] but it's pointless because that list of float[][] you created in the first is backed by your original float[][][] and cannot be modified (well, you may modify individual elements, but you cannot resize it).
List points = Arrays.asList(data);
It's creating list (points) of two dimensional arrays not floats which is what you need.
But the way you are trying to achieve your requirement is not possible and logically invalid.
It sounds like you have to turn your array into list of list of list. Which will logically makes sense when you turn it back into a three dimensional array after removing elements because keeps track of the dimensions.
Is it not because you are trying to push back into a three dimensional array.
You would need to cycle through your array populating the dimensions 2 and 3, 1 by 1.
The whole idea seems overly complex because you would need to know the dimensions after removing the values, I think you are probably best maintaining the 3d array and removing values from that.
Multi-dimensional arrays are arrays of arrays. data is an array of float[][] objects; data[i] is an array of float[] objects, and data[i][j] is an array of float objects. Instead of converting data to a list, you need to convert data[i][j] to a list.
Also, you can't directly remove an item from the list returned by Arrays.asList(), as the list is directly backed by the array, which cannot be resized. Instead, you have to populate an ArrayList, remove the elements, then convert back to an array and replace the original (see this question)
Finally, you're working with an array of primitives (floats), you'll need to convert from float[] to ArrayList<Float> and back again. This isn't trivial; this question may help

Java native array lengths

I have a 2D array of doubles in Java which is basically a table of values and I want to find out how many rows it has...
It is declared elsewhere (and allocated) like this:
double[][] table;
then passed to a function...
private void doSomething(double[][] table)
{
}
In my function I want to know the length of each dimension without having to pass them around as arguments. I can do this for the number of columns but don't know how to do it for the rows...
int cols = table[0].length;
int rows = ?;
How do I do that?
Can I just say...
int rows = table.length;
Why would that not give rows x cols?
In Java a 2D array is nothing more than an array of arrays.
This means that you can easily get the number of rows like this:
int rows = array.length;
This also means that each row in such an array can have a different amount of elements (i.e. each row can have a varying number of columns).
int columnsInFirstRow = array[0].length;
This will only give you the number of columns in the first row, but the second row could have more or less columns than that.
You could specify that your method only takes rectangular arrays and assume that each row has the same number of columns than the first one. But in that case I'd wrap the 2D-array in some Matrix class (that you might have to write).
This kind of array is called a Jagged Array.
Look at this example. They use .length there to get the row count, [].length to get the column count.
It's because the array consists of "row" pointers and these could lead anywhere, so you have to use .length for each column to get the sizes of these arrays, too.
I don't quite understand your question. You have to realize that in Java, multidimensional arrays are in fact arrays of arrays.
table.length will in fact give you the number of one-dimensional arrays contained in your two-dimensional array (assuming there are no null entries).
table[0].length will give you the size of the first one-dimensional entry. This could be different from the size of the others, and it could throw a NullPointerException (though neither is possible when it's allocated as new double[rows][cols]).
Well, first of all, why don't you just test if
int rows = table.length;
gives the desired result?
It does indeed give you the number of elements in the first dimension. Multidimensional arrays are in fact nothing special, as they are just arrays of arrays of arrays of ... In your case - a 2D array - it is organized like this (in pseudo-code):
double[][] foo = { double[] = {...}, double[] = {...}, ... }
So when accessing foo, it refers to the "outer" array, which has of course the length property, which contains the number of arrays it contains on the second level.
You can read the double[][] as "An array ([]) of double-arrrays (double[])".
No it won't. You can just use table.length
Alternatively, you could wrap your 2d array into a Matrix or Grid class of some sort. Internally, you could represent it as a 1d array and compute offsets for the row/col coordinates.

Categories

Resources