Map the values of array elements - java

public class EconomicModel {
public static void main(String[] args) {
int[] StarTime = new int[20];
int[] duration = new int[40];
int[] TotalDuration = new int[40];
int[] EndTime = new int[StarTime.length];
int[] relinqtime = new int[20];
int[] ResAllocRAM = {101,9,56,89,43,30,8,60,13,41,60, 20, 32,71,76,7,31,46,30,99 };
StarTime[0] = 0;
ExponentialDistribution exp = new ExponentialDistribution(4.0);
for(int j = 1; j < 20; j++){
StarTime[j] = (int)exp.sample() + 1+StarTime[j-1];
}
for(int k = 0; k < 20;k ++){
duration[k] = 20 + (int)(Math.random() * ((120 - 10) + 1));
}
for(int k = 0; k < 20; k++){
EndTime[k] = StarTime[k] + duration[k];
}
Random r = new Random();
for (int i=0; i<20; i++){
relinqtime[i] = r.nextInt((EndTime[i] - StarTime[i])+ StarTime[i] ) + StarTime[i];
}
for ( int j = 0; j<20; j++)
for(int k = StarTime[j]; k <= relinqtime[j]; k++){
TotalDuration[k]+= ResReqRAM[j];
}
}
}
I have arrays called StarTime, relinqtime, ResAllocRAM and TotalDuration. I want to assign values to the indexes of array TotalDuration based on the other three arrays. Like if value of StarTime[1] is 5, value of relinqtime[1] is 8, value of ResAllocRAM[1] is 9. I want that value TotalDuration[5],TotalDuration[6],TotalDuration[7] should be the value of ResAllocRAM[1].
I tried the above code but it is giving exception bound error at line TotalDuration[k]+= ResReqRAM[j];
What should I do to map the values of these arrays and produce a new array as mentioned?

Use a Map, it saves elements as Key, Value pair, remember keys should be unique.
Map<Integer, Integer> hashMap = new HashMap<>();
hashMap.put(TotalDuration[5], ResAllocRAM[1]); //put(key,value)
int value = hashMap.get(TotalDuration[5]); //it will return you value of ResAllocRAM[1]
simple tutorial for map

Try changing the line as follows
TotalDuration[k] = ResReqRAM[j];
If you are trying to increment TotalDuration then set initial values to 0 as the TotalDuration array is empty when you are trying to assign in it

Related

Inputting multiple arrays of integers into an arrayList and then printing each array

I'm looking to create a dynamic amount of arrays of random integers and then put them into an array list. Later I want to use each of these arrays separately to test for quick sort functionality. I'm having problems with adding the object List[] into the ArrayList.
//Create dynamic amount of random arrays
public static ArrayList<int[]> Randomizer(int arrays, int size, int seed){
ArrayList<int[]> Tests = new ArrayList<int[]>(arrays);
int[] List = new int[size];
for (int j = 0; j < arrays; j++){
Random r = new Random(seed+j);
for(int i = 0; i < size; i++){
List[i] = r.nextInt(5*size);//Multiplier for how big the numbers get
System.out.print(List[i] + ",");
}
System.out.println();
Tests.add(j, List);
}
return Tests;
}
public static void main(String[] args) {
int tests = 5;
int size = 4;
ArrayList<int[]> Test = Randomizer(tests,size,10); //1st = Number of Tests
//2nd = Number of Digits
//3rd = seed for Randomizer
for(int i = 0; i < Test.size(); i++){
System.out.println(Test.get(i));
}
}
}
The problem with your code was that you were storing the same array 5 times into the ArrayList, so when printing during generation it printed correct numbers, but later you couldn't get them out. Each iteration of the for loop was overwriting the values generated earlier.
Here is the corrected code:
private static ArrayList<int[]> randomizer(int arrays, int size, int seed){
ArrayList<int[]> tests = new ArrayList<>(arrays);
for (int j = 0; j < arrays; j++) {
int[] list = new int[size];
Random r = new Random(seed + j);
for(int i = 0; i < size; i++) {
list[i] = r.nextInt(5 * size); // Multiplier for how big the numbers get
}
tests.add(j, list);
}
return tests;
}
public static void main(String[] args) {
int tests = 5;
int size = 4;
ArrayList<int[]> arrays = randomizer(tests, size, 10);
for (int i = 0; i < arrays.size(); i++){
int[] ints = arrays.get(i);
for (int j = 0; j < ints.length; j++) {
System.out.print(ints[j] + ",");
}
System.out.println();
}
}
Basically you needed to move the int[] list = new int[size]; line inside the for loop, so that you are actually creating new arrays instead of using the same one each time.
You can now replace the printing loop in the main() method with whatever you like, like your quick sort tests. Let me know if anything still doesn't work.

