Problems detecting object duplication in array during pruning/migration - java

This following of my program should recieve an array of objects and sort them based on the size of their privilege variable. The "arrayFromBefore" variable is filled with objects of type MyClass. It just basically creates a new MyClass object and returns it with the same attributes of the object.
The problem is, in certain cases, there seems to be several occurences of the same MyClass object in the priority array. These duplications are also not always the same multiple (e.g. one object occurs 3 times in a row, another 5 times in a row, another twice, etc...)
MyClass[] priorityArray = new MyClass[arrayFromBefore.length];
for (int i = 0; i < priorityArray.length; i++) {
int maxIndex = 0;
int maxPrivilege = arrayFromBefore[i].returnPrivilege();
for (int j = 1; j < arrayFromBefore.length; j++) {
int currentPrivilege = arrayFromBefore[j].returnPrivilege();
if (currentPrivilege > maxPrivilege) {
maxPrivilege = currentPrivilege;
maxIndex = j;
}
}
MyClass mostPrivilaged = arrayFromBefore[maxIndex];
priorityArray[i] = mostPrivileged;
arrayFromBefore[maxIndex].setPriority(-900000000);
}

The problem is in your inner for-loop where for each i, j starts from same value 1. j should start exactly from next to i, so that same object cannot be overrided.
MyClass[] priorityArray = new MyClass[arrayFromBefore.length];
for (int i=0; i<priorityArray.length - 1; i++) {
int maxIndex = 0;
int maxPrivilege = arrayFromBefore[i].returnPrivilege();
for (int j=1+i; j<arrayFromBefore.legnth; j++) {
int currentPrivilege = arrayFromBefore[j].returnPrivilege();
if (currentPrivilege > maxPrivilege) {
maxPrivilege = currentPrivilege;
maxIndex = j;
}
}
// priorityArray[i] = mostPrivileged; this line can be removed as it isn't required because you are getting sorted arrayFromBefore.
myClass mostPrivilaged = arrayFromBefore[maxIndex]; // Swapping of
arrayFromBefore[maxIndex] = arrayFromBefore[i]; // largest priority object
arrayFromBefore[i] = mostPrivilaged; // with its required position in sorted array.
}
After this you will get arrayFromBefore as shorted in descending order of priority.

Related

Is there a way to return an array into another array?

Is there a way to return an array into another array.
I have a multidimensional array which I am using a method combineArrays(Comparable[][] x) to combine into another 1D array.
Normally I'd just create the 1D array in a higher scope, but I've painfully learned that Comparable arrays need a dimension when initialized and the combineArrays() is responsible for determining the size of the mutliarray.
Please be kind, I'm not done yet.
The purpose of the program itself is to accept an array of objects and find a common list of object which exist in each row. The trick is the findCommonElements() must do so in either O(nlogn) or O(n) time
/*
* combs through the original array to find the shortest row which must hold
* the least # of common objects
*/
public static int findSmallestRow(Comparable[][] queries) {
int array_length = 0;
int indexOfMaster = 0;
array_length = queries[0].length; // sets variable to initial arrays row
// length
for (int i = 0; i < queries.length; i++) { // iterates through each row
// comparing size of each
// row
if (queries[i].length <= array_length) { // ensures the 1st row is,
// at minimum, the
// master array
array_length = queries[i].length;
indexOfMaster = i;
}
}
return indexOfMaster;
}
public static void findCommonElements(Comparable[][] queries){
Comparable[] new_query = combineArray(queries);
for(int a = 0; a<new_query.length; a++){
System.out.println(new_query[a]);
}
//Arrays.sort(new_query);
int query_length = new_query.length;
int masterIndex = findSmallestRow(queries);
Comparable extracted[] = new Comparable[queries[masterIndex].length];
System.arraycopy(queries[masterIndex], 0, extracted, 0,
extracted.length);
Comparable[] intermediate_query = new Comparable[masterIndex];
int nonquery_length = extracted.length;
int counter = 0;
int counter2 = 0;
int query_index = 0;
int nonquery_index = 0;
int i =0;
int j = 0;
while(i < nonquery_length && j < query_length){
if(extracted[nonquery_index].compareTo(new_query[query_index])>0){
query_index++;
}
if(extracted[nonquery_index].compareTo(new_query[query_index])<0){
nonquery_index++;
}
if(extracted[nonquery_index].compareTo(new_query[query_index])==0){
counter++;
if(counter == queries.length){
intermediate_query[counter2] = extracted[nonquery_index];
counter2++;
}
}
}
Comparable common_list[] = new Comparable[counter2];
for(int k = 0; k<counter2; k++){
common_list[k] = intermediate_query[k];
System.out.println(common_list[i]);
}
}
//gets size of query array, even if not uniform
public static Comparable[] combineArray(Comparable[][]queries){
int length = queries.length;
ArrayList rows = new ArrayList();
for(int i = 0; i< length; i++){
for(int k = 0; k<queries[i].length; k++){
rows.add("");
}
}
int query_size = rows.size();
Comparable[] new_query = new Comparable[query_size];
int new_query_counter = 0;
for(int i = 0; i< length; i++){
for(int k = 0; k<queries[i].length; k++){
new_query[new_query_counter] = queries[i][k];
}
}
return new_query;
}
This computes the set intersection of all the rows of the array.
public static Set<Comparable<?>> common( Comparable<?>[][] a ){
Set<Comparable<?>> inter = new HashSet<>( Arrays.asList( a[0] ) );
for( int i = 1; i < a.length; ++i ){
inter.retainAll( new HashSet<>( Arrays.asList( a[i] ) ) );
}
return inter;
}
It is possible that the original idea is to retain repeated elements, i.e., if there are two 'x' in each row, the result should also contain two 'x'. The short solution given hear uses sets, which do not store repetition of equal elements. - But here is a library where you find HashMultiSet, and the code will remain basically the same except for the types of inter and result.
import org.apache.commons.collections4.multiset.HashMultiSet;

