Implementation of an nxn matrix using a single record - java

To start off, I would like to know what exactly is a record in comparison to an array? From what I'm trying to understand from my textbook, "Gilles Dowek, Principles of Programming Languages", it's almost like an array but needs labels and values associated to these labels. The example given is:
labels: {latitude, longitude, altitude}
record: {latitude = 48.715, longitude = 2.208, altitude = 156}
What also confuses me is how one implements this 2-D matrix with a single record (which I assume is a single row vector like the example above).
I have only a year experience with programming in general so any sort of readings or sources with a descriptive answer would be greatly appreciated.

Array can only store values which you can access by indices, while record assigns one label to one value (you can access value using a key).
You can use a Map to store multiple records with different keys, example:
HashMap<String, Double> map = new HashMap<>();
map.put("latitude", 48.715);
map.put("longitude", 2.208);
map.put("altitude", 156.0);
Then, when you want to get a value:
double latitude = map.get("latitude");

To answer my own question, (with the resources provided in the comments to my question) a record is simply a Java object that has instance variables, but no instance methods. Using this knowledge, an array is very different from a record. The comparison would essentially be between an object class and an array.
Implementing a 2-D matrix, or more specifically, visually implementing the matrix so it looks like a square when printed is not the record's job, as this would require instance methods which isn't part of a record.
The solution to implementing an nxn matrix using a single record would simply be initializing "n times n" instance variables within a class. In general, the solution to making any record would be to initialize any required number of instance variables within a class.

Related

Java: how to get object instance from string?

Before we start, I should mention that I'm trying to do this in Android, though I believe it is not relevant to what I am trying to resolve in this question specifically.
I should also mention that I have seen similar things asked already, though they did not exactly help me in what I am trying to do. While some of them have helped me get a general idea of how it should be done, in the end, I've been left helpless by the too-specific problems the other users had.
I believe it would also be useful to clarify that I am relatively new to programming in Java, with very little experience or knowledge of complex data structures.
What I am trying to do is as follows:
Say I have a class named WordThing, which contains two strings, called name and color, and an int called picture (which is used for retrieving the ID for an imagebutton). I also have a separate char called uno, whose value is a. There is an instance of WordThing called a, with its values properly assigned. I want to ask if it'd be possible to call one of the values of WordThing a using the value of uno, like this:
getValue(uno).picture
While I am aware that the above example is, in many ways, incorrect, nevertheless am I asking whether such a thing would be possible.
To clarify, in reality there are more chars than just uno, namely four, all with different letters, who are subject to randomization. My intention is to use these random letters to call upon four distinct WordThing instances, whose values will then be used in altering some elements of a given View, like this:
upperleftButton.setImageResource(getValue(uno).picture);
Any kind of help is appreciated.
What you are looking for is a Map, also know as an Associative Array or dictionary. Maps are used to store items in key/value pairs, where the key can be used to look up the value within a map. In java (and android) you can use a map like this.
Map<String, WordThing> wordThingMap = new HashMap<String, WordThing>();
// Add some items to the map
wordThingMap.put("a", new WordThing());
wordThingMap.put("b", new WordThing());
// Do some other stuff
someSuperSpecialMethod();
// Retrieve values from the map
WordThing a = map.get("a");
As a side note, you should probably think about re-naming some of your variables. WordThing isn't really that descriptive, and variable names like "a" and "b" will become very difficult to work with very quickly. For some tips on naming variables, see this question for a start.

Idea for a data structure to store 2D data?