Creating a multi-dimensional String array from a method array parameter

I am attempting to solve a semi-difficult problem in which I am attempting to create an array and return a 3 dimensional array based on the parameter which happens to be a 2 dimensional int array. The array I'm attempting to return is a String array of 3 dimensions. So here is the code:
public class Displaydata {
static String[][][] makeArray(int[][] dimensions) {
String myArray[][][];
for (int i = 0; i < dimensions.length; i++) {
for (int j = 0; j < dimensions[i].length; j++) {
myArray[][][] = new String[i][j][]; //getting error here.
}
}
return myArray;
}
static void printArray(String[][][] a) {
for (int i = 0; i < a.length; i++) {
System.out.println("\nrow_" + i);
for (int j = 0; j < a[i].length; j++) {
System.out.print( "\t");
for (int k = 0; k < a[i][j].length; k++)
System.out.print(a[i][j][k] + " ");
System.out.println();
}
}
}
public static void main(String[] args) {
int [][] dim = new int[5][];
dim[0] = new int[2];
dim[1] = new int[4];
dim[2] = new int[1];
dim[3] = new int[7];
dim[4] = new int[13];
dim[0][0] = 4;
dim[0][1] = 8;
dim[1][0] = 5;
dim[1][1] = 6;
dim[1][2] = 2;
dim[1][3] = 7;
dim[2][0] = 11;
for (int i = 0; i < dim[3].length;i++)
dim[3][i] = 2*i+1;
for (int i = 0; i < dim[4].length;i++)
dim[4][i] = 26- 2*i;
String[][][] threeDee = makeArray(dim);
printArray(threeDee);
}
}
As you can see from the source code, I'm getting an error when I try to create an instance of my 3-dimensional array which I'm attempting to return. I'm supposed to create a three dimensional array with the number of top-level rows determined by the length of dimensions and, for each top-level row i, the number of second-level rows is determined by the length of dimensions[i]. The number of columns in second-level row j of top-level row i is determined by the value of dimensions[i][j]. The value of each array element is the concatenation of its top-level row index with its second-level row index with its column index, where indices are represented by letters : ‘A’ for 0, ‘B’ for 1 etc. (Of course, this will only be true if the indices don’t exceed 25.) I don't necessarily know where I'm going wrong. Thanks!
You should not be initializing the array on every iteration of the loop. Initialize it once outside the loop and then populate it inside the loop.
static String[][][] makeArray(int[][] dimensions) {
String[][][] myArray = new String[25][25][1];
for (int i = 0; i < dimensions.length; i++) {
for (int j = 0; j < dimensions[i].length; j++) {
myArray[i][j][0] = i + "," + j;
}
}
return myArray;
}
I just plugged in values for the size of the first two dimensions, you will need to calculate them based on what you put in there. The 'i' value will always be dimensions.length but the 'j' value will be the largest value returned from dimensions[0].length -> dimensions[n-1].length where 'n' is the number of elements in the second dimension.
Also you will need to set up a way to convert the numbers in 'i' and 'j' to letters, maybe use a Map.
I guess you should initialize the array as
myArray = new String[i][j][]; //getting error here.
I think
myArray[][][] = new String[i][j][]; //getting error here.
should be:
myArray[i][j] = new String[5]; // I have no idea how big you want to go.
And then you can fill in each element of you inner-most array like such:
myArray[i][j][0] = "first item";
myArray[i][j][1] = "second string";
...
I think you should just change that line to:
myArray = new String[i][j][]; //look ma! no compiler error
Also, you would need to initialize myArray to something sensible (perhaps null?)