How to create multiple arrays with a loop?

I am having trouble creating multiple arrays with a loop in Java. What I am trying to do is create a set of arrays, so that each following array has 3 more numbers in it, and all numbers are consecutive. Just to clarify, what I need to get is a set of, let's say 30 arrays, so that it looks like this:
[1,2,3]
[4,5,6,7,8,9]
[10,11,12,13,14,15,16,17,18]
[19,20,21,22,23,24,25,26,27,28,29,30]
....
And so on. Any help much appreciated!
Do you need something like this?
int size = 3;
int values = 1;
for (int i = 0; i < size; i = i + 3) {
int[] arr = new int[size];
for (int j = 0; j < size; j++) {
arr[j] = values;
values++;
}
size += 3;
int count = 0;
for (int j : arr) { // for display
++count;
System.out.print(j);
if (count != arr.length) {
System.out.print(" , ");
}
}
System.out.println();
if (i > 6) { // to put an end to endless creation of arrays
break;
}
}
To do this, you need to keep track of three things: (1) how many arrays you've already created (so you can stop at 30); (2) what length of array you're on (so you can create the next array with the right length); and (3) what integer-value you're up to (so you can populate the next array with the right values).
Here's one way:
private Set<int[]> createArrays() {
final Set<int[]> arrays = new HashSet<int[]>();
int arrayLength = 3;
int value = 1;
for (int arrayNum = 0; arrayNum < 30; ++arrayNum) {
final int[] array = new int[arrayLength];
for (int j = 0; j < array.length; ++j) {
array[j] = value;
++value;
}
arrays.add(array);
arrayLength += 3;
}
return arrays;
}
I don't think that you can "create" arrays in java, but you can create an array of arrays, so the output will look something like this:
[[1,2,3],[4,5,6,7,8,9],[10,11,12,13...]...]
you can do this very succinctly by using two for-loops
Quick Answer
==================
int arrays[][] = new int[30][];
for (int j = 0; j < 30; j++){
for (int i = 0; i < (j++)*3; i++){
arrays[j][i] = (i++)+j*3;
}
}
the first for-loop tells us, via the variable j, which array we are currently adding items to. The second for-loop tells us which item we are adding, and adds the correct item to that position.
All you have to remember is that j++ means j + 1.
Now, the super long-winded explanation:
I've used some simple (well, I say simple, but...) maths to generate the correct item each time:
[1,2,3]
here, j is 0, and we see that the first item is one. At the first item, i is also equal to 0, so we can say that, here, each item is equal to i + 1, or i++.
However, in the next array,
[4,5,6,7,8,9]
each item is not equal to i++, because i has been reset to 0. However, j=1, so we can use this to our advantage to generate the correct elements this time: each item is equal to (i++)+j*3.
Does this rule hold up?
Well, we can look at the next one, where j is 2:
[10,11,12,13,14...]
i = 0, j = 2 and 10 = (0+1)+2*3, so it still follows our rule.
That's how I was able to generate each element correctly.
tl;dr
int arrays[][] = new int[30][];
for (int j = 0; j < 30; j++){
for (int i = 0; i < (j++)*3; i++){
arrays[j][i] = (i++)+j*3;
}
}
It works.
You have to use a double for loop. First loop will iterate for your arrays, second for their contents.
Sor the first for has to iterate from 0 to 30. The second one is a little less easy to write. You have to remember where you last stop and how many items you had in the last one. At the end, it will look like that:
int base = 1;
int size = 3;
int arrays[][] = new int[30][];
for(int i = 0; i < 30; i++) {
arrays[i] = new int[size];
for(int j = 0; j < size; j++) {
arrays[i][j] = base;
base++;
}
size += 3;
}

