Compilation error - Inversions counting algorithm - java

I am struggling in my code with an error.
This is the error I got:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The method recur(Integer[]) in the type D_and_con is not applicable for the arguments (int[])
at edu.uqu.algorithms.inversions.D_and_con.recur(D_and_con.java:27)
at edu.uqu.algorithms.inversions.MainTest.main(MainTest.java:27)
The code computes the number of inversions.
It is:
package edu.uqu.algorithms.inversions;
import java.io.FileNotFoundException;
import java.util.Arrays;
import edu.uqu.algorithms.inversions.util.IOUtil;
public class MainTest {
public static void main(String[] args) {
try {
/*//Inversions using BRUTE FORCE
Integer[] tokens1 = IOUtil.loadFileIntoArray("IntegerArray.txt");
long startTime1 = System.currentTimeMillis();
System.out.println("Started Computing Total nb of invertions BRUTE FORCE..........................");
System.out.println("Total nb of invertions BRUTE FORCE: " + Inversions.countInvertionsBruteForce(tokens1));
long runningTime1 = (System.currentTimeMillis() - startTime1);
System.out.println("BRUTE FORCE Running time: " + runningTime1);
System.out.println("\n");*/
//Inversions using DIVIDE & CONQUER
Integer[] tokens2 = IOUtil.loadFileIntoArray("IntegerArray.txt");
long startTime2 = System.currentTimeMillis();
System.out.println("Started Computing Total nb of invertions DIVIDE & CONQUER..........................");
System.out.println("MMMMM" + D_and_con.recur(tokens2) );
long runningTime2 = (System.currentTimeMillis() - startTime2);
System.out.println("DIVIDE & CONQUER Running time: " + runningTime2);
System.out.println("----------------------- FINISHED -------------------------");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
----------------------------------------
/************************************
*
* The aim of this code is to count the number of inversions in
* an array of integers. Two ways of counting are used, a Brute Force algorithm and
* a recursive Divide and Conquer algorithm.
*
***********************************/
package edu.uqu.algorithms.inversions;
/**
public class Inversions{
/**
* Brute force inversions counting method.
*/
public static long countInvertionsBruteForce(Integer[] entries_p)
{
long result = 0;
for(int i = 0; i < entries_p.length; i++){
for(int j = i+1; j < entries_p.length; j++){
if(entries_p[i] > entries_p[j]) result++;
}
//System.out.println("BRUTE FORCE intermediate result for i = " + i + " IS: " + result);
}
return result;
}
}
--------------------------
Divide and conquer
/************************************
*
* The aim of this code is to count the number of inversions in
* an array of integers. Two ways of counting are used, a Brute Force algorithm and
* a recursive Divide and Conquer algorithm.
*
***********************************/
package edu.uqu.algorithms.inversions;
import java.math.BigDecimal;
public class D_and_con{
private static BigDecimal totalcount = new BigDecimal(0);
public static Integer[] recur(Integer[] entries_p)
{
int n = entries_p.length;
if(n == 1)
{
return entries_p;
}
int middel = n/2;
int[] Larray = new int[middel];
int[] Rarray = new int[n - middel];
System.arraycopy(entries_p , 0 , Larray, 0 , Larray.length );
System.arraycopy(entries_p , Larray.length , Rarray , 0 , Rarray.length);
recur(Larray);\\ERROR APPEAR HERE
recur(Rarray);\\ERROR APPEAR HERE
comb(Larray , Rarray , entries_p );
return entries_p;
}
private static void comb(int[] Larray, int[] Rarray, Integer[] newarray)
{
int LarrayL = Larray.length;
int RarrayL = Rarray.length;
int i=0 , j=0 , k=0 ;
while(i< LarrayL && i<RarrayL)
{
if(Larray[i] < Rarray[i] )
{
newarray[k] = Larray[i];
i++;
}
else
{
newarray[k] = Rarray[j];
i++;
totalcount = totalcount.add (new BigDecimal(Larray.length - 1));
}
k++;
}
while(i < LarrayL) {
newarray[k] = Larray[i];
i++;
k++;
}
while(j < RarrayL) {
newarray[k] = Rarray[j];
j++;
k++;
}
}
}

Explanation
The compiler complaints that you feed your recur method with something of type int[] but you declared that it accepts Integer[]. Therefore take a look at the method signature
// entries_p is Integer[], not int[]
public static Integer[] recur(Integer[] entries_p)
but you feed the method with int[] as seen here
int[] Larray = new int[middel];
int[] Rarray = new int[n - middel];
...
recur(Larray);
recur(Rarray);
Integer is different to int. Though Java can automatically convert both into each other (boxing) it won't do that for advanced types liked arrays Integer[] and int[].
Converting
You will need to convert the types by yourself. Note that Integer[] in contrast to int[] is capable of storing null.
Here are some easy conversions, first without using Streams:
// from int[] to Integer[]
int[] source = ...
Integer[] target = new Integer[source.length];
for (int i = 0; i < source.length; i++) {
// Convert int to Integer
target[i] = Integer.valueOf(source[i]);
}
// from Integer[] to int[]
Integer[] source = ...
int[] target = new int[source.length];
for (int i = 0; i < source.length; i++) {
if (source[i] == null) {
// Don't support null values
throw IllegalArgumentException();
}
// Convert Integer to int
target[i] = source[i].intValue();
}
And now the same using Streams (Java 8):
// from int[] to Integer[]
int[] source = ...
Integer[] target = Arrays.stream() // IntStream
.boxed() // Stream<Integer>
.toArray(Integer[]::new)
// from Integer[] to int[]
Integer[] source = ...
int[] target = Arrays.stream() // Stream<Integer>
.mapToInt(Integer::intValue) // Stream<Integer>
.toArray(int[]::new)
Changing method or argument
Instead of converting the array from one into the other type you may also adjust your method or the argument. For example you could change the method signature from
public static Integer[] recur(Integer[] entries_p)
to
public static Integer[] recur(int[] entries_p)
then it will accept int[] as argument. You may also change the return type to int[]. The other alternative would, as said, be to change the argument from int[] to Integer[]. This applies to that code section:
// You may change both to Integer[]
int[] Larray = new int[middel];
int[] Rarray = new int[n - middel];

Change your Integer[] arrays to int[] arrays!

"int" is a primitive data-type and "Integer" is a Class.
To solve your problem:-
1 - Integer[] tokens2 = IOUtil.loadFileIntoArray("IntegerArray.txt"); //Read data from file in int[].
2 - Integer[] recur(Integer[] entries_p){} //change it as int[] recur(int[] entries_p)

Related

only mange 77% on codility sample test

I tried the codility demo test, but never get more than 77% due to their performance tests.
the test mainly states:
given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A.
Whats wrong with my solution?
The failed performance test comlains:TIMEOUT ERROR
running time: 0.152 sec., time limit: 0.100 sec.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
class Solution3 {
int solution(int[] A) {
ArrayList<Integer> list = Arrays.stream(A).boxed().distinct().sorted()
.filter(i -> i > 0)
.collect(Collectors.toCollection(ArrayList::new));
Integer prev_item = 0;
for (int i = 0; i < list.size(); i++) {
Integer item = list.get(i);
if (!(item - 1 == prev_item)) {
return prev_item + 1;
}
prev_item = item;
}
return prev_item + 1;
}
public static void main(String[] args) {
Solution3 solution3 = new Solution3();
int[] A = new int[6];
A[0] = 1;
A[1] = 2;
A[2] = 3;
A[3] = 8;
A[4] = 8;
A[5] = 11;
int solution = solution3.solution(A);
System.out.println("solution: " + solution);
}
}
I came up with this solution and it scored 100%. It is in python, if someone wants it in java I will post that too. Just let me know.
def solution(A):
A.sort()
smallest = 1
for i in range(0, len(A)):
if A[i] > 0:
if smallest < A[i]:
return smallest
elif smallest == A[i]:
smallest = smallest + 1
return smallest
I think the main problem is that and how you transform the array to an ArrayList and put work into cleaning it from negative values.
It would be a lot better in terms of performance if you would just sort the array with Arrays.sort(A) and then binary search it for the first positive value and do the rest from there.
I found the solution with following code:
function smallest(A) {
const set = new Set(A);
let i=1;
while(set.includes(i)) {
i++;
}
return i;
}
how could I know that brute force iteration is a solution here. would expect that performance is bad for big arrays
public class Foo {
public static void main(String[] args) {
Integer[] ints = { 11, 2, 6, 3, 4, 8, 1, 5 };
System.out.println(findSmallest(ints));
}
private static Integer findSmallest(Integer[] ints){
List<Integer> integers = Arrays.asList(ints);
for (int i = 1; i < Integer.MAX_VALUE; i++) {
if (!integers.contains(i)) {
return i;
}
}
return Integer.MAX_VALUE;
}
}

Sort multiple arrays simultaneously "in place"

I have the following 3 arrays:
int[] indexes = new int[]{0,2,8,5};
String[] sources = new String[]{"how", "are", "today", "you"};
String[] targets = new String[]{"I", "am", "thanks", "fine"};
I want to sort the three arrays based on the indexes:
indexes -> {0,2,5,8}
sources -> {"how", "are", "you", "today"}
targets -> {"I", "am", "fine", "thanks"}
I can create a new class myClass with all three elements:
class myClass {
int x;
String source;
String target;
}
Reassign everything to myClass, then sort myClass using x. However, this would required additional spaces. I am wondering if it is possible to do in place sorting? Thanks!
Three ways of doing this
1. Using Comparator (Need Java 8 plus)
import java.io.*;
import java.util.*;
class Test {
public static String[] sortWithIndex (String[] strArr, int[] intIndex )
{
if (! isSorted(intIndex)){
final List<String> stringList = Arrays.asList(strArr);
Collections.sort(stringList, Comparator.comparing(s -> intIndex[stringList.indexOf(s)]));
return stringList.toArray(new String[stringList.size()]);
}
else
return strArr;
}
public static boolean isSorted(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i + 1] < arr[i]) {
return false;
};
}
return true;
}
// Driver program to test function.
public static void main(String args[])
{
int[] indexes = new int[]{0,2,8,5};
String[] sources = new String[]{"how", "are", "today", "you"};
String[] targets = new String[]{"I", "am", "thanks", "fine"};
String[] sortedSources = sortWithIndex(sources,indexes);
String[] sortedTargets = sortWithIndex(targets,indexes);
Arrays.sort(indexes);
System.out.println("Sorted Sources " + Arrays.toString(sortedSources) + " Sorted Targets " + Arrays.toString(sortedTargets) + " Sorted Indexes " + Arrays.toString(indexes));
}
}
Output
Sorted Sources [how, are, you, today] Sorted Targets [I, am, fine, thanks] Sorted Indexes [0, 2, 5, 8]
2. Using Lambda (Need Java 8 plus)
import java.io.*;
import java.util.*;
public class Test {
public static String[] sortWithIndex (String[] strArr, int[] intIndex )
{
if (! isSorted(intIndex)) {
final List<String> stringList = Arrays.asList(strArr);
Collections.sort(stringList, (left, right) -> intIndex[stringList.indexOf(left)] - intIndex[stringList.indexOf(right)]);
return stringList.toArray(new String[stringList.size()]);
}
else
return strArr;
}
public static boolean isSorted(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i + 1] < arr[i]) {
return false;
};
}
return true;
}
// Driver program to test function.
public static void main(String args[])
{
int[] indexes = new int[]{0,2,5,8};
String[] sources = new String[]{"how", "are", "today", "you"};
String[] targets = new String[]{"I", "am", "thanks", "fine"};
String[] sortedSources = sortWithIndex(sources,indexes);
String[] sortedTargets = sortWithIndex(targets,indexes);
Arrays.sort(indexes);
System.out.println("Sorted Sources " + Arrays.toString(sortedSources) + " Sorted Targets " + Arrays.toString(sortedTargets) + " Sorted Indexes " + Arrays.toString(indexes));
}
}
3. Using Lists and Maps and avoiding multiple calls (as in second solution above) to the method to sort individual arrays
import java.util.*;
import java.lang.*;
import java.io.*;
public class Test{
public static <T extends Comparable<T>> void sortWithIndex( final List<T> key, List<?>... lists){
// input validation
if(key == null || lists == null)
throw new NullPointerException("Key cannot be null.");
for(List<?> list : lists)
if(list.size() != key.size())
throw new IllegalArgumentException("All lists should be of the same size");
// Lists are size 0 or 1, nothing to sort
if(key.size() < 2)
return;
// Create a List of indices
List<Integer> indices = new ArrayList<Integer>();
for(int i = 0; i < key.size(); i++)
indices.add(i);
// Sort the indices list based on the key
Collections.sort(indices, new Comparator<Integer>(){
#Override public int compare(Integer i, Integer j) {
return key.get(i).compareTo(key.get(j));
}
});
Map<Integer, Integer> swapMap = new HashMap<Integer, Integer>(indices.size());
List<Integer> swapFrom = new ArrayList<Integer>(indices.size()),
swapTo = new ArrayList<Integer>(indices.size());
// create a mapping that allows sorting of the List by N swaps.
for(int i = 0; i < key.size(); i++){
int k = indices.get(i);
while(i != k && swapMap.containsKey(k))
k = swapMap.get(k);
swapFrom.add(i);
swapTo.add(k);
swapMap.put(i, k);
}
// use the swap order to sort each list by swapping elements
for(List<?> list : lists)
for(int i = 0; i < list.size(); i++)
Collections.swap(list, swapFrom.get(i), swapTo.get(i));
}
public static void main (String[] args) throws java.lang.Exception{
List<Integer> index = Arrays.asList(0,2,8,5);
List<String> sources = Arrays.asList("how", "are", "today", "you");
// List Types do not need to be the same
List<String> targets = Arrays.asList("I", "am", "thanks", "fine");
sortWithIndex(index, index, sources, targets);
System.out.println("Sorted Sources " + sources + " Sorted Targets " + targets + " Sorted Indexes " + index);
}
}
Output
Sorted Sources [how, are, you, today] Sorted Targets [I, am, fine, thanks] Sorted Indexes [0, 2, 5, 8]
It is possible although it is not that easy than it looks like. There are two options:
write your own sort algorithm where the swap function for two elements also swaps the elements in the other arrays.
AFAIK there is no way to extend the standard Array.sort in a way that it swaps additional arrays.
Use a helper array with the sort order.
First of all you need to initialize the helper array with the range {0, 1 ... indexes.Length-1}.
Now you sort the helper array using a Comparator that compares indexes[a] with indexes[b] rather than a to b.
The result is an helper array where each element has the index of the element of the source array where its content should come from, i.e. the sort sequence.
The last step is the most tricky one. You need to swap the elements in your source arrays according to the sort sequence above.
To operate strictly in place set your current index cur to 0.
Then take the cur-th element from your helper array. Let's call it from. This is the element index that should be placed at index cur after completion.
Now you need to make space at index cur to place the elements from index from there. Copy them to a temporary location tmp.
Now move the elements from index from to index cur. Index from is now free to be overridden.
Set the element in the helper array at index cur to some invalid value, e.g. -1.
Set your current index cur to from proceed from above until you reach an element in the helper array which already has an invalid index value, i.e. your starting point. In this case store the content of tmp at the last index. You now have found a closed loop of rotated indices.
Unfortunately there may exist an arbitrary number of such loops each of arbitrary size. So you need to seek in the helper array for the next non-invalid index value and again continue from above until all elements of the helper array are processed.
Since you will end at the starting point after each loop it is sufficient to increment cur unless you find an non-invalid entry. So the algorithm is still O(n) while processing the helper array.
All entries before cur are necessarily invalid after a loop completed.
If curincrements beyond the size of the helper array you are done.
There is an easier variation of option 2 when you are allowed to create new target arrays.
In this case you simply allocate the new target arrays and fill their content according to the indices in your helper array.
The drawback is that the allocations might be quite expensive if the arrays are really large. And of course, it is no longer in place.
Some further notes.
Normally the custom sort algorithm performs better as it avoids the allocation of the temporary array. But in some cases the situation changes. The processing of the cyclic element rotation loops uses a minimum move operations. This is O(n) rather than O(n log n) of common sort algorithms.
So when the number of arrays to sort and or the size of the arrays grows the method #2 has an advantage because it uses less swap operations.
A data model requiring a sort algorithm like this is mostly broken by design. Of course, like always there are a few cases where you can't avoid this.
May I suggest you to use a TreeMap or something similar, using your integer as key.
static Map<Integer, myClass> map = new TreeMap<>();
So when you want to retrieve ordered you only have to do a for loop or whatever you prefer.
for (int i : map.keyset()){
System.out.println("x: "+map.get(i).x+"\nsource: "+map.get(i).source+"\ntarget: "+map.get(i).target);
}
This example requires creating an Integer array of indexes, but the arrays to be sorted are reordered in place according to array1, and the arrays can be of any type (primitives or objects) that allows indexing.
public static void main(String[] args) {
int array1[]={5,1,9,3,8};
int array2[]={2,0,3,6,1};
int array3[]={3,1,4,5,9};
// generate array of indices
Integer[] I = new Integer [array1.length];
for(int i = 0; i < I.length; i++)
I[i] = i;
// sort array of indices according to array1
Arrays.sort(I, (i, j) -> array1[i]-array1[j]);
// reorder array1 ... array3 in place using sorted indices
// also reorder indices back to 0 to length-1
// time complexity is O(n)
for(int i = 0; i < I.length; i++){
if(i != I[i]){
int t1 = array1[i];
int t2 = array2[i];
int t3 = array3[i];
int j;
int k = i;
while(i != (j = I[k])){
array1[k] = array1[j];
array2[k] = array2[j];
array3[k] = array3[j];
I[k] = k;
k = j;
}
array1[k] = t1;
array2[k] = t2;
array3[k] = t3;
I[k] = k;
}
}
// display result
for (int i = 0; i < array1.length; i++) {
System.out.println("array1 " + array1[i] +
" array2 " + array2[i] +
" array3 " + array3[i]);
}
}
Another solution using Collection (increase the memory usage) :
Let's create a sorted map to will simply be a mapping between the correct index and the original position :
public static TreeMap<Integer, Integer> sortIndex(int[] array){
TreeMap<Integer, Integer> tree = new TreeMap<>();
for(int i=0; i < array.length; ++i) {
tree.put(array[i], i);
}
return tree;
}
Test :
int[] indexes = new int[] { 0, 1, 3, 2, 4, 5 };
TreeMap<Integer, Integer> map = sortIndex(indexes);
map.keySet().stream().forEach(System.out::print); //012345
map.values().stream().forEach(System.out::print); //013245
We have the indexes sorted (on the key) and the original index order as the values.
No we can simple use this to order the array, I will be drastic and use a Stream to map and collect into a List.
public static List<String> sortInPlace(String[] array, TreeMap<Integer, Integer> map) {
return map.values().stream().map(i -> array[i]).collect(Collectors.toList());
}
Test :
String[] sources = "to be not or to be".split(" ");
int[] indexes = new int[] { 0, 1, 3, 2, 4, 5 };
TreeMap<Integer, Integer> map = sortIndex(indexes);
List<String> result = sortInPlace(sources, map);
System.out.println(result);
[to, be, or, not, to, be]
Why did I use a List. Mostly to simplify the re-ordering, if we try to order the original arrays, it will be complicated because we need to remove the opposed key/pair
2 -> 3
3 -> 2
Without some cleaning, we will just swap the cells twice ... so there will be no changes.
If we want to reduce a bit the memory usage, we can create another array instead of using the stream and copy values per values iterating the map. This would be possible to do with multiple array in parallel too.
It all depends on the size of your arrays. This solution will use the first array to perform the sorting but will perform the permutation on multiple arrays.
So this could have some performances issues if the sorting algorithm used will need a lot of permutation.
Here, I took a basic sorting algorithm on which I have added some actions I can do during the swap of two cells. This allows use to define some lambda to swap multiple array at the same time based on one array.
public static void sortArray( int[] array, BiConsumer<Integer, Integer>... actions ) {
int tmp;
for ( int i = 0, length = array.length; i < length; ++i ) {
tmp = array[i];
for ( int j = i + 1; j < length; ++j ) {
if ( tmp > array[j] ) {
array[i] = array[j];
array[j] = tmp;
tmp = array[i];
// Swap the other arrays
for ( BiConsumer<Integer, Integer> cons : actions ){
cons.accept( i, j);
}
}
}
}
}
Let's create a generic method to swap the cells that we can pass as a BiConsumer lambda (only works for non-primitive arrays):
public static <T> void swapCell( T[] array, int from, int to ) {
T tmp = array[from];
array[from] = array[to];
array[to] = tmp;
}
That allows use to sort the arrays like :
public static void main( String[] args ) throws ParseException {
int[] indexes = new int[] { 0, 2, 8, 5 };
String[] sources = new String[] { "how", "are", "today", "you" };
String[] targets = new String[] { "I", "am", "thanks", "fine" };
sortArray( indexes,
( i, j ) -> swapCell( sources, i, j ),
( i, j ) -> swapCell( targets, i, j ) );
System.out.println( Arrays.toString( indexes ) );
System.out.println( Arrays.toString( sources ) );
System.out.println( Arrays.toString( targets ) );
}
[0, 2, 5, 8]
[how, are, you, today]
[I, am, fine, thanks]
This solution does not required (much) more memory than the one already used since no additional array or Collection are required.
The use of BiConsumer<>... provide a generic solution, this could also accept an Object[]... but this would not work for primitives array anymore. This have a slight performance lost of course, so based on the need, this can be removed.
Creation of a complete solution, first let's define an interface that will be used as a factory as well :
interface Sorter {
void sort(int[] array, BiConsumer<Integer, Integer>... actions);
static void sortArrays(int[] array, BiConsumer<Integer, Integer>... actions){
// call the implemented Sorter
}
}
Then, implement a simple Selection sorterr with the same logic as before, for each permutation in the original array, we execute the BiConsumer:
class SelectionSorter implements Sorter {
public void sort(int[] array, BiConsumer<Integer, Integer>... actions) {
int index;
int value;
int tmp;
for (int i = 0, length = array.length; i < length; ++i) {
index = i;
value = array[i];
for (int j = i + 1; j < length; ++j) {
if (value > array[j]) {
index = j;
value = array[j];
}
}
if (index != i) {
tmp = array[i];
array[i] = array[index];
array[index] = tmp;
// Swap the other arrays
for (BiConsumer<Integer, Integer> cons : actions) {
cons.accept(i, index);
}
}
}
}
}
Let also create a Bubble sorter :
class BubbleSorter implements Sorter {
public void sort(int[] array, BiConsumer<Integer, Integer>... actions) {
int tmp;
boolean swapped;
do {
swapped = false;
for (int i = 1, length = array.length; i < length; ++i) {
if (array[i - 1] > array[i]) {
tmp = array[i];
array[i] = array[i - 1];
array[i - 1] = tmp;
// Swap the other arrays
for (BiConsumer<Integer, Integer> cons : actions) {
cons.accept(i, i - 1);
}
swapped = true;
}
}
} while (swapped);
}
}
Now, we can simple call one or the other based on a simple condition, the length :
static void sortArrays(int[] array, BiConsumer<Integer, Integer>... actions){
if(array.length < 1000){
new BubbleSorter().sort(array, actions);
} else {
new SelectionSorter().sort(array, actions);
}
}
That way, we can call our sorter simply with
Sorter.sortArrays(indexes,
(i, j) -> swapCell(sources, i, j),
(i, j) -> swapCell(targets, i, j)
);
Complete test case on ideone (limit on size because of the time out)
I wonder if my approach is valid.
public class rakesh{
public static void sort_myClass(myClass myClasses[]){
for(int i=0; i<myClasses.length; i++){
for(int j=0; j<myClasses.length-i-1; j++){
if(myClasses[j].x >myClasses[j+1].x){
myClass temp_myClass = new myClass(myClasses[j+1]);
myClasses[j+1] = new myClass(myClasses[j]);
myClasses[j] = new myClass(temp_myClass);
}
}
}
}
public static class myClass{
int x;
String source;
String target;
myClass(int x,String source,String target){
this.x = x;
this.source = source;
this.target = target;
}
myClass(myClass super_myClass){
this.x = super_myClass.x;
this.source = super_myClass.source;
this.target = super_myClass.target;
}
}
public static void main(String args[]) {
myClass myClass1 = new myClass(0,"how","I");
myClass myClass2 = new myClass(2,"are","am");
myClass myClass3 = new myClass(8,"today","thanks");
myClass myClass4 = new myClass(5,"you","fine");
myClass[] myClasses = {myClass1, myClass2, myClass3, myClass4};
sort_myClass(myClasses);
for(myClass myClass_dummy : myClasses){
System.out.print(myClass_dummy.x + " ");
}
System.out.print("\n");
for(myClass myClass_dummy : myClasses){
System.out.print(myClass_dummy.source + " ");
}
System.out.print("\n");
for(myClass myClass_dummy : myClasses){
System.out.print(myClass_dummy.target + " ");
}
}
}
If you find any error or have suggestions then please leave a comment so I could make any necessary edits.
Output
0 2 5 8
how are you today
I am fine thanks
Process finished with exit code 0
without assign values in class, you can achieve it with following code:
Integer[] indexes = new Integer[]{0,2,8,5};
String[] sources = new String[]{"how", "are", "today", "you"};
String[] targets = new String[]{"I", "am", "thanks", "fine"};
Integer[] sortedArrya = Arrays.copyOf(indexes, indexes.length);
Arrays.sort(sortedArrya);
String[] sortedSourses = new String[sources.length];
String[] sortedTargets = new String[targets.length];
for (int i = 0; i < sortedArrya.length; i++) {
int intValus = sortedArrya[i];
int inx = Arrays.asList(indexes).indexOf(intValus);
sortedSourses[i] = sources[+inx];
sortedTargets[i] = targets[+inx];
}
System.out.println(sortedArrya);
System.out.println(sortedSourses);
System.out.println(sortedTargets);
I have an other solution for your question:
private void reOrder(int[] indexes, String[] sources, String[] targets){
int[] reIndexs = new int[indexes.length]; // contain index of item from MIN to MAX
String[] reSources = new String[indexes.length]; // array sources after re-order follow reIndexs
String[] reTargets = new String[indexes.length]; // array targets after re-order follow reIndexs
for (int i=0; i < (indexes.length - 1); i++){
if (i == (indexes.length - 2)){
if (indexes[i] > indexes[i+1]){
reIndexs[i] = i+1;
reIndexs[i+1] = i;
}else
{
reIndexs[i] = i;
reIndexs[i+1] = i+1;
}
}else
{
for (int j=(i+1); j < indexes.length; j++){
if (indexes[i] > indexes[j]){
reIndexs[i] = j;
}else {
reIndexs[i] = i;
}
}
}
}
// Re-order sources array and targets array
for (int index = 0; index < reIndexs.length; index++){
reSources[index] = sources[reIndexs[index]];
reTargets[index] = targets[reIndexs[index]];
}
// Print to view result
System.out.println( Arrays.toString(reIndexs));
System.out.println( Arrays.toString(reSources));
System.out.println( Arrays.toString(reTargets));
}
You can also achieve in your way too.
Here I created an ArrayList myArr and sorted Based on index value and then converted back to the array if you satisfied with ArrayList just you can remove the conversion or you want Array this one be helpful.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
public class StackOverflow {
public static void main(String[] args) {
int[] indexes = new int[]{0,2,8,5};
String[] sources = new String[]{"how", "are", "today", "you"};
String[] targets = new String[]{"I", "am", "thanks", "fine"};
ArrayList<myClass> myArr=new ArrayList<>();
for(int i=0;i<indexes.length;i++) {
myArr.add(new myClass(indexes[i], sources[i], targets[i]));
}
//Collections.sort(myArr,new compareIndex());
// Just for readability of code
Collections.sort(myArr, (mC1, mC2) -> mC1.getX() - mC2.getX());
//Conversion Part
for (int i=0;i<myArr.size();i++){
indexes[i]=myArr.get(i).getX();
sources[i]=myArr.get(i).getSource();
targets[i]=myArr.get(i).getTarget();
}
System.out.println(Arrays.toString(indexes));
System.out.println(Arrays.toString(sources));
System.out.println(Arrays.toString(targets));
}
}
class myClass {
private Integer x;
private String source;
private String target;
public myClass(Integer x,String source,String target){
this.x=x;
this.source=source;
this.target=target;
}
public Integer getX() {
return x;
}
public String getSource() {
return source;
}
public String getTarget() {
return target;
}
}