Merge Sort - Sorting String Array with Int Array

For this project, I'm given an array of strings and an array of ints. int[1] is the ranking for string[1]. I need to sort the int array in order from 1 to n using mergesort, which I've done below. But I also need to switch the positions of the string array when the int array gets moved so they are both sorted, if that makes sense? I can't figure out what's wrong with my coding or even if my idea will actually work, but I keep getting an array index out of bounds error on stringSorted[k] = stringRight[j] and I can't figure out if there's a way to fix this. Essentially, when an int was added to the sortedInt array, I also added that element to the sorted String array. Thank you for any help, and let me know if something doesn't make sense
private static int sortAndCount(int intToSort[]){
int inversionsLeft;
int inversionsRight;
int inversionsMerged;
if(intToSort.length == 1){
return 0;
}
int m = intToSort.length/2;
int[] intLeft = new int[m];
stringLeft = new String[m];
int[] intRight = new int[intToSort.length-m];
stringRight = new String[intToSort.length-m];
for (int i=0; i < m; i++){
intLeft[i] = intToSort[i];
stringLeft[i] = stringToSort[i];
}
for (int i = 0;i < intRight.length; i++){
intRight[i] = intToSort[m+i];
stringRight[i] = stringToSort[m+i];
}
inversionsLeft = sortAndCount(intLeft);
inversionsRight = sortAndCount(intRight);
intSorted = new int[intToSort.length];
stringSorted = new String[stringToSort.length];
inversionsMerged = mergeAndCount(intLeft, intRight);
return(inversionsLeft + inversionsRight + inversionsMerged);
}
private static int mergeAndCount(int[] intLeft, int[] intRight){
int count = 0;
int i = 0;
int j = 0;
int k = 0;
while(i < intLeft.length && j < intRight.length){
if(intLeft[i] < intRight[j]){
intSorted[k] = intLeft[i];
stringSorted[k] = stringLeft[i];
i++;
}
else{
intSorted[k] = intRight[j];
stringSorted[k] = stringRight[j];
count += intLeft.length - i + 1;
j++;
}
k++;
}
while (i < intLeft.length)
{
intSorted[k] = intLeft[i];
stringSorted[k] = stringLeft[i];
k++;
i++;
}
while (j < intRight.length)
{
intSorted[k] = intRight[j];
stringSorted[k] = stringRight[j];
j++;
k++;
}
return count;
}
}
int[] intLeft = new int[m];
stringLeft = new String[m];
int[] intRight = new int[intToSort.length-m];
stringRight = new String[intToSort.length-m];
You'll notice here that for the int arrays you are creating new variables, for the string you are replacing the outer. This is making your string arrays smaller with each recursive call whereas your int arrays are passed to each method.
By the time you get to calling mergeAndCount, stringLeft and stringRight are very small whereas the appropriately sized intLeft and intRight are passed as arguments.

Get unique indexes after sorting an array with duplicate entries