I have a large 2D grid, x-by-y. The user of the application will add data about specific points on this grid. Unfortunately, the grid is far too big to be implemented as a large x-by-y array because the system on which this is running does not have enough memory.
What is a good way to implement this so that only the points that have data added to them are stored in memory?
My first idea was to create a BST of the data points. A hash function such as "(long)x<<32 + y" would be used to compare the nodes.
I then concluded that this could lose efficiency if not well balanced so I came up with the idea of having a BST of comparable BSTs of points. The outer BST would compare the inner BSTs based on their x values. The inner BSTs would compare the points by their y values (and they would all have the same x). So when the programmer wants to see if there is a point at (5,6), they would query the outer BST for 5. If an inner BST exists at that point then the programmer would query the inner BST for 6. The result would be returned.
Can you think of any better way of implementing this?
Edit: In regards to HashMaps: Most HashMaps require having an array for the lookup. One would say "data[hash(Point)] = Point();" to set a point and then find the Point by hashing it to find the index. The problem, however, is that the array would have to be the size of the range of the hash function. If this range is less than the total number of data points that are added then they would either have no room or have to be added to an overflow. Because I don't know the number of points that will be added, I would have to make an assumption that this number would be less than a certain amount and then set the array to that size. Again, this instantiates a very large array (although smaller than originally if the assumption is that there will be less data points than x*y). I would like the structure to scale linearly with the amount of data and not take up a large amount when empty.
It looks like what I want is a SparseArray, as some have mentioned. Are they implemented similarly to having a BST inside of a BST?
Edit2: Map<> is an interface. If I were to use a Map then it looks like TreeMap<> would be the best bet. So I would end up with TreeMap< TreeMap< Point> >, similar to the Map< Map< Point> > suggestions that people have made, which is basically a BST inside of a BST. Thanks for the info, though, because I didn't know that the TreeMap<> was basically the Java SDK of a BST.
Edit3: For those whom it may concern, the selected answer is the best method. Firstly, one must create a Point class that contains (x,y) and implements comparable. The Point could potentially be compared by something like (((long)x)<<32)+y). Then one would TreeMap each point to the data. Searching this is efficient because it is in a balanced tree so log(n) cost. The user can also query all of this data, or iterate through it, by using the TreeMap.entrySet() function, which returns a set of Points along with the data.
In conclusion, this allows for the space-efficient and search-efficient implementation of a sparse array, or in my case, a 2D array, that can also be iterated through efficiently.
Either a Quadtree, a k-d-tree or an R-tree.
Store index to large point array into one of the spatial structures.
Such spatial structures are advantageous if the data is not equally distributed, like geographic data that concentrates in cities, and have no point in the sea.
Think if you can forget the regular grid, and stay with the quad tree.
(Think, why do you need a regular grid? A regular grid is usually only a simplification)
Under no circumstances use Objects to store a Point.
Such an Object needs 20 bytes only for the fact that it is an object! A bad idea for a huge data set.
An int x[], and int[] y, or an int[]xy array is ideal related to memory usage.
Consider reading
Hanan Samet's "Foundations of Multidimensional Data Structures"
(at least the Introduction).
You could use a Map<Pair, Whatever> to store your data (you have to write the Pair class). If you need to iterate the data in some specific order, make Pair Comparable, and use NavigableMap
One approach could be Map<Integer, Map<Integer, Data>>. The key on the outer map is the row value, and the key in the inner map is the column value. The value associated with that inner map (of type Data in this case) corresponds to the data at (row, column). Of course, this won't help if you're looking at trying to do matrix operations or such. For that you'll need sparse matrices.
Another approach is to represent the row and column as a Coordinate class or a Point class. You will need to implement equals and hashCode (should be very trivial). Then, you can represent your data as Map<Point, Data> or Map<Coordinate, Data>.
You could have a list of lists of an object, and that object can encode it's horizontal and vertical position.
class MyClass
{
int x;
int y;
...
}
Maybe I'm being too simplistic here, but I think you can just use a regular HashMap. It would contain custom Point objects as keys:
class Point {
int x;
int y;
}
Then you override the equals method (and thus the hashCode method) to be based on x and y. That way you only store points that have some data.
I think you are on the right track to do this in a memory efficient way - it can be implemented fairly easily by using a map of maps, wrapped in a class to give a clean interface for lookups.
An alternative (and more memory efficient) approach would be to use a single map, where the key was a tuple (x,y). However, this would be less convenient if you need to make queries like 'give me all values where x == some value'.
You might want to look at FlexCompColMatrix, CompColMatrix and other sparse matrices implementations from the Matrix toolkit project.
The performance will really depends on the write/read ratio and on the density of the matrix, but if you're using a matrix package it will be easier to experiment by switching the implementation
My suggestion to you is use Commons Math: The Apache Commons Mathematics Library. Because it will save your day, by leveraging the math force that your application require.

Comparing player strengths and weaknesses