MultiDimensional ArrayList in kmeans clustering algorithm

I am trying to implement kmeans algorithm for a certain Music Recommendation System in Java.
I have generated 2 arrays,playsFinal[](the total play-count of an artist by all users in the dataset) and artFinal[] (the unique artists in the entire dataset) . The playcount of every artFinal[i] is playsFinal[i]. For k,I have chosen kclusters=Math.sqrt(playsFinal.length)/2.
I have an array clusters[kclusters][playsFinal.length] and the first position clusters[i][0] for every 0<i<kclusters is filled with a certain value,which is basically the initial mean as in kmeans algorithm.
int j = 0;
for (int i = 0; i < n && j < kclusters; i += kclusters) {
clusters[j][0] = weighty[j];//initial means
System.out.println(clusters[j][0]);
j++;
}
Here,weight[] is a certain score given to every artist.
Now,in the following function I am returning the index,ie,which cluster the plays[i] should be added to.
public static int smallestdistance(double a, double[][] clusters) {
a = (double) a;
double smallest = 0;
double d[] = new double[kclusters];
for (int i = 0; i < kclusters; i++) {
d[i] = a - clusters[i][0];
}
int index = -1;
double d1 = Double.POSITIVE_INFINITY;
for (int i = 0; i < d.length; i++)
if (d[i] < d1) {
d1 = d[i];
index = i;
}
return index;
}
If not obvious,I am finding the minimum distance between playsFinal[i] and the initial element in every clusters[j][0] and the one that is the smallest,I am returning its index (kfound). Now at the index of the clusters[kfound][] I want to add the playsFinal[i] but here is where I am stuck. I can't use .add() function like in ArrayList. And I guess using an ArrayList would be way better. I have gone through most of the articles on ArrayList but found nothing that could help me. How can I implement this using a multidimensional ArrayList?
Thanks in advance.
My code is put together as follows:
int j = 0;
for (int i = 0; i < n && j < kclusters; i += kclusters) {
clusters[j][0] = weighty[j];//initial means
System.out.println(clusters[j][0]);
j++;
}
double[] weighty = new double[artFinal.length];
for (int i = 0; i < artFinal.length; i++) {
weighty[i] = (playsFinal[i] * 10000 / playsFinal.length);
}
n = playsFinal.length;
kclusters = (int) (Math.sqrt(n) / 2);
double[][] clusters = new double[kclusters][playsFinal.length];
int j = 0;
for (int i = 0; i < n && j < kclusters; i += kclusters) {
clusters[j][0] = weighty[j];//initial means
System.out.println(clusters[j][0]);
j++;
}
int kfound;
for (int i = 0; i < playsFinal.length; i++) {
kfound = smallestdistance(playsFinal[i], clusters);
//HERE IS WHERE I AM STUCK. I want to add playsFinal[i] to the corresponding clusters[kfound][]
}
}
public static int smallestdistance(double a, double[][] clusters) {
a = (double) a;
double smallest = 0;
double d[] = new double[kclusters];
for (int i = 0; i < kclusters; i++) {
d[i] = a - clusters[i][0];
}
int index = -1;
double d1 = Double.POSITIVE_INFINITY;
for (int i = 0; i < d.length; i++)
if (d[i] < d1) {
d1 = d[i];
index = i;
}
return index;
}
Java's "multidimensional arrays" are really just arrays whose elements are themselves (references to) arrays. The ArrayList equivalent is to create a list containing other lists:
List<List<Foo>> l = new ArrayList<>(); //create outer ArrayList
for (int i = 0; i < 10; i++) //create 10 inner ArrayLists
l.add(new ArrayList<Foo>());
l.get(5).add(foo1); //add an element to the sixth inner list
l.get(5).set(0, foo2); //set that element to a different value
Unlike arrays, the lists are created empty (as any list), rather than with some specified number of slots; if you want to treat them as drop-in replacements for multidimensional arrays, you have to fill them in manually. This implies your inner lists can have different lengths. (You can actually get "ragged" multidimensional arrays by only specifying the outer dimension (int[][] x = new int[10][];), then manually initializing the slots (for (int i = 0; i < x.length; ++i) x[i] = new int[i]; for a "triangular" array), but the special syntax for multidimensional array creation strongly predisposes most programmers to thinking in terms of "rectangular" arrays only.)

