Earlier last week I was in an android/Java class, and our lecturer likes to throw little challenges at us every now and then, just as fun little programs for us to think about.
The topic I'm studying is OOP and OOD in c# and Java environments, so this really doesn't have any huge leverage on my actual final project, and I'd like to stress this was an optional task set for fun.
The Task was asking for the programmer to:
Create a program that could hold an "unlimited" array of integers (based on how many the user required) and find the max value in the array.
The issue wasn't the max method (easy), or the variables in the array (basic), but the array itself. we weren't allowed to use linked lists, it had to be an "Unlimited" 1D array that could take user input.
I've been playing around with the array for a while now, was going to make a circular array at first but that still doesn't solve many of the issues, and I can't really work out how to solve the problem in a way that this could be ported over and used in c#
any ideas as to how this could be achieved?
If you can't use only LinkedList you can use any other implementation of java.util.List.
If you can't use at all java.util.List you can use an array with enough values as you need and use a pointer to the last value.
Something like this
public class MyArray {
private int[] myArray = new int[10000];
private int index = -1;
public void add(int obj) {
index++;
myArray[index] = obj;
}
public Integer removeLast() {
if (index >= 0) {
return myArray[index--];
}
return null;
}
public Integer get(int i) {
if (i >= 0 && i < index) {
return myArray[i];
}
return null;
}
}
Note. This is very similar to the internal representation of ArrayList. Take a tour of source of ArrayList to know more, the biggest difference is that this implentation is blocked to a maximum of 10000 ints, instead the ArrayList can grows if necessary, but I think that the grows implementation is outside the scope of your exercise.
Related
This question already has answers here:
Java N-Dimensional Arrays
(3 answers)
Closed 5 years ago.
Is it possible to have an n dimensional array in Java without having to explicitly specify the number of dimensions?
I.e. if I wanted a 2D array of ints I'd do:
int[][] myArray = new int[a][b];
For the above I've had to specify that the myArray variable is of type int[][]. What I'm asking is whether there's the possibility to declare a variable that is an array of n dimensions without having to know n in advance.
I.e. If I had the variable test, test could be of type int[][] or int[][][] or int[][][][][][][][][][][] - you get the idea. I just want to define test without having to define the number of dimensions.
I'm sure the above kind of breaks the type system in Java so I'm open to any ideas as I think I'm approaching this the wrong way.
To give you a bit of context I've developed an algorithm to find an integer in a 2D array of integers that are sorted by both row and column in ascending order. I've noticed that it will work with any dimension array and would thus like to make it more generic. However, I don't fancy defining a function for every possible dimension of array to be passed as a parameter since the dimensions could (unlikely as it is) be anywhere from 1D to infinityD - hence the question.
This is also just for my own curiosity as to whether this can be done for any dimension array. I don't know whether this potentially can't be done using Java's built in facilities and I'd be better building my own class system to support multi-dimension arrays in this situation.
You can not define an array as unknown-dimensional. But you can make your own class like NDimensionalArray, that would wrap array of another NDimensionalArray instances, and implement getter like getValue(int indexes...), and dimension()
class NDimensionalArray {
NDimensionalArray[] arrays;
int value;
int getValue(int... indexes) {
if (indexes.length == 0) return value;
return arrays[indexes[0]].getValue(indexes[1],indexes[2],...,indexes[n-1]);
}
void setValue(int value, int... indexes) {
// implement simillary to getValue
}
int getDimension() {
if (arrays == 0 || arrays.length == 0) return 0;
return arrays[0].getDimension() + 1;
}
}
that's not a working class, but only an idea, creating the entire structure is on your own. You would need to implement all the index and null checks.
An interview question was to write this method to remove duplicate element in an array.
public static Array removeDuplicates(Array a) {
...
return type is java.lang.reflect.Array and parameter is also java.lang.reflect.Array type.
How would this method be called for any array?
Also not sure about my implementation:
public static Array removeDuplicates(Array a)
{
int end=Array.getLength(a)-1;
for(int i=0;i<=end-1;i++)
{
for(int j=i+1;j<=end;j++)
{
if(Array.get(a, i)==Array.get(a, j))
{
Array.set(a, j, Array.get(a, end));
end--;
j--;
}
}
}
Array b=(Array) Array.newInstance(a.getClass(), end+1);
for(int i=0;i<=end;i++)
Array.set(a, i, Array.get(a, i));
return b;
}
You may want to consider using a different data structure such as a hashmap to detect the duplicate (O(1)) instead of looping with nested for loops (O(n^2)). It should give you much better time complexity.
There are various problem with this code. Starting here:
if(Array.get(a, i)==Array.get(a, j))
Keep in mind that those get() calls return Object. So, when you pass in an array of strings, comparing with == simply will most likely result in wrong results (because many objects that are in fact equal still have different references --- so your check returns false all the time!)
So, the first thing to change: use equals() instead of == !
The other problem is:
end--;
Seriously: you never ever change the variable that controls your for loop.
Instead: have another counter, like
int numberOfOutgoingItems = end;
and then decrease that counter!
For your final question - check the javadoc; for example for get(). That reads get(Object array, int index)
So you should be able to do something like:
int a[] = ...;
Object oneValue = Array.get(a, 0);
for example.
Disclaimer. I have to admit: I don't know if the Array implementation is smart enough to automatically turn the elements of an int[] into an Integer object.
It could well be that you have to write code first to detect the exact type of array (if it is an array of int for example); to instead call getInt() instead of getObject().
Beyond that, some further reading how to use reflection/Array can be found here
I know how to find minimum and maximum in an array. If a method lets say was called fMax():
public static double fMax(Object[] stuff)
The parameter is an array object how would I go about finding the max of this array? I cannot just do. Okay so how would I do this if I want the method to return a double and if the memory hasnt been allocated for the parameter named stuff then it will return the value NEGATIVE_INFINITY in the Double class, otherwise the return value will be the maximum value from the elements in the stuff array
Object max = stuff[0];
for (int i = 0; i < stuff.length; i++) {
if (data[i] > max) {
max = stuff[i];
}
}
To find the maximum of something, either
a) that something needs to implement the Comparable interface
b) you need to have some sort of explicit criteria for determining what maximum is, so you can put that in an instance of Comparator
Object itself isn't going to have anything useful for sorting. If you subclass object, you could sort based on the components of that object.
public class Example implements Comparable
{
int sortableValue = 0;
public Example (int value)
{
this.sortableValue = value;
}
public int compareTo(Example other)
{
return Integer.compare(this.sortableValue, other.sortableValue);
}
}
That's an object definition that has a natural sorting order. Java can look at that with any of the built in sorting algorithms and know the order they belong in.
If you don't provide java with a means of determining how an object has greater or lesser relative value compared to another object of the same type, it won't figure it out on its own.
Object is not comparable, you need a definite type if you want to compare values, sort or find something.
Streams are the most powerful, versatile tools for the job, this here will solve your problem if your want to find min/max of an array of Double :
Double[] arr = {1d, 2d, 3d, 4d};
Double min = Arrays.asList(arr).stream().parallel().min(Double::compare).get();
Double max = Arrays.asList(arr).stream().parallel().max(Double::compare).get();
String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);
Now, just compare the new primitive array that we made from the object. If you don't need the object after this, and you aren't planning on returning an array object, then make your original array null, to take up less memory.
Check this:
How to compare two object arrays in Java?
As a sample, I am developing a simple MySortedSet in java which implements SortedSet interface. It is backed up with a simple array which is E[] array.
I have several questions regarding that:
This is the class: (I am not writing entire code, instead of related parts)
public class MySortedSet<E> implements SortedSet<E>, Iterator<E> {
private E[] array;
private Comparator<? super E> _comparator;
private int size = 0;
private int capacity;
#SuppressWarnings("unchecked")
public MySortedSet() {
this.capacity = 10;
this.array = (E[]) new Object[this.capacity];
// this.array = Array.newInstance(Class<E> var,int size);
// We have to get Class<E> from outside caller.
}
}
Since it accepts all sort of type from primitive to reference types etc. I am not really sure when removing an item, assigning null is a good way in place of the removed item. Since Java initializes primitive types with 0. So null only works for reference types.
Below is probably very bad design:
#Override
public boolean remove(Object o) {
int indexOfElement = this.find(o);
boolean removed = false;
if (indexOfElement != -1) {
this.array[indexOfElement] = null;
removed = true;
}
return removed;
}
Can someone tell me what the best way is to remove an element from an array?
Edit:
Honestly what I am thinking to remove an element from an simple array is like copy the entire array without the removed item into a whole new array but I am not sure how efficient it would be in terms of performance and etc.
It kinda depends on the context of how you want to use your array. For example, if you are going to be iterating over the array and using the contents of it for standard methods like Arrays.sort(), they might generate NullPointerExceptions if you have null values in your array.
If you really want to remove items from an array in a safe way, I'd suggest changing your array to an ArrayList like this...
ArrayList<Object> list = new ArrayList<Object>();
list.add(object);
list.remove(object);
As this will actually remove the item from the list completely - no nulls or anything will remain, and performing methods like length() will return a real value.
For instances when I have used an array, I set the value to null, and ensure that all iterations over the array check that value != null before I try to query it. After setting the nulls for the removed items, I usually loop over the array and manually sort all the nulls to the end of the array, and then do System.arraycopy() to resize the array. This will leave you with a new array of the correct size, with all items in it except for the removed ones. However, I suggest this only if you really must use an array, as it is slower and introduces much greater potential for errors and NullPointerExceptions.
Alternatively, if you're not worried about sort-order, you can simple move the last item in the array over the top of the item you want to remove, and keep a count of the real array size. For example...
Object[] array = new Object[20];
int realSize = 15; // real number of items in the array
public void remove(int arrayIndex){
array[arrayIndex] = array[realSize-1];
realSize--;
}
This method removes an item in the array by 'replacing' it with the item in the last position of the array - its very quick and pretty to implement, if you don't care about sort order.
Suppose I read a stream of integers. The same integer may appear more than once in the stream. Now I would like to keep a cache of N integers that appeared most frequently. The cache is sorted by the frequency of the stream elements.
How would you implement it in Java?
You want to use a binary indexed tree, the code in the link is for C++ and should be fairly straightforward to convert into Java (AFAICT the code would be the same):
Paper Peter Fenwick
Implementation in C++
Use a Guava Multiset and sort it by frequency
public class MyData implements Comparable<MyData>{
public int frequency = 0;
public Integer data;
#Override
public int compareTo(MyData that) {
return this.frequency - that.frequency;
}
}
Have it stored in a PriorityQueue
Create an object model for the int, inside create a Count property. Create a SortedVector collection extending the Vector collection. Each time an integer occurs, add it to the vector if it doesn't exist. Else, find it, update the count property += 1, then call Collections.sort(this) within your Vector.
Do you know the range of the numbers? If so, it might make sense to use an array. For example, if I knew that the range of the numbers was between 0 and 10, I would make an array of size 10. Each element in this array would count the number of times I've seen a given number. Then, you just have to remember the most frequently seen number.
e.g.
array[10];
freq_index = -1;
freq_count = -1;
readVal(int n){
array[n]+=1;
if array[n] > freq_count
freq_index = n;
freq_count = array[n];
}
Of course, this approach is bad if the distribution of numbers is sparse.
I'd try a priority queue.