I'm developing a game which will have the same sort of system as pokemon does, i.e. every player will have a 'type'(fire,water,grass etc.). When players fight, I need to determine what factr to multiply attacks by, to create strengths and weaknesses. So far I'm using a switch in each 'type' class which takes another 'type' class as input and returns the multiplication factor. With only three of these 'type' classes, I'm writing a lot of ode and I can foresee it getting out of hand in the future when I want to add more.
So my question is, how can I implement a DRY solution for determining strengths and weaknesses of each type? I've attached a table of the pokemon types as a reference for what it is I am trying to do.
How about enumerating the types, and building a 2D matrix that looks just like the one you posted. Whenever you need the "factor" for a battle, look the factor up using the attacker and defender as indices in the 2D array. Lookups would be fast and the code would be pretty clean.
Sample use cases would look something like this:
factor = factorTable[FIRE][WATER]; // would set factor to 0.5
factor = factorTable[WATER][FIRE]; // would set factor to 2.0
As Noctua suggested, it might be a good idea to have the actual data in a config file. That way you can easily change it without recompiling. If you go for that option, you'd need some kind of parsing function to create the matrix at the beginning of the program.
An even better step to take next would be to encapsulate the table behavior and type representation in classes. The underlying implementation could still be the same (or change, that's the point) but you wouldn't expose the table nor the enumerations directly.
factor = StrengthFactors(Player1.Type(), Player2.Type()); // or similar
I think you should use a single array of strings to store the different types. Then you use a 2D Matrix to store multipliers. The idea is to use the id of this array of string to know where is the multiplier. You will have a O(n) complexity to find the multiplier you want.

Separate chaining in Java

Our class is learning about hash tables, and one of my study questions involves me creating a dictionary using a hash table with separate chaining. However, the catch is that we are not allowed to use Java's provided methods for creating hash tables. Rather, our lecture notes mention that separate chaining involves each cell in an array pointing to a linked list of entries.
Thus, my understanding is that I should create an array of size n (where n is prime), and insert an empty linked list into each position in the array. Then, I use my hash function to hash strings and insert them into the corresponding linked list in the proper array position. I created my hash function, and so far my Dictionary constructor takes in a size and creates an array of that size (actually, of size 4999, both prime and large as discussed in class). Am I on the right track here? Should I now insert a new linked list into each position and then work on insert/remove methods?
What you have sounds good so far.
Bear in mind that an array of object references has each cell null by default, and you can write your insert and remove functions to work with that. If you choose to create a linked list object that contains no data (sometimes called a sentinel node) it may be advantageous to create a single immutable (read-only) instance to put in every empty slot, rather than create 4,999 separate instances with new (where most don't hold any data).
It sounds like you are on the right track.
Some extra pointers:
It's not worth creating a LinkedList in each bucket until it is actually used. So you can leave the buckets as null until they are added to. Just remember to write your accessor functions to take account of this.
It's not always efficient to create a large array immediately. It can be better to start with a small array, keep track of the capacity used, and enlarge the array when necessary (which involves re-bucketing the values into the new array)
It's a good idea to make your class implement the whole of the Map<K,V> interface - just to get some practice implementing the other standard Java collection methods.

Java: How to think about Modelling a Markov Chain?

I have a program that I am trying to make a Markov text generator for. I plan on splitting some text up at a set interval and then storing that into a class. The problem that I don't know how to solve is how to handle naming the instances of the class I am going to make. I was planning on generating the instances in a for loop. The user will pass the method some amount of text (the length of which is not known beforehand). Pseudo-code below:
create vector for sets and tail letter;
for (int c = 0; c < text.length; c++) {
Check to make sure overflow doesnt happen;
Create instance of set named c;
store set and tailLetter into vector;
}
public class set {
String characters;
char tailLetter;
}
I'm sorry if that's not clear enough. I'm teaching myself Java and this is my first post here.
If you are learning Java, I'd suggest that you first focus on how to model the problem with Java's classes and methods.
A Markov Chain is a model or statistical elaboration of the seed text, right? Using it to model a text, it normally describes how often each word is followed by each other word. (normally you'd split the text on word boundaries). That feels like it needs a class; it might be called MarkovChain.
Within the MarkovChain class, you need something to hold each word that occurs in the text, and maps that word to the other words in the text, and the count of frequency of those other words.
Suppose the word is 'and'. In the text, 'and' is followed by "the" four times, and "then" 3 times. So you'd need some data structure to hold something like this:
and -->
the (4)
then (3)
One way to do this is to use an ArrayList to hold all words, then a Map<T1,T2> that holds the relationship between words and the frequency of following words.
In this case T1 is probably a string, and the T2 is probably an ArrayList of pairs - a string and the (integer) count for that string.
But wait, now you don't need the base ArrayList<> to store the words, because they are just the keys in the map.
...and so on. The next step would be to figure out how to populate that data structure. That's probably an internal (private) method that gets called when a caller instantiates the MarkovChain class with a seed text.
Probably you also want that MarkovChain class to expose another method, a public one, that callers invoke when they want to generate some random sequence from the chain, relying on probabilities based on the frequency counts.
...
This is just one way to think about the modelling of the problem.
Anyway I would focus on that modelling/design exercise, before writing code.
Can't you use a Map<String, Set> where the key is the generated name?
You can use an ArrayList to manage the instances. I like the Map idea better so you can dynamically set the names instead of trying to access instances by an index number.
I don't see the point of the names:
If they are just so that 'set' objects will have some distinct String for debugging, the default toString() implementation will give you that.
If you specifically need to do lookup of these 'set' objects, then a numeric identifier or a sequence number will work better.
If you explained the purpose of the names, and how you intend to use them, maybe we could give you better advice.

Categories

Resources