I'm trying to make a program that consists of an array of 10 integers which all has a random value, so far so good.
However, now I need to sort them in order from lowest to highest value and then print it onto the screen, how would I go about doing so?
(Sorry for having so much code for a program that small, I ain't that good with loops, just started working with Java)
public static void main(String args[])
{
int [] array = new int[10];
array[0] = ((int)(Math.random()*100+1));
array[1] = ((int)(Math.random()*100+1));
array[2] = ((int)(Math.random()*100+1));
array[3] = ((int)(Math.random()*100+1));
array[4] = ((int)(Math.random()*100+1));
array[5] = ((int)(Math.random()*100+1));
array[6] = ((int)(Math.random()*100+1));
array[7] = ((int)(Math.random()*100+1));
array[8] = ((int)(Math.random()*100+1));
array[9] = ((int)(Math.random()*100+1));
System.out.println(array[0] +" " + array[1] +" " + array[2] +" " + array[3]
+" " + array[4] +" " + array[5]+" " + array[6]+" " + array[7]+" "
+ array[8]+" " + array[9] );
}
Loops are also very useful to learn about, esp When using arrays,
int[] array = new int[10];
Random rand = new Random();
for (int i = 0; i < array.length; i++)
array[i] = rand.nextInt(100) + 1;
Arrays.sort(array);
System.out.println(Arrays.toString(array));
// in reverse order
for (int i = array.length - 1; i >= 0; i--)
System.out.print(array[i] + " ");
System.out.println();
Add the Line before println and your array gets sorted
Arrays.sort( array );
It may help you understand loops by implementing yourself. See Bubble sort is easy to understand:
public void bubbleSort(int[] array) {
boolean swapped = true;
int j = 0;
int tmp;
while (swapped) {
swapped = false;
j++;
for (int i = 0; i < array.length - j; i++) {
if (array[i] > array[i + 1]) {
tmp = array[i];
array[i] = array[i + 1];
array[i + 1] = tmp;
swapped = true;
}
}
}
}
Of course, you should not use it in production as there are better performing algorithms for large lists such as QuickSort or MergeSort which are implemented by Arrays.sort(array)
Take a look at Arrays.sort()
I was lazy and added the loops
import java.util.Arrays;
public class Sort {
public static void main(String args[])
{
int [] array = new int[10];
for ( int i = 0 ; i < array.length ; i++ ) {
array[i] = ((int)(Math.random()*100+1));
}
Arrays.sort( array );
for ( int i = 0 ; i < array.length ; i++ ) {
System.out.println(array[i]);
}
}
}
Your array has a length of 10. You need one variable (i) which takes the values from 0to 9.
for ( int i = 0 ; i < array.length ; i++ )
^ ^ ^
| | ------ increment ( i = i + 1 )
| |
| +-------------------------- repeat as long i < 10
+------------------------------------------ start value of i
Arrays.sort( array );
Is a library methods that sorts arrays.
Arrays.sort(yourArray)
will do the job perfectly
For natural order : Arrays.sort(array)
For reverse Order : Arrays.sort(array, Collections.reverseOrder()); -- > It is a static method in Collections class which will further call an inner class of itself to return a reverse Comparator.
You can sort a int array with Arrays.sort( array ).
See below, it will give you sorted ascending and descending both
import java.util.Arrays;
import java.util.Collections;
public class SortTestArray {
/**
* Example method for sorting an Integer array
* in reverse & normal order.
*/
public void sortIntArrayReverseOrder() {
Integer[] arrayToSort = new Integer[] {
new Integer(48),
new Integer(5),
new Integer(89),
new Integer(80),
new Integer(81),
new Integer(23),
new Integer(45),
new Integer(16),
new Integer(2)
};
System.out.print("General Order is : ");
for (Integer i : arrayToSort) {
System.out.print(i.intValue() + " ");
}
Arrays.sort(arrayToSort);
System.out.print("\n\nAscending Order is : ");
for (Integer i : arrayToSort) {
System.out.print(i.intValue() + " ");
}
Arrays.sort(arrayToSort, Collections.reverseOrder());
System.out.print("\n\nDescinding Order is : ");
for (Integer i : arrayToSort) {
System.out.print(i.intValue() + " ");
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
SortTestArray SortTestArray = new SortTestArray();
SortTestArray.sortIntArrayReverseOrder();
}}
Output will be
General Order is : 48 5 89 80 81 23 45 16 2
Ascending Order is : 2 5 16 23 45 48 80 81 89
Descinding Order is : 89 81 80 48 45 23 16 5 2
Note: You can use Math.ranodm instead of adding manual numbers. Let me know if I need to change the code...
Good Luck... Cheers!!!
int[] array = {2, 3, 4, 5, 3, 4, 2, 34, 2, 56, 98, 32, 54};
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[i] < array[j]) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
Here is how to use this in your program:
public static void main(String args[])
{
int [] array = new int[10];
array[0] = ((int)(Math.random()*100+1));
array[1] = ((int)(Math.random()*100+1));
array[2] = ((int)(Math.random()*100+1));
array[3] = ((int)(Math.random()*100+1));
array[4] = ((int)(Math.random()*100+1));
array[5] = ((int)(Math.random()*100+1));
array[6] = ((int)(Math.random()*100+1));
array[7] = ((int)(Math.random()*100+1));
array[8] = ((int)(Math.random()*100+1));
array[9] = ((int)(Math.random()*100+1));
Arrays.sort(array);
System.out.println(array[0] +" " + array[1] +" " + array[2] +" " + array[3]
+" " + array[4] +" " + array[5]+" " + array[6]+" " + array[7]+" "
+ array[8]+" " + array[9] );
}
just FYI, you can now use Java 8 new API for sorting any type of array using parallelSort
parallelSort uses Fork/Join framework introduced in Java 7 to assign the sorting tasks to multiple threads available in the thread pool.
the two methods that can be used to sort int array,
parallelSort(int[] a)
parallelSort(int[] a,int fromIndex,int toIndex)
Java 8 provides the option of using streams which can be used to sort int[] array as:
int[] sorted = Arrays.stream(array).sorted().toArray(); // option 1
Arrays.parallelSort(array); //option 2
As mentioned in doc for parallelSort :
The sorting algorithm is a parallel sort-merge that breaks the array
into sub-arrays that are themselves sorted and then merged. When the
sub-array length reaches a minimum granularity, the sub-array is
sorted using the appropriate Arrays.sort method. If the length of the
specified array is less than the minimum granularity, then it is
sorted using the appropriate Arrays.sort method. The algorithm
requires a working space no greater than the size of the original
array. The ForkJoin common pool is used to execute any parallel tasks.
So if the input array is less than granularity (8192 elements in Java 9 and 4096 in Java 8 I believe), then parallelSort simply calls sequential sort algorithm.
Just in case we want to reverse sort the integer array we can make use of comparator as:
int[] reverseSorted = IntStream.of(array).boxed()
.sorted(Comparator.reverseOrder()).mapToInt(i -> i).toArray();
Since Java has no way to sort primitives with custom comparator, we have to use intermediate boxing or some other third party library which implements such primitive sorting.
You may use Arrays.sort() function.
sort() method is a java.util.Arrays class method.
Declaration : Arrays.sort(arrName)
Simply do the following before printing the array:-
Arrays.sort(array);
Note:-
you will have to import the arrays class by saying:-
import java.util.Arrays;
If you want to build the Quick sort algorithm yourself and have more understanding of how it works check the below code :
1- Create sort class
class QuickSort {
private int input[];
private int length;
public void sort(int[] numbers) {
if (numbers == null || numbers.length == 0) {
return;
}
this.input = numbers;
length = numbers.length;
quickSort(0, length - 1);
}
/*
* This method implements in-place quicksort algorithm recursively.
*/
private void quickSort(int low, int high) {
int i = low;
int j = high;
// pivot is middle index
int pivot = input[low + (high - low) / 2];
// Divide into two arrays
while (i <= j) {
/**
* As shown in above image, In each iteration, we will identify a
* number from left side which is greater then the pivot value, and
* a number from right side which is less then the pivot value. Once
* search is complete, we can swap both numbers.
*/
while (input[i] < pivot) {
i++;
}
while (input[j] > pivot) {
j--;
}
if (i <= j) {
swap(i, j);
// move index to next position on both sides
i++;
j--;
}
}
// calls quickSort() method recursively
if (low < j) {
quickSort(low, j);
}
if (i < high) {
quickSort(i, high);
}
}
private void swap(int i, int j) {
int temp = input[i];
input[i] = input[j];
input[j] = temp;
}
}
2- Send your unsorted array to Quicksort class
import java.util.Arrays;
public class QuickSortDemo {
public static void main(String args[]) {
// unsorted integer array
int[] unsorted = {6, 5, 3, 1, 8, 7, 2, 4};
System.out.println("Unsorted array :" + Arrays.toString(unsorted));
QuickSort algorithm = new QuickSort();
// sorting integer array using quicksort algorithm
algorithm.sort(unsorted);
// printing sorted array
System.out.println("Sorted array :" + Arrays.toString(unsorted));
}
}
3- Output
Unsorted array :[6, 5, 3, 1, 8, 7, 2, 4]
Sorted array :[1, 2, 3, 4, 5, 6, 7, 8]
We can also use binary search tree for getting sorted array by using in-order traversal method. The code also has implementation of basic binary search tree below.
class Util {
public static void printInorder(Node node)
{
if (node == null) {
return;
}
/* traverse left child */
printInorder(node.left);
System.out.print(node.data + " ");
/* traverse right child */
printInorder(node.right);
}
public static void sort(ArrayList<Integer> al, Node node) {
if (node == null) {
return;
}
/* sort left child */
sort(al, node.left);
al.add(node.data);
/* sort right child */
sort(al, node.right);
}
}
class Node {
Node left;
Integer data;
Node right;
public Node(Integer data) {
this.data = data;
}
public void insert(Integer element) {
if(element.equals(data)) {
return;
}
// if element is less than current then we know we will insert element to left-sub-tree
if(element < data) {
// if this node does not have a sub tree then this is the place we insert the element.
if(this.left == null) {
this.left = new Node(element);
} else { // if it has left subtree then we should iterate again.
this.left.insert(element);
}
} else {
if(this.right == null) {
this.right = new Node(element);
} else {
this.right.insert(element);
}
}
}
}
class Tree {
Node root;
public void insert(Integer element) {
if(root == null) {
root = new Node(element);
} else {
root.insert(element);
}
}
public void print() {
Util.printInorder(root);
}
public ArrayList<Integer> sort() {
ArrayList<Integer> al = new ArrayList<Integer>();
Util.sort(al, root);
return al;
}
}
public class Test {
public static void main(String[] args) {
int [] array = new int[10];
array[0] = ((int)(Math.random()*100+1));
array[1] = ((int)(Math.random()*100+1));
array[2] = ((int)(Math.random()*100+1));
array[3] = ((int)(Math.random()*100+1));
array[4] = ((int)(Math.random()*100+1));
array[5] = ((int)(Math.random()*100+1));
array[6] = ((int)(Math.random()*100+1));
array[7] = ((int)(Math.random()*100+1));
array[8] = ((int)(Math.random()*100+1));
array[9] = ((int)(Math.random()*100+1));
Tree tree = new Tree();
for (int i = 0; i < array.length; i++) {
tree.insert(array[i]);
}
tree.print();
ArrayList<Integer> al = tree.sort();
System.out.println("sorted array : ");
al.forEach(item -> System.out.print(item + " "));
}
}
MOST EFFECTIVE WAY!
public static void main(String args[])
{
int [] array = new int[10];//creates an array named array to hold 10 int's
for(int x: array)//for-each loop!
x = ((int)(Math.random()*100+1));
Array.sort(array);
for(int x: array)
System.out.println(x+" ");
}
Be aware that Arrays.sort() method is not thread safe: if your array is a property of a singleton, and used in a multi-threaded enviroment, you should put the sorting code in a synchronized block, or create a copy of the array and order that copy (only the array structure is copied, using the same objects inside).
For example:
int[] array = new int[10];
...
int[] arrayCopy = Arrays.copyOf(array , array .length);
Arrays.sort(arrayCopy);
// use the arrayCopy;
Related
I have code for a MergeSort of generic arrays. The only problem is, that I want the output to be with the index instead of the actual int, float or whatever. Do you guys have any idea on how to do that?
Here is the code I have so far:
class MergeSortGeneric<T extends Comparable<? super T>> {
public static void main(String[] args)
{
// example using Strings
String[] arrayOfStrings = {"Andree", "Leana", "Faviola", "Loyce", "Quincy",
"Milo", "Jamila", "Toccara", "Nelda", "Blair", "Ernestine", "Chara", "Kareen", "Monty", "Rene",
"Cami", "Winifred", "Tara", "Demetrice", "Azucena"};
MergeSortGeneric<String> stringSorter = new MergeSortGeneric<>();
stringSorter.mergeSort(arrayOfStrings, 0, arrayOfStrings.length - 1);
System.out.println(java.util.Arrays.toString(arrayOfStrings));
// example using Doubles
Double[] arrayOfDoubles = {0.35, 0.02, 0.36, 0.82, 0.27, 0.49, 0.41, 0.17, 0.30,
0.89, 0.37, 0.66, 0.82, 0.17, 0.20, 0.96, 0.18, 0.25, 0.37, 0.52};
MergeSortGeneric<Double> doubleSorter = new MergeSortGeneric<>();
doubleSorter.mergeSort(arrayOfDoubles, 0, arrayOfDoubles.length - 1);
System.out.println(java.util.Arrays.toString(arrayOfDoubles));
}
// main function that sorts array[start..end] using merge()
void mergeSort(T[] array, int start, int end)
{
// base case
if (start < end)
{
// find the middle point
int middle = (start + end) / 2;
mergeSort(array, start, middle); // sort first half
mergeSort(array, middle + 1, end); // sort second half
// merge the sorted halves
merge(array, start, middle, end);
}
}
// merges two subarrays of array[].
void merge(T[] array, int start, int middle, int end)
{
T[] leftArray = (T[]) new Comparable[middle - start + 1];
T[] rightArray = (T[]) new Comparable[end - middle];
// fill in left array
for (int i = 0; i < leftArray.length; ++i)
leftArray[i] = array[start + i];
// fill in right array
for (int i = 0; i < rightArray.length; ++i)
rightArray[i] = array[middle + 1 + i];
/* Merge the temp arrays */
// initial indexes of first and second subarrays
int leftIndex = 0, rightIndex = 0;
// the index we will start at when adding the subarrays back into the main array
int currentIndex = start;
// compare each index of the subarrays adding the lowest value to the currentIndex
while (leftIndex < leftArray.length && rightIndex < rightArray.length)
{
if (leftArray[leftIndex].compareTo(rightArray[rightIndex]) <= 0)
{
array[currentIndex] = leftArray[leftIndex];
leftIndex++;
}
else
{
array[currentIndex] = rightArray[rightIndex];
rightIndex++;
}
currentIndex++;
}
// copy remaining elements of leftArray[] if any
while (leftIndex < leftArray.length) array[currentIndex++] = leftArray[leftIndex++];
// copy remaining elements of rightArray[] if any
while (rightIndex < rightArray.length) array[currentIndex++] = rightArray[rightIndex++];
}
}
thank you guys for any tips. Thats the task by the way:
Implement the Merge-Sort algorithm. The algorithm sorts a java.util.list
of any elements. Therefore the class must be generic. For sorting it gets a
matching comparator.
var data = Arrays.asList(23, 42, 11, 1, 12);
var mergeSort = new MergeSort<Integer>();
mergeSort.setup(data, (i1, i2) -> i1 - i2);
However, the element positions in the input list are not changed. Instead, the
specifies the sorting by a permutation array. The array has as many in-elements as
the input data list has elements. Each τ element specifies the index of the corresponding input element after sorting. Also internally you use only permutation arrays and no
further lists of input elements.
The easiest way without modifying the merge algorithm you be:
Create a copy of the arrays to be sorted;
Sort the arrays;
Compare the copy and the sorted array and figure it out the index.
For example:
String[] arrayOfStrings = {...};
List<String> copyArrayOfStrings = Arrays.stream(arrayOfStrings).collect(Collectors.toList());
...
stringSorter.mergeSort(arrayOfStrings, 0, arrayOfStrings.length - 1);
...
List<Integer> index = Arrays.stream(arrayOfStrings).map(copyArrayOfStrings::indexOf).collect(Collectors.toList());
System.out.println(java.util.Arrays.toString(index.toArray()));
If for some strange reason you can only use arrays, and basic operators, the aforementioned logic still holds true:
the copy:
String[] copyArrayOfStrings = new String[arrayOfStrings.length];
for(int i = 0; i < arrayOfStrings.length; i++){
copyArrayOfStrings[i] = arrayOfStrings[i];
}
the sorting:
stringSorter.mergeSort(arrayOfStrings, 0, arrayOfStrings.length - 1);
getting the indexes:
Integer[] index = new Integer[copyArrayOfStrings.length];
int index_pos = 0;
for(String s : arrayOfStrings) {
for (int i = 0; i < copyArrayOfStrings.length; i++) {
if(copyArrayOfStrings[i].equals(s)){
index[index_pos++] = i;
break;
}
}
}
System.out.println(java.util.Arrays.toString(index));
You can use a lambda compare, if the indexes are Integer types as opposed to native ints. Only the array of indices needs to be Integer type, the array of values can be primitive type.
package x;
import java.util.Arrays;
public class x {
public static void main(String[] args) {
int[] A = {3, 1, 2, 0};
Integer[] I = {0, 1, 2, 3};
Arrays.sort(I, (i, j) -> A[i]-A[j]);
for (Integer i : I) {
System.out.println(A[i]);
}
}
}
you can create a class like below (note it is pseudo code)
import java.util.Arrays;
public class SomeClass {
public static void main(String[] args) {
double[] doubleArray = new double[] {2.3, 3.4, 1.2, 0.3, 4.3};
ObjectWithIndex[] objectWithIndexAr = new ObjectWithIndex[doubleArray.length];
for (int i = 0; i < doubleArray.length; i++) {
objectWithIndexAr[i] = new ObjectWithIndex(i, doubleArray[i]);
}
Arrays.sort(objectWithIndexAr);
for ( ObjectWithIndex obj : objectWithIndexAr) {
System.out.println("index: " + obj.index + " value: " + obj.actualObject);
}
}
}
class ObjectWithIndex implements Comparable<ObjectWithIndex> {
int index;
Comparable actualObject;
public ObjectWithIndex(int index, Comparable object) {
this.index = index;
this.actualObject = object;
}
#Override
public int compareTo(ObjectWithIndex o) {
return this.actualObject.compareTo(o.actualObject);
}
}
you can create array of this object using your input array of Double, Integer (whatever implements Comparable) and sort the new array of ObjectWithIndex.
once sorted, you can print the index (which will have original index from your input)
Given an array of ints, I want to rearrange it alternately i.e. first element should be minimum, second should be maximum, third second-minimum, fourth second-maximum and so on...
I'm completely lost here...
Another method that doesn't require the space of three separate arrays but isn't as complex as reordering in place would be to sort the original array and then create a single new array. Then start iterating with a pointer to the current i-th index of the new array and pointers starting at the 0-th index and the last index of the sorted array.
public class Foo {
public static void main(String[] args) {
// Take your original array
int[] arr = { 1, 4, 5, 10, 6, 8, 3, 9 };
// Use the Arrays sort method to sort it into ascending order (note this mutates the array instance)
Arrays.sort(arr);
// Create a new array of the same length
int[] minMaxSorted = new int[arr.length];
// Iterate through the array (from the left and right at the same time)
for (int i = 0, min = 0, max = arr.length - 1; i < arr.length; i += 2, min++, max--) {
// the next minimum goes into minMaxSorted[i]
minMaxSorted[i] = arr[min];
// the next maximum goes into minMaxSorted[i + 1] ... but
// guard against index out of bounds for odd number arrays
if (i + 1 < minMaxSorted.length) {
minMaxSorted[i + 1] = arr[max];
}
}
System.out.println(Arrays.toString(minMaxSorted));
}
}
Hint:
Create two new arrays, 1st is sorted in assenting order and other is in descending order. Than select 1st element from 2nd array and 1st element from 1st array, repeat this selection until you reach half of both 1st and second array. and you will get your desired array.
Hope this will help you.
The approach in #Kaushal28's answer is the best approach for a beginner. It requires more space (2 extra copies of the array) but it is easy to understand and code.
An advanced programmer might consider sorting the array once, and then rearranging the elements. It should work, but the logic is complicated.
Hint: have you ever played "Clock Patience"?
This solution is based on Aaron Davis solution. I tried to make the looping easier to follow:
public class AltSort {
//list of array elements that were sorted
static Set<Integer> indexSorted = new HashSet<Integer>();
public static void main (String[] args) throws java.lang.Exception
{
//test case
int[] array = new int[]{7,22,4,67,5,11,-9,23,48, 3, 73, 1, 10};
System.out.println(Arrays.toString(altSort(array)));
//test case
array = new int[]{ 1, 4, 5, 10, 6, 8, 3, 9 };
System.out.println(Arrays.toString(altSort(array)));
}
private static int[] altSort(int[] array) {
if((array == null) || (array.length == 0)) {
System.err.println("Empty or null array can not be sorted.");
}
Arrays.sort(array);
//returned array
int[] sortedArray = new int[array.length];
int firstIndex = 0, lastIndex = array.length-1;
for (int i = 0; i < array.length; i++) {
if((i%2) == 0) { //even indices
sortedArray[i] = array[firstIndex++];
}
else {
sortedArray[i] = array[lastIndex --];
}
}
return sortedArray;
}
}
Here is another alternative: monitor the indices that have been sorted, and search the rest for the next min / max:
import java.util.Arrays;
import java.util.Set;
/**
* Demonstrates an option for sorting an int[] array as requested,
* by keeping a list of the array indices that has been sorted, and searching
* for the next min / max.
* This code is not optimal nor robust. It serves a demo for this option only.
*
*/
public class AltSort {
//list of array elements that were sorted
static Set<Integer> indexSorted ;
public static void main (String[] args) throws java.lang.Exception {
//test case
int[] array = new int[]{7,22,4,67,5,11,-9,23,48, 3, 73, 1, 10};
System.out.println(Arrays.toString(altSort2(array)));
//test case
array = new int[]{ 1, 4, 5, 10, 6, 8, 3, 9 };
System.out.println(Arrays.toString(altSort2(array)));
}
private static int[] altSort2(int[] array) {
if((array == null) || (array.length == 0)) {
System.err.println("Empty or null array can not be sorted.");
}
//returned array
int[] sortedArray = new int[array.length];
//flag indicating wether to look for min or max
boolean lookForMin = true;
int index = 0;
while(index < array.length) {
if(lookForMin) {
sortedArray[index] = lookForArrayMin(array);
}else {
sortedArray[index] = lookForArrayMax(array);
}
index++;
//alternate look for min / look for max
lookForMin = ! lookForMin;
}
return sortedArray;
}
private static int lookForArrayMin(int[] array) {
int minValue = Integer.MAX_VALUE;
int minValueIndex = 0;
for( int i =0; i< array.length; i++ ){
//if array[i] is min and was not sorted before, keep it as min
if( (array[i]< minValue) && ! indexSorted.contains(i) ) {
minValue = array[i]; //keep min
minValueIndex = i; //keep min index
}
}
//add the index to the list of sorted indices
indexSorted.add(minValueIndex);
return minValue;
}
private static int lookForArrayMax(int[] array) {
int maxValue = Integer.MIN_VALUE; //max value
int maxValueIndex = 0; //index of max value
for( int i =0; i< array.length; i++ ){
//if array[i] is max and was not sorted before, keep it as max
if( (array[i] > maxValue) && ! indexSorted.contains(i)) {
maxValue = array[i]; //keep max
maxValueIndex = i; //keep max index
}
}
//add the index to the list of sorted indices
indexSorted.add(maxValueIndex);
return maxValue;
}
}
I just had an online coding interview and one of the questions asked there is for a given array of integers, find out the number of pairs whose summation is equal to a certain number (passed as parameter inside the method ). For example an array is given as,
int[] a = {3, 2, 1, 45, 27, 6, 78, 9, 0};
int k = 9; // given number
So, there will be 2 pairs (3, 6) and (9, 0) whose sum is equal to 9. It's good to mention that how the pairs are formed doesn't matter. The means (3,6) and (6,3) will be considered as same pair. I provided the following solution (in Java) and curious to know if I missed any edge cases?
public static int numberOfPairs(int[] a, int k ){
int len = a.length;
if (len == 0){
return -1;
}
Arrays.sort(a);
int count = 0, left = 0, right = len -1;
while( left < right ){
if ( a[left] + a[right] == k ){
count++;
if (a[left] == a[left+1] && left < len-1 ){
left++;
}
if ( a[right] == a[right-1] && right >1 ){
right-- ;
}
right--; // right-- or left++, otherwise, will get struck in the while loop
}
else if ( a[left] + a[right] < k ){
left++;
}
else {
right--;
}
}
return count;
}
Besides, can anyone propose any alternative solution of the problem ? Thanks.
Following solution will return the number of unique pairs
public static int numberOfPairs(Integer[] array, int sum) {
Set<Integer> set = new HashSet<>(Arrays.asList(array));
// this set will keep track of the unique pairs.
Set<String> uniquePairs = new HashSet<String>();
for (int i : array) {
int x = sum - i;
if (set.contains(x)) {
int[] y = new int[] { x, i };
Arrays.sort(y);
uniquePairs.add(Arrays.toString(y));
}
}
//System.out.println(uniquePairs.size());
return uniquePairs.size();
}
The time complexity will be O(n).
Hope this helps.
You can use the HashMap<K,V> where K: a[i] and V: k-a[i]
This may result in an incorrect answer if there are duplicates in an array.
Say for instances:
int a[] = {4, 4, 4, 4, 4, 4, 4, 4, 4}
where k = 8 or:
int a[] = {1, 3, 3, 3, 3, 1, 2, 1, 2}
where k = 4.
So in order to avoid that, we can have a List<List<Integer>> , which can check each pair and see if it is already in the list.
static int numberOfPairs(int[] a, int k)
{
List<List<Integer>> res = new ArrayList<>();
Map<Integer, Integer> map = new HashMap<>();
for(int element:a)
{
List<Integer> list = new ArrayList<>();
if(map.containsKey(element))
{
list.add(element);
list.add(map.get(element));
if(!res.contains(list))
res.add(list);
}
else
map.put(k - element, element);
}
return res.size();
}
Your solution is overly complex, you can do this exercise in a much easier manner:
public static int numberOfPairs(int[] a, int k ){
int count=0;
List<Integer> dedup = new ArrayList<>(new HashSet<>(Arrays.asList(a)));
for (int x=0 ; x < dedup.size() ; x++ ){
for (int y=x+1 ; y < dedup.size() ; y++ ){
if (dedup.get(x)+dedup.get(y) == k)
count++;
}
}
return count;
}
The trick here is to have a loop starting after the first loop's index to not count the same values twice, and not compare it with your own index. Also, you can deduplicate the array to avoid duplicate pairs, since they don't matter.
You can also sort the list, then break the loop as soon as your sum goes above k, but that's optimization.
This code will give you count of the pairs that equals to given sum and as well as the pair of elements that equals to sum
private void pairofArrayElementsEqualstoGivenSum(int sum,Integer[] arr){
int count=0;
List numList = Arrays.asList(arr);
for (int i = 0; i < arr.length; i++) {
int num = sum - arr[i];
if (numList.contains(num)) {
count++;
System.out.println("" + arr[i] + " " + num + " = "+sum);
}
}
System.out.println("Total count of pairs "+count);
}
Given an array of integers and a target value, determine the number of pairs of array elements with a difference equal to a target value.
The function has the following parameters:
k: an integer, the target difference
arr: an array of integers
Using LINQ this is nice solution:
public static int CountNumberOfPairsWithDiff(int k, int[] arr)
{
var numbers = arr.Select((value) => new { value });
var pairs = from num1 in numbers
join num2 in numbers
on num1.value - k equals num2.value
select new[]
{
num1.value, // first number in the pair
num2.value, // second number in the pair
};
foreach (var pair in pairs)
{
Console.WriteLine("Pair found: " + pair[0] + ", " + pair[1]);
}
return pairs.Count();
}
This question already has answers here:
Algorithm to return all combinations of k elements from n
(77 answers)
Closed 9 years ago.
For example, I have an array ["Sam", "Mary", "John"].
I would like to display the combination of choose 2 out of 3.
The results should be:
[Sam, Mary]
[Sam, John]
[Mary, John]
I have researched a lot but still dun know how to do it.
Of course, this example only contain 3 people.
In fact, the number of total people will be larger, e.g. 15
Here is what I found:
Algorithm to return all combinations of k elements from n
What is a good way to implement choose notation in Java?
Some of them is only display the value of nCr, but not giving out the combination.
public static int width;
public static void main(String [] args){
String[] array = {"one", "two", "three", "four", "five"};
width = 3;
List<String> list = new ArrayList<String>();
for (int i = 0; i < array.length; i++){
method(array, list, i, 1, "[" + array[i]);
}
System.out.println(list);
}
public static void method(String[] array, List<String> list, int i, int depth, String string){
if (depth == width){
list.add(string + "]");
return;
}
for (int j = i+1; j < array.length; j++){
method(array, list, j, depth+1, string + ", " + array[j]);
}
}
Simple recursive function to print out combination(nCr) of a given string array (named array):
String[] array = {"Sam", "Mary", "John"};
public void function(int counter, String comb_Str, int r) {
if (r == 0) {
System.out.println(comb_Str);
} else {
for (; counter < array.length; ++counter) {
function(counter + 1, comb_Str + " " + array[counter], r - 1);
}
}
}
called using function(0, "", #r value#)
r value should be <= n value (array length)
Here's some pseudocode to get you started with a recursive solution. Lists will be easier to work with than string arrays, as you can change their size easily. Also, once you get your combos, you can iterate over them to display them however you want. However, though it's a good problem to think about, the number of combos will get out of hand pretty quickly, so displaying them all to a user will become a bad idea if you are working with more than a handful of results...
/**
* #param list The list to create all combos for
* #param comboSize The size of the combo lists to build (e.g. 2 for 2 items combos)
* #param startingIndex The starting index to consider (used mainly for recursion). Set to 0 to consider all items.
*/
getAllCombos(list, comboSize, startingIndex){
allCombos;
itemsToConsider = list.length - startingIndex;
if(itemsToConsider >= comboSize){
allCombos = getAllCombos(list, comboSize, startingIndex + 1);
entry = list[startingIndex];
if(comboSize == 1){
singleList;
singleList.add(entry);
allCombos.add(singleList);
} else {
subListCombos = getAllCombos(list, comboSize - 1, i+1);
for(int i = 0; i < subListCombos.length; i++){
subListCombo = subListCombos[i];
subListCombo.add(entry);
allCombos.add(subListCombo);
}
}
}
return allCombos;
}
This probably isn't perfect, but it should get you on the right track. Create a function to get combinations for each element. Then you just have to loop through each element and call your function on each of them.
int num = 2; //Number of elements per combination
for(int i=0; i <= (array.length - num); i++) {
String comb = "[" + array[i];
comb += getComb(i,num);
comb += "]";
println(comb);
}
String getComb(int i, int num) {
int counter = 1;
String s = "";
while(counter < num) {
s += ", " + array[i+counter];
counter++;
}
return s;
}
These numbers are stored in the same integer variable. How would I go about sorting the integers in order lowest to highest?
11367
11358
11421
11530
11491
11218
11789
There are two options, really:
Use standard collections, as explained by Shakedown
Use Arrays.sort
E.g.,
int[] ints = {11367, 11358, 11421, 11530, 11491, 11218, 11789};
Arrays.sort(ints);
System.out.println(Arrays.asList(ints));
That of course assumes that you already have your integers as an array.
If you need to parse those first, look for String.split and Integer.parseInt.
You can put them into a list and then sort them using their natural ordering, like so:
final List<Integer> list = Arrays.asList(11367, 11358, 11421, 11530, 11491, 11218, 11789);
Collections.sort( list );
// Use the sorted list
If the numbers are stored in the same variable, then you'll have to somehow put them into a List and then call sort, like so:
final List<Integer> list = new ArrayList<Integer>();
list.add( myVariable );
// Change myVariable to another number...
list.add( myVariable );
// etc...
Collections.sort( list );
// Use the sorted list
Collections.sort( List )
Well, if you want to do it using an algorithm. There are a plethora of sorting algorithms out there. If you aren't concerned too much about efficiency and more about readability and understandability. I recommend Insertion Sort. Here is the psudo code, it is trivial to translate this into java.
begin
for i := 1 to length(A)-1 do
begin
value := A[i];
j := i - 1;
done := false;
repeat
{ To sort in descending order simply reverse
the operator i.e. A[j] < value }
if A[j] > value then
begin
A[j + 1] := A[j];
j := j - 1;
if j < 0 then
done := true;
end
else
done := true;
until done;
A[j + 1] := value;
end;
end;
For sorting narrow range of integers try Counting sort, which has a complexity of O(range + n), where n is number of items to be sorted. If you'd like to sort something not discrete use optimal n*log(n) algorithms (quicksort, heapsort, mergesort). Merge sort is also used in a method already mentioned by other responses Arrays.sort. There is no simple way how to recommend some algorithm or function call, because there are dozens of special cases, where you would use some sort, but not the other.
So please specify the exact purpose of your application (to learn something (well - start with the insertion sort or bubble sort), effectivity for integers (use counting sort), effectivity and reusability for structures (use n*log(n) algorithms), or zou just want it to be somehow sorted - use Arrays.sort :-)). If you'd like to sort string representations of integers, than u might be interrested in radix sort....
import java.util.Arrays;
public class sortNumber {
public static void main(String[] args) {
// Our array contains 13 elements
int[] array = {9, 238, 248, 138, 118, 45, 180, 212, 103, 230, 104, 41, 49};
Arrays.sort(array);
System.out.printf(" The result : %s", Arrays.toString(array));
}
}
if array.sort doesn't have what your looking for you can try this:
package drawFramePackage;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Random;
public class QuicksortAlgorithm {
ArrayList<AffineTransform> affs;
ListIterator<AffineTransform> li;
Integer count, count2;
/**
* #param args
*/
public static void main(String[] args) {
new QuicksortAlgorithm();
}
public QuicksortAlgorithm(){
count = new Integer(0);
count2 = new Integer(1);
affs = new ArrayList<AffineTransform>();
for (int i = 0; i <= 128; i++){
affs.add(new AffineTransform(1, 0, 0, 1, new Random().nextInt(1024), 0));
}
affs = arrangeNumbers(affs);
printNumbers();
}
public ArrayList<AffineTransform> arrangeNumbers(ArrayList<AffineTransform> list){
while (list.size() > 1 && count != list.size() - 1){
if (list.get(count2).getTranslateX() > list.get(count).getTranslateX()){
list.add(count, list.get(count2));
list.remove(count2 + 1);
}
if (count2 == list.size() - 1){
count++;
count2 = count + 1;
}
else{
count2++;
}
}
return list;
}
public void printNumbers(){
li = affs.listIterator();
while (li.hasNext()){
System.out.println(li.next());
}
}
}
Take Inputs from User and Insertion Sort. Here is how it works:
package com.learning.constructor;
import java.util.Scanner;
public class InsertionSortArray {
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
System.out.println("enter number of elements");
int n=s.nextInt();
int arr[]=new int[n];
System.out.println("enter elements");
for(int i=0;i<n;i++){//for reading array
arr[i]=s.nextInt();
}
System.out.print("Your Array Is: ");
//for(int i: arr){ //for printing array
for (int i = 0; i < arr.length; i++){
System.out.print(arr[i] + ",");
}
System.out.println("\n");
int[] input = arr;
insertionSort(input);
}
private static void printNumbers(int[] input) {
for (int i = 0; i < input.length; i++) {
System.out.print(input[i] + ", ");
}
System.out.println("\n");
}
public static void insertionSort(int array[]) {
int n = array.length;
for (int j = 1; j < n; j++) {
int key = array[j];
int i = j-1;
while ( (i > -1) && ( array [i] > key ) ) {
array [i+1] = array [i];
i--;
}
array[i+1] = key;
printNumbers(array);
}
}
}