Get MIN and MAX from an array and remove them for Java [duplicate]

It's trivial to write a function to determine the min/max value in an array, such as:
/**
*
* #param chars
* #return the max value in the array of chars
*/
private static int maxValue(char[] chars) {
int max = chars[0];
for (int ktr = 0; ktr < chars.length; ktr++) {
if (chars[ktr] > max) {
max = chars[ktr];
}
}
return max;
}
but isn't this already done somewhere?
Using Commons Lang (to convert) + Collections (to min/max)
import java.util.Arrays;
import java.util.Collections;
import org.apache.commons.lang.ArrayUtils;
public class MinMaxValue {
public static void main(String[] args) {
char[] a = {'3', '5', '1', '4', '2'};
List b = Arrays.asList(ArrayUtils.toObject(a));
System.out.println(Collections.min(b));
System.out.println(Collections.max(b));
}
}
Note that Arrays.asList() wraps the underlying array, so it should not be too memory intensive and it should not perform a copy on the elements of the array.
You can simply use the new Java 8 Streams but you have to work with int.
The stream method of the utility class Arrays gives you an IntStream on which you can use the min method. You can also do max, sum, average,...
The getAsInt method is used to get the value from the OptionalInt
import java.util.Arrays;
public class Test {
public static void main(String[] args){
int[] tab = {12, 1, 21, 8};
int min = Arrays.stream(tab).min().getAsInt();
int max = Arrays.stream(tab).max().getAsInt();
System.out.println("Min = " + min);
System.out.println("Max = " + max)
}
}
==UPDATE==
If execution time is important and you want to go through the data only once you can use the summaryStatistics() method like this
import java.util.Arrays;
import java.util.IntSummaryStatistics;
public class SOTest {
public static void main(String[] args){
int[] tab = {12, 1, 21, 8};
IntSummaryStatistics stat = Arrays.stream(tab).summaryStatistics();
int min = stat.getMin();
int max = stat.getMax();
System.out.println("Min = " + min);
System.out.println("Max = " + max);
}
}
This approach can give better performance than classical loop because the summaryStatistics method is a reduction operation and it allows parallelization.
The Google Guava library has min and max methods in its Chars, Ints, Longs, etc. classes.
So you can simply use:
Chars.min(myarray)
No conversions are required and presumably it's efficiently implemented.
By sorting the array, you get the first and last values for min / max.
import java.util.Arrays;
public class apples {
public static void main(String[] args) {
int a[] = {2,5,3,7,8};
Arrays.sort(a);
int min =a[0];
System.out.println(min);
int max= a[a.length-1];
System.out.println(max);
}
}
Although the sorting operation is more expensive than simply finding min/max values with a simple loop. But when performance is not a concern (e.g. small arrays, or your the cost is irrelevant for your application), it is a quite simple solution.
Note: the array also gets modified after this.
Yes, it's done in the Collections class. Note that you will need to convert your primitive char array to a Character[] manually.
A short demo:
import java.util.*;
public class Main {
public static Character[] convert(char[] chars) {
Character[] copy = new Character[chars.length];
for(int i = 0; i < copy.length; i++) {
copy[i] = Character.valueOf(chars[i]);
}
return copy;
}
public static void main(String[] args) {
char[] a = {'3', '5', '1', '4', '2'};
Character[] b = convert(a);
System.out.println(Collections.max(Arrays.asList(b)));
}
}
I have a little helper class in all of my applications with methods like:
public static double arrayMax(double[] arr) {
double max = Double.NEGATIVE_INFINITY;
for(double cur: arr)
max = Math.max(max, cur);
return max;
}
You could easily do it with an IntStream and the max() method.
Example
public static int maxValue(final int[] intArray) {
return IntStream.range(0, intArray.length).map(i -> intArray[i]).max().getAsInt();
}
Explanation
range(0, intArray.length) - To get a stream with as many elements as present in the intArray.
map(i -> intArray[i]) - Map every element of the stream to an actual element of the intArray.
max() - Get the maximum element of this stream as OptionalInt.
getAsInt() - Unwrap the OptionalInt. (You could also use here: orElse(0), just in case the OptionalInt is empty.)
public int getMin(int[] values){
int ret = values[0];
for(int i = 1; i < values.length; i++)
ret = Math.min(ret,values[i]);
return ret;
}
import java.util.Random;
public class Main {
public static void main(String[] args) {
int a[] = new int [100];
Random rnd = new Random ();
for (int i = 0; i< a.length; i++) {
a[i] = rnd.nextInt(99-0)+0;
System.out.println(a[i]);
}
int max = 0;
for (int i = 0; i < a.length; i++) {
a[i] = max;
for (int j = i+1; j<a.length; j++) {
if (a[j] > max) {
max = a[j];
}
}
}
System.out.println("Max element: " + max);
}
}
A solution with reduce():
int[] array = {23, 3, 56, 97, 42};
// directly print out
Arrays.stream(array).reduce((x, y) -> x > y ? x : y).ifPresent(System.out::println);
// get the result as an int
int res = Arrays.stream(array).reduce((x, y) -> x > y ? x : y).getAsInt();
System.out.println(res);
>>
97
97
In the code above, reduce() returns data in Optional format, which you can convert to int by getAsInt().
If we want to compare the max value with a certain number, we can set a start value in reduce():
int[] array = {23, 3, 56, 97, 42};
// e.g., compare with 100
int max = Arrays.stream(array).reduce(100, (x, y) -> x > y ? x : y);
System.out.println(max);
>>
100
In the code above, when reduce() with an identity (start value) as the first parameter, it returns data in the same format with the identity. With this property, we can apply this solution to other arrays:
double[] array = {23.1, 3, 56.6, 97, 42};
double max = Arrays.stream(array).reduce(array[0], (x, y) -> x > y ? x : y);
System.out.println(max);
>>
97.0
Here's a utility class providing min/max methods for primitive types: Primitives.java
int [] numbers= {10,1,8,7,6,5,2};
int a=Integer.MAX_VALUE;
for(int c:numbers) {
a=c<a?c:a;
}
System.out.println("Lowest value is"+a);
Example with float:
public static float getMaxFloat(float[] data) {
float[] copy = Arrays.copyOf(data, data.length);
Arrays.sort(copy);
return copy[data.length - 1];
}
public static float getMinFloat(float[] data) {
float[] copy = Arrays.copyOf(data, data.length);
Arrays.sort(copy);
return copy[0];
}
Pass the array to a method that sorts it with Arrays.sort() so it only sorts the array the method is using then sets min to array[0] and max to array[array.length-1].
The basic way to get the min/max value of an Array. If you need the unsorted array, you may create a copy or pass it to a method that returns the min or max. If not, sorted array is better since it performs faster in some cases.
public class MinMaxValueOfArray {
public static void main(String[] args) {
int[] A = {2, 4, 3, 5, 5};
Arrays.sort(A);
int min = A[0];
int max = A[A.length -1];
System.out.println("Min Value = " + min);
System.out.println("Max Value = " + max);
}
}
Here is a solution to get the max value in about 99% of runs (change the 0.01 to get a better result):
public static double getMax(double[] vals){
final double[] max = {Double.NEGATIVE_INFINITY};
IntStream.of(new Random().ints((int) Math.ceil(Math.log(0.01) / Math.log(1.0 - (1.0/vals.length))),0,vals.length).toArray())
.forEach(r -> max[0] = (max[0] < vals[r])? vals[r]: max[0]);
return max[0];
}
(Not completely serious)
int[] arr = {1, 2, 3};
List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList());
int max_ = Collections.max(list);
int i;
if (max_ > 0) {
for (i = 1; i < Collections.max(list); i++) {
if (!list.contains(i)) {
System.out.println(i);
break;
}
}
if(i==max_){
System.out.println(i+1);
}
} else {
System.out.println("1");
}
}