Why am I receiving an ArrayIndexOutofBoundsException?

In my JAVA code, I am given a data and I have to find the mode. Everything successfully compiled, and every method works. However, when I try to access the mode, I get an java.lang.ArrayIndexOutOfBoundsException: 987 in my terminal window. The highlighted portion is in the following method, which is one of my max methods. The data array, by the way, is just int [] data.
public int maxOfData(int [] oa)
{
int max = oa[0];
for (int i = 1; i < size; i++)
{
if (oa[i] > max)
max = oa[i];
}
return max;
}
The exception is on the line if(oa[i] > max)
And the mode code is this:
public int[] modeOfData()
{
int[] tally = new int[maxOfData() + 1];
for( int i = 0; i < size; i++)
{
tally[data[i]]++;
}
//max contains frequency of modes
int max = maxOfData (tally);
int count = 0;
for( int i = 0; i < tally.length; i++)
{
if( tally[i] == max )
count++;
}
//count occurence of maxValue in tally (for)
//that determines how many modes there are
//declare another int called modes
int[] modes = new int[count];
//size of array should be count
//loop through tally and extract modes: it's the index value.
int pos = 0;
for( int i = 0; i < tally.length; i++)
{
if(tally[i] == count)
modes[pos++] = i;
}
return modes;
//modes are where the values are == max
}
My other max for data is the same but data instead of oa. I need both max methods, just like that, according to my teacher. So what do I do? How do I fix this?
I think the line
for (int i = 1; i < size; i++)
should be
for (int i = 1; i < oa.length; i++)
ArrayIndexOutOfBound Exception is thrown to indicate that an array has been accessed with an illegal index. The index is either negative or greater than or equal to the size of the array. Whenever you iterate an Array object. you need to iterate while checking the index is always lesser than its length
for example,
for(int i=1;i<array.length;i++){
//access array content in ith position
System.out.println(array[i]);
}
Your size variable has the value of an illegal array index. that's the problem
Look at the number stored into size and then check to see what size you declared oa[] to be. If size is bigger than the size of oa[] then you have a problem.
Problem is in this part of code
int max = oa[0];
for (int i = 1; i < size; i++)
{
if (oa[i] > max)
max = oa[i];
}
rewrite the method maxOfData(int [] oa) with proper checks like this
public int maxOfData(int[] oa) {
if (oa == null) {
throw new IllegalArgumentException("Input array is null");
}
int max=oa[0];
for (int i = 1; i < oa.length; i++) {
if (oa[i] > max)
max = oa[i];
}
return max;
}
if input array is null it should not be processed.

java.lang.NullPointerException error trying to fill arrays

I am trying to put the values (integers) from the 2 dimensional array prices[][] into the cost variable of the objects in the array seatArray[][]. I think the problem is that I am trying to put the values from the prices array into nothing because the seatArray array is only full of object references to null. How would I go about fixing this?
line that calls constructor:
SeatChart seatArray = new SeatChart(givenArray);
constructor method:
public SeatChart(int[][] prices)
{
Seat[][] seatArray = new Seat[9][10];
for(int i = 0; i < 9; i++)
{
for(int j = 0; j < 10; j++)
{
seatArray[i][j].cost=prices[i][j];
}
}
}
Seat[][] seatArray = new Seat[9][10];
This just declares the array and doesn't initialize the array elements with Seat objects.
for(int i = 0; i < 9; i++)
{
for(int j = 0; j < 10; j++)
{
// I've used a default Seat() constructor to create the object, in your actual case, it may differ.
seatArray[i][j] = new Seat(); // Initializing each array element with a new Seat object
seatArray[i][j].cost=prices[i][j];
}
}
seatArray[i][j] = new Seat();
seatArray[i][j].cost= prices[i][j];
Or maybe for clarity
Seat seat = new Seat();
seat.setCost(prices[i][j]);
seatArray[i][j] = seat;

Categories

Resources