I need to sort an array and get indexes linked to an unsorted array. The problem is that if the unsorted array contains duplicate entries, i.e. [1,1,1,2,2,], then indexes are the same for these entries. For the example [3,5,5,3,3,] the indexes would be [0,1,1,0,0]. But I would need to get the following indexes [0,3,4,1,2]. How to do this?
ArrayList<Double> nfit = new ArrayList<Double>();
ArrayList<Double> nfit_copy = new ArrayList<Double>(nfit);
// Fill nfit
Collections.sort(nfit);
int[] ind = new int[nfit.size()];
for (int n = 0; n < nfit.size(); n++){
ind[n] = nfit_copy.indexOf(nfit.get(n));
}
This is because you use nfit_copy.indexOf(nfit.get(n)); which will gave you the same index if you have duplicated number
For Example
[3,5,5,3,3,]----> every time you will use :nfit.indexOf(3) ,will give you index 0
so , may be you need to change this value or set it null (Don't reomve it because it will change the index) , to allow you to get the next duplicate number
Try this:
ArrayList<Integer> nfit = new ArrayList<Integer>();
ArrayList<Integer> nfit_copy = new ArrayList<Integer>(nfit);
// Fill nfit
nfit.add(3);
nfit.add(5);
nfit.add(5);
nfit.add(3);
nfit.add(3);
nfit_copy = (ArrayList<Integer>) nfit.clone();
Collections.sort(nfit);
int[] ind = new int[nfit.size()];
for (int n = 0; n < nfit.size(); n++) {
ind[n] = nfit_copy.indexOf(nfit.get(n));
nfit_copy.set(nfit_copy.indexOf(nfit.get(n)), null);
}
for (int i = 0; i < ind.length; i++) {
int j = ind[i];
System.out.println(j);
}
public static void main(String[] args) {
Integer[] input = new Integer[]{1,2,2,1,5,6,2,3,2,3,4,5,6,1};
List<Integer> mappedIndexes = new ArrayList<Integer>();
List<Integer> sorted = new ArrayList<Integer>();
for (int num : input) {
sorted.add(num);
}
Collections.sort(sorted);
for (int number : input) {
System.out.println("finding for input -> " + number);
for (int i = 0; i < sorted.size(); i++) {
int sortedNumber = sorted.get(i);
if (number == sortedNumber) {
if (mappedIndexes.contains(i)) {
continue;
} else {
System.out.println("setting index as -> " + i);
mappedIndexes.add(i);
break;
}
}
}
}
System.out.println(mappedIndexes);
}
Here is my solution with Set and HashMap structures. Read the code comments for more info, please.
int[] input = { 45, 3, 4, 9, 2, 1, 45, 3 };
// Backup the initial array for later use.
int[] originalArray = Arrays.copyOf(input, input.length);
Arrays.sort(input);
// Determine all occurences with a set.
Set<Integer> set = new HashSet<Integer>();
for (int i : input) {
set.add(i);
}
// Populate a hashmap for keeping <value,index> pairs.
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
int counter = 0;
for (int i : set) {
map.put(i, counter++);
}
// Populate the output array.
int[] output = new int[input.length];
for (int i = 0; i < output.length; i++) {
output[i] = map.get(originalArray[i]);
}
That's all. If you print the contents of output to console, you can see the results.

How to reduce copy-pasting?

If I have a number of similar classes, say:
Integer i0;
Integer i1;
Integer i2;
Integer i3;
Integer i4;
Integer i5;
Integer i6;
Integer i7;
Integer i8;
Integer i9;
And wanted to avoid doing this:
i0 = 0;
i1 = 1;
i2 = 2;
i3 = 3;
i4 = 4;
i5 = 5;
i6 = 6;
i7 = 7;
i8 = 8;
i9 = 9;
I'm thinking of doing something similar to this to achieve the same result:
int cnt = 0;
for(classname : arrayOfClassNames {
classname = cnt++;
}
How do I do that?
[clarification] I appears I was misunderstood. I was thinking more along the lines of having 10 separate classes still, not one array having 10 items.
Use an array or an ArrayList?
// using an array
Integer[] ints = new Integer[10];
for (int i = 0; i < 10; i++) {
ints[i] = i;
}
// using an array list
ArrayList<Integer> ints = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
ints.add(i);
}
Following on from your update, what you are looking to do can be achieved using
Class.forName(classname).newInstance();
However, I would suggest that whatever you save in time to code it, you will lose in readability and ease of maintenance, so you may find this a false economy.
Store them in an array:
Integer[] array = new Integer[10];
for(int i = 0 ; i < 10 ; i++){
array[i] = i ;
}
To get i9: array[9]
Use a java.util.Map<T, K>:
Map<String, Integer> map = new HashMap<String, Integer>();
for (int i = 0; i < 10; i++)
{
map.put("i" + i, i);
}
System.out.println(map);
System.out.println("i8: " + map.get("i8"));
A number of similar classes sounds like you want an Array:
Integer[] manyI = new Integer[] {0, 1, 2, ....};
Or you fill the Array with a loop:
Integer[] manyI = new Integer[10];
for (int i = 0; i < manyI.length; i++) manyI[i] = i;

Categories