add an element to int [] array in java [duplicate]

This question already has answers here:
How to add new elements to an array?
(19 answers)
Closed 6 years ago.
Want to add or append elements to existing array
int[] series = {4,2};
now i want to update the series dynamically with new values i send..
like if i send 3 update series as int[] series = {4,2,3};
again if i send 4 update series as int[] series = {4,2,3,4};
again if i send 1 update series as int[] series = {4,2,3,4,1}; so on
How to do it????
I generate an integer every 5 minutes in some other function and want to send to update the int[] series array..
The length of an array is immutable in java. This means you can't change the size of an array once you have created it. If you initialised it with 2 elements, its length is 2. You can however use a different collection.
List<Integer> myList = new ArrayList<Integer>();
myList.add(5);
myList.add(7);
And with a wrapper method
public void addMember(Integer x) {
myList.add(x);
};
try this
public static void main(String[] args) {
int[] series = {4,2};
series = addElement(series, 3);
series = addElement(series, 1);
}
static int[] addElement(int[] a, int e) {
a = Arrays.copyOf(a, a.length + 1);
a[a.length - 1] = e;
return a;
}
If you are generating an integer every 5 minutes, better to use collection. You can always get array out of it, if required in your code.
Else define the array big enough to handle all your values at runtime (not preferred though.)
You'll need to create a new array if you want to add an index.
Try this:
public static void main(String[] args) {
int[] series = new int[0];
int x = 5;
series = addInt(series, x);
//print out the array with commas as delimiters
System.out.print("New series: ");
for (int i = 0; i < series.length; i++){
if (i == series.length - 1){
System.out.println(series[i]);
}
else{
System.out.print(series[i] + ", ");
}
}
}
// here, create a method
public static int[] addInt(int [] series, int newInt){
//create a new array with extra index
int[] newSeries = new int[series.length + 1];
//copy the integers from series to newSeries
for (int i = 0; i < series.length; i++){
newSeries[i] = series[i];
}
//add the new integer to the last index
newSeries[newSeries.length - 1] = newInt;
return newSeries;
}
Like others suggested you are better off using collection. If you however for some reason must stick to array then Apache Commons ArrayUtils may help:
int[] series = {4,2};
series = ArrayUtils.add(series, 3); // series is now {4,2,3}
series = ArrayUtils.add(series, 4); // series is now {4,2,3,4};
Note that the add method creates a new array, copies the given array and appends the new element at the end, which may have impact on performance.
You could also try this.
public static int[] addOneIntToArray(int[] initialArray , int newValue) {
int[] newArray = new int[initialArray.length + 1];
for (int index = 0; index < initialArray.length; index++) {
newArray[index] = initialArray[index];
}
newArray[newArray.length - 1] = newValue;
return newArray;
}
The size of an array can't be changed. If you want a bigger array you have to create a new array.
However, a better solution would be to use an (Array)List which can grow as you need it. The method ArrayList.toArray(T[] a) returns an array if you need to use an array in your application.
public int[] return_Array() {
int[] a =new int[10];
int b = 25;
for(int i=0; i<10; i++) {
a[i] = b * i;
}
return a;
}
import java.util.Arrays;
public class NumberArray {
public static void main(String []args){
int[] series = {4,2};
int[] newSeries = putNumberInSeries(1,series);
System.out.println(series==newSeries);//return false. you won't get the same int[] object. But functionality achieved.
}
private static int[] putNumberInSeries(int i, int[] series) {
int[] localSeries = Arrays.copyOf(series, series.length+1);
localSeries[series.length] = i;
System.out.println(localSeries);
return localSeries;
}
}
The ... can only be used in JDK 1.5 or later. If you are using JDK 4 or lower, use this code:'
public static int[] addElement(int[] original, int newelement) {
int[] nEw = new int[original.length + 1];
System.arraycopy(original, 0, nEw, 0, original.length);
nEw[original.length] = newelement;
}
otherwise (JDK 5 or higher):
public static int[] addElement(int[] original, int... elements) { // This can add multiple elements at once; addElement(int[], int) will still work though.
int[] nEw = new int[original.length + elements.length];
System.arraycopy(original, 0, nEw, 0, original.length);
System.arraycopy(elements, 0, nEw, original.length, elements.length);
return nEw;
}
Of course, as many have mentioned above, you could use a Collection or an ArrayList, which allows you to use the .add() method.
class AddElement {
public static void main(String s[]) {
int arr[] ={2,3};
int add[] = new int[arr.length+1];
for(int i=0;i<add.length;i++){
if(i==add.length-1){
add[i]=4;
}else{
add[i]=arr[i];
}
System.out.println(add[i]);
}
}
}
This works for me:
int[] list = new int[maximum];
for (int i = 0; i < maximum; i++{
list[i] = put_input_here;
}
This way, it's simple, yet efficient.
similar to Evgeniy:
int[] series = {4,2};
add_element(3);
add_element(4);
add_element(1);
public void add_element(int element){
series = Arrays.copyOf(series, series.length +1);
series[series.length - 1] = element;
}
int[] oldArray = {1,2,3,4,5};
//new value
int newValue = 10;
//define the new array
int[] newArray = new int[oldArray.length + 1];
//copy values into new array
for(int i=0;i < oldArray.length;i++)
newArray[i] = oldArray[i];
//another solution is to use
//System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
//add new value to the new array
newArray[newArray.length-1] = newValue;
//copy the address to the old reference
//the old array values will be deleted by the Garbage Collector
oldArray = newArray;

Finding the max/min value in an array of primitives using Java

It's trivial to write a function to determine the min/max value in an array, such as:
/**
*
* #param chars
* #return the max value in the array of chars
*/
private static int maxValue(char[] chars) {
int max = chars[0];
for (int ktr = 0; ktr < chars.length; ktr++) {
if (chars[ktr] > max) {
max = chars[ktr];
}
}
return max;
}
but isn't this already done somewhere?
Using Commons Lang (to convert) + Collections (to min/max)
import java.util.Arrays;
import java.util.Collections;
import org.apache.commons.lang.ArrayUtils;
public class MinMaxValue {
public static void main(String[] args) {
char[] a = {'3', '5', '1', '4', '2'};
List b = Arrays.asList(ArrayUtils.toObject(a));
System.out.println(Collections.min(b));
System.out.println(Collections.max(b));
}
}
Note that Arrays.asList() wraps the underlying array, so it should not be too memory intensive and it should not perform a copy on the elements of the array.
You can simply use the new Java 8 Streams but you have to work with int.
The stream method of the utility class Arrays gives you an IntStream on which you can use the min method. You can also do max, sum, average,...
The getAsInt method is used to get the value from the OptionalInt
import java.util.Arrays;
public class Test {
public static void main(String[] args){
int[] tab = {12, 1, 21, 8};
int min = Arrays.stream(tab).min().getAsInt();
int max = Arrays.stream(tab).max().getAsInt();
System.out.println("Min = " + min);
System.out.println("Max = " + max)
}
}
==UPDATE==
If execution time is important and you want to go through the data only once you can use the summaryStatistics() method like this
import java.util.Arrays;
import java.util.IntSummaryStatistics;
public class SOTest {
public static void main(String[] args){
int[] tab = {12, 1, 21, 8};
IntSummaryStatistics stat = Arrays.stream(tab).summaryStatistics();
int min = stat.getMin();
int max = stat.getMax();
System.out.println("Min = " + min);
System.out.println("Max = " + max);
}
}
This approach can give better performance than classical loop because the summaryStatistics method is a reduction operation and it allows parallelization.
The Google Guava library has min and max methods in its Chars, Ints, Longs, etc. classes.
So you can simply use:
Chars.min(myarray)
No conversions are required and presumably it's efficiently implemented.
By sorting the array, you get the first and last values for min / max.
import java.util.Arrays;
public class apples {
public static void main(String[] args) {
int a[] = {2,5,3,7,8};
Arrays.sort(a);
int min =a[0];
System.out.println(min);
int max= a[a.length-1];
System.out.println(max);
}
}
Although the sorting operation is more expensive than simply finding min/max values with a simple loop. But when performance is not a concern (e.g. small arrays, or your the cost is irrelevant for your application), it is a quite simple solution.
Note: the array also gets modified after this.
Yes, it's done in the Collections class. Note that you will need to convert your primitive char array to a Character[] manually.
A short demo:
import java.util.*;
public class Main {
public static Character[] convert(char[] chars) {
Character[] copy = new Character[chars.length];
for(int i = 0; i < copy.length; i++) {
copy[i] = Character.valueOf(chars[i]);
}
return copy;
}
public static void main(String[] args) {
char[] a = {'3', '5', '1', '4', '2'};
Character[] b = convert(a);
System.out.println(Collections.max(Arrays.asList(b)));
}
}
I have a little helper class in all of my applications with methods like:
public static double arrayMax(double[] arr) {
double max = Double.NEGATIVE_INFINITY;
for(double cur: arr)
max = Math.max(max, cur);
return max;
}
You could easily do it with an IntStream and the max() method.
Example
public static int maxValue(final int[] intArray) {
return IntStream.range(0, intArray.length).map(i -> intArray[i]).max().getAsInt();
}
Explanation
range(0, intArray.length) - To get a stream with as many elements as present in the intArray.
map(i -> intArray[i]) - Map every element of the stream to an actual element of the intArray.
max() - Get the maximum element of this stream as OptionalInt.
getAsInt() - Unwrap the OptionalInt. (You could also use here: orElse(0), just in case the OptionalInt is empty.)
public int getMin(int[] values){
int ret = values[0];
for(int i = 1; i < values.length; i++)
ret = Math.min(ret,values[i]);
return ret;
}
import java.util.Random;
public class Main {
public static void main(String[] args) {
int a[] = new int [100];
Random rnd = new Random ();
for (int i = 0; i< a.length; i++) {
a[i] = rnd.nextInt(99-0)+0;
System.out.println(a[i]);
}
int max = 0;
for (int i = 0; i < a.length; i++) {
a[i] = max;
for (int j = i+1; j<a.length; j++) {
if (a[j] > max) {
max = a[j];
}
}
}
System.out.println("Max element: " + max);
}
}
A solution with reduce():
int[] array = {23, 3, 56, 97, 42};
// directly print out
Arrays.stream(array).reduce((x, y) -> x > y ? x : y).ifPresent(System.out::println);
// get the result as an int
int res = Arrays.stream(array).reduce((x, y) -> x > y ? x : y).getAsInt();
System.out.println(res);
>>
97
97
In the code above, reduce() returns data in Optional format, which you can convert to int by getAsInt().
If we want to compare the max value with a certain number, we can set a start value in reduce():
int[] array = {23, 3, 56, 97, 42};
// e.g., compare with 100
int max = Arrays.stream(array).reduce(100, (x, y) -> x > y ? x : y);
System.out.println(max);
>>
100
In the code above, when reduce() with an identity (start value) as the first parameter, it returns data in the same format with the identity. With this property, we can apply this solution to other arrays:
double[] array = {23.1, 3, 56.6, 97, 42};
double max = Arrays.stream(array).reduce(array[0], (x, y) -> x > y ? x : y);
System.out.println(max);
>>
97.0
Here's a utility class providing min/max methods for primitive types: Primitives.java
int [] numbers= {10,1,8,7,6,5,2};
int a=Integer.MAX_VALUE;
for(int c:numbers) {
a=c<a?c:a;
}
System.out.println("Lowest value is"+a);
Example with float:
public static float getMaxFloat(float[] data) {
float[] copy = Arrays.copyOf(data, data.length);
Arrays.sort(copy);
return copy[data.length - 1];
}
public static float getMinFloat(float[] data) {
float[] copy = Arrays.copyOf(data, data.length);
Arrays.sort(copy);
return copy[0];
}
Pass the array to a method that sorts it with Arrays.sort() so it only sorts the array the method is using then sets min to array[0] and max to array[array.length-1].
The basic way to get the min/max value of an Array. If you need the unsorted array, you may create a copy or pass it to a method that returns the min or max. If not, sorted array is better since it performs faster in some cases.
public class MinMaxValueOfArray {
public static void main(String[] args) {
int[] A = {2, 4, 3, 5, 5};
Arrays.sort(A);
int min = A[0];
int max = A[A.length -1];
System.out.println("Min Value = " + min);
System.out.println("Max Value = " + max);
}
}
Here is a solution to get the max value in about 99% of runs (change the 0.01 to get a better result):
public static double getMax(double[] vals){
final double[] max = {Double.NEGATIVE_INFINITY};
IntStream.of(new Random().ints((int) Math.ceil(Math.log(0.01) / Math.log(1.0 - (1.0/vals.length))),0,vals.length).toArray())
.forEach(r -> max[0] = (max[0] < vals[r])? vals[r]: max[0]);
return max[0];
}
(Not completely serious)
int[] arr = {1, 2, 3};
List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList());
int max_ = Collections.max(list);
int i;
if (max_ > 0) {
for (i = 1; i < Collections.max(list); i++) {
if (!list.contains(i)) {
System.out.println(i);
break;
}
}
if(i==max_){
System.out.println(i+1);
}
} else {
System.out.println("1");
}
}

Categories

Resources