I'm working on this project using Arrays. I have a method called createRandomIntArray that creates an array. This method is meant to return the Array in descending order. I have been able to do just that but I want to know if there is a more effective way to write this method than the way I wrote it. I have my code below.
public static int[] createRandomIntArray(int n) {
Random random = new Random();
int[] result = new int[n];
for (int i = 0; i < n; i++) {
result[i] = random.nextInt(n);
}
Arrays.sort(result);
for (int i = 0; i < result.length / 2; i++) {
int temp = result[i];
result[i] = result[result.length - i - 1];
result[result.length - i - 1] = temp;
}
return result;
}
You could avoid reversing the sorted array by directly sorting reverse order:
Arrays.sort(result, Comparator.reverseOrder());
As mentioned in the comments one could use Random.ints(…) if you’re not tied to using arrays:
random.ints(n, 0, n).boxed().sorted(Comparator.reverseOrder()).mapToInt(i -> i).toArray();
Using Java Streams
private static int[] createRandomIntArray(int n) {
return ThreadLocalRandom.current().ints() // Stream of random ints
.limit(n) // Limit the stream to n values
.boxed() // Convert to Stream of Integer Objects for reverse sorting
.sorted(Collections.reverseOrder()) // Sort in reverse Order
.mapToInt(Integer::intValue) // Map back to primitive ints
.toArray(); // as Array
}
public class SortDes {
public static void main(String[] args) {
int [] arr = new int [] {5, 2, 8, 7, 1};
int temp = 0;
System.out.println("Elements of original array: ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
for (int i = 0; i < arr.length; i++) {
for (int j = i+1; j < arr.length; j++) {
if(arr[i] < arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
System.out.println();
System.out.println("Elements of array sorted in descending order: ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
There's an alternative which is using Stream.
Arrays.stream(result).sorted(Comparator.reverseOrder());
Related
I was trying to create a code that rearranges given elements in an array -by the user- in ascending order, and I have done that, but the program requires
printing the given elements after sorting them firstly, then printing them before sorting.
I have no problem with printing the elements after sorting
the problem is with printing them before sorting
how to re-use ar[S] = in.nextInt() the given elements by the user out of its for loop
import java.util.*;
public class SortingnumbersANDswapping {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int swap;
int ar[] = new int[3]; //{8,10,5}
for (int S = 0; S < ar.length; S++) {
ar[S] = in.nextInt(); //this for loop is used to store numbers in the array
}
for (int i = 0; i < ar.length; i++) {
/* this nested for loop is used to compare the first element with the second one in the array
or the second element with the third.
*/
for (int j = i + 1; j < ar.length; j++) {
if (ar[i] > ar[j]) { //8>10-->F , 8>5 -->T , {5,10,8} the new arrangment we are going to use
swap = ar[i]; // 10>8-->T {5,8,10}
ar[i] = ar[j];
ar[j] = swap;
}
}
System.out.println(ar[i]); // to print the new order print it inside the array
}
// I wanna do something like that
// System.out.println(ar[S]);
// but of course I cant cause array S is only defined in it's loop
}
}
You can't reuse it, you need to keep the original array stored in another array that stays untouched. Additionally, Arrays are usually declared as int[] ar in Java, instead of int ar[]. Something along the following lines should work as intended:
public class SortingnumbersANDswapping {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int swap;
int[] ar = new int[3]; //{8,10,5}
for (int S = 0; S < ar.length; S++) {
ar[S] = in.nextInt(); //this for loop is used to store numbers in the array
}
System.out.println("::: Original Array :::");
int[] originalArray = Arrays.copyOf(ar, ar.length);
for (int j : originalArray) {
System.out.println(j);
}
System.out.println("::: Sorted Array :::");
for (int i = 0; i < ar.length; i++) {
for (int j = i + 1; j < ar.length; j++) {
if (ar[i] > ar[j]) { //8>10-->F , 8>5 -->T , {5,10,8} the new arrangment we are going to use
swap = ar[i]; // 10>8-->T {5,8,10}
ar[i] = ar[j];
ar[j] = swap;
}
}
System.out.println(ar[i]); // to print the new order print it inside the array
}
}
}
You can do a copy of the array using the copyOf method from the Arrays library (java.util.Arrays) before you start changing the array.
Here you can find some different approaches - https://www.softwaretestinghelp.com/java-copy-array/amp/
You can use System.out.print(Arrays.toString(arr)); to print the entire array.
public static void main(String... args) {
int[] arr = readArray(3);
System.out.print(Arrays.toString(arr));
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < ar.length; j++) {
if (arr[i] > arr[j]) {
swap(arr, i, j);
System.out.print(Arrays.toString(arr));
}
}
}
}
private static int[] readArray(int size) {
System.out.format("Enter %d elements:\n", size);
Scanner scan = new Scanner(System.in);
int[] arr = new int[size];
for(itn i = 0; i < arr.length; i++)
arr[i] = scan.nextInt();
return arr;
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
I want that sorting array without actually changing its data. So I want only keep its indexes in another array. For this I use Bubble Sort algorithm, and at every swapping step I change elements of new array which keeps indexes of actual array. That's my code, but it doesn't work correctly
int[] bSort(int[] arrivalTimes) {
int[] sequence = new int[arrivalTimes.length];
for (int i = 0; i < sequence.length; i++) {
sequence[i] = i;
}
for (int i = 0; i < arrivalTimes.length - 1; i++) {
for (int j = i + 1; j < arrivalTimes.length; j++) {
if (arrivalTimes[i] > arrivalTimes[j]) {
int temp = sequence[i];
sequence[i] = sequence[j];
sequence[j] = temp;
}
}
}
return sequence;
}
So if input array is [2, 5, 1, 0, 4]
Then sequence array should be [3, 2, 0, 4, 1] (indexes of actual array)
You're forgetting to sort the actual array also. If the arrivalTimes array isn't sorted, your condition will not act the way you expect.
int[] bSort(int[] arrivalTimes) {
int[] sequence = new int[arrivalTimes.length];
for (int i = 0; i < sequence.length; i++) {
sequence[i] = i;
}
for (int i = 0; i < arrivalTimes.length - 1; i++) {
for (int j = i + 1; j < arrivalTimes.length; j++) {
if (arrivalTimes[i] > arrivalTimes[j]) {
int temp = sequence[i];
sequence[i] = sequence[j];
sequence[j] = temp;
int temp2 = arrivalTimes[i];
arrivalTimes[i] = arrivalTimes[j];
arrivalTimes[j] = temp2;
}
}
}
return sequence;
}
This is an inefficient solution though. I suspect this is part of some algorithms assignment so I'll leave the optimisations up to you.
I want to sort an array of int from the smallest value to the greatest one. I have created the next algorithm but the problem is that the new array does't receive the right values from the if statement. I am going put my code bellow.
public static void main(String[] args) {
int[] arr = {33,44,22,11,22,11};
int[] arrSort = new int[6];
int temp=0;
for (int i = 0; i < arrSort.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
temp = arr[i + 1];
arr[i + 1] = arr[i];
arrSort[i] = temp;
}
else {
arrSort[i] = arr[i];
}
}
System.out.println(Arrays.toString(arrSort));
}
If i run the code I get the next values: [33, 22, 11, 22, 11, 0];
I just want to figure out what part of the algorithm was thought wrong. Thank you in advance.
You need to apply 2 loops.
1st loop is to access 1st arr element.
2nd loop is to access next(1st + 1)th element.
After comparing 1st element with other swap it accordingly.
public static void main(String []args)
{
int[] arr = {33,44,22,11,22,11};
int len=arr.length;
int temp=0,i,j;
for (i = 0; i < len; i++)
{
for (j = i+1; j < len; j++)
{
if (arr[i] > arr[j])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
for(i=0; i<arr.length; i++)
{
System.out.println(arr[i]);
}
}
when it is the case of array Loops are very handy to use.
int[] yourArary = new int[10];
ArrayList<Integer> intArray = new ArrayList<>();
for( int value : yourArary ){
intArray.add( value );
}
Arrays.sort(intArray);
System.out.println(Arrays.toString(yourArary));
// you can short like this in reverse order
for (int i = yourArary.length - 1; i >= 0; i--)
System.out.print(yourArary[i] + " ");
System.out.println();
You cannot do it with just one loop. Sorting is a more complex than that. For bubble sort or selection sort it's like O(n^2). There are better algorithms that like quick sort or merge sort that have better results and aim for O(n log N) complexity. But anyway you can do it like that for example for a simple bubble sort implementation:
int[] arr = {33,44,22,11,22,11};
for (int i = 0; i < arrSort.length - 1; i++) {
for(int j=i;j<arrSort.length; j++) {
if (arr[i] > arr[j]) {
temp = arr[j];
arr[j] = arr[i];
arr[i]=temp;
}
}
System.out.println(Arrays.toString(arr));
Don't know if this will help you, but why sort it by yourself, if Java can do the Job:
int[] unsortedArray = { 33, 44, 22, 11, 22, 11 };
ArrayList<Integer> intArray = new ArrayList<>();
for( int value : unsortedArray )
{
intArray.add( value );
}
Collections.sort( intArray );
System.out.println( intArray );
If you use the helper variable temp to move positions, you don't need a second array, just put it back into arr[i]. Second, one run is not enough, you will need to run this, until there are no position changes needed. So it would look like this:
public static void main(String[] args) {
//source Array
int[] arr = {33,44,22,11,22,11};
int temp=0;
//marker, that positions were switched
boolean sthChanged = false;
do
{
//in each run assume that nothing is left to change
sthChanged = false;
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
//we found an instance, where the earlier position holds a higher int than the latter
//save the latter value in the temp variable
temp = arr[i + 1];
//move the former value to the latter position
arr[i + 1] = arr[i];
//fill the former position with the value from the temp variable
arr[i] = temp;
//set the marker to true, as there might be other changes to be done
sthChanged = true;
}
}
}
while (sthChanged); //stop only, if we didn't find sth to be changed in the last run
System.out.println(Arrays.toString(arr));
}
Best regards
First of all, u shud not use two arrays in your algorithm, as its just a waste of memory and unecessary array access overhead. If u need to retain the original array copy it over, and send the copied array to the sort method.
Secondly, for the method adopted here (bubble sort), you are iterating the array and finding the largest element and shifting it to the end.
U need to repeat this process, for each subarray of length-1, length-2 ... 1.
So the time complexity of this approach would be O(n^2). There are better algorithms, like MergeSort, QuickSort which can do the sort in the theoretical O(n log(n)) time.
See below the correctin required for your code :
public static void main(String[] args) {
int[] arr = {33,44,22,11,22,11};
//int[] arrSort = new int[6];
int temp=0;
for(int j = 0; j < arr.length; j++) {
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
temp = arr[i + 1];
arr[i + 1] = arr[i];
arr[i] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
i want to store the original index numbers of array elements before for sorting in ascending order.
assume if the elements in array are
x[]= {20,40,70,80,50,30};
i want another array to return with index number of the sorted form like
sorted[] = {0,5,1,4,2,3}
i tried many times. but can't figure out how to get the index numbers. everytime the index number gets changed after the swap.
Note:
i can't use comparotor,map,Arrays.sort or anything like that. i have
to use loop only.
i already searched all the websites. i cant find any specific answer.
cause all of them uses comparator map or something that i am not
allowed to use at the moment.
public static int[] sort(int[] numbers) {
int[] sorted = new int[numbers.length];
int temp;
int[] index= new int[numbers.length];
for (int i = 0; i < numbers.length; i++) {
for (int j = i+1; j < numbers.length; j++) {
if (numbers[i] > numbers[j]) {
temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
index[i]= j;
}
}
}
return index;
}
i was able to do it by storing the original array in another array and then use loop to compare the sorted array and store the index .
Thanks #RubioRic #RCInd .
I think this is what you're looking for:
keep positions in a map
Sort
Lookup the map for the indexes before the sorting
PS: The complexity would come because of the duplicates. You need to handle
that with the help of another map
See the working code here...
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.print.attribute.HashAttributeSet;
public class PositionFinder{
public static void main(String[] args) {
Integer []a = {3,2,3,0,1};
Map <Integer , List<Integer>> map = new HashMap<>();
for (int i = 0; i < a.length; i++) {
int j = a[i];
if(map.get(j)==null){
map.put(j, new ArrayList<>());
map.get(j).add(i);
}
else{
map.get(j).add(i);
}
}
System.out.println("Positions ->" + map);
//sort
List<Integer> l = new ArrayList<Integer>(Arrays.asList(a));
Collections.sort(l);
System.out.println("Sorted List -->" + l );
//get and print index
List positionList = new ArrayList<>();
Map<Integer, Integer> duplicateTrackerMap = new HashMap<>();
for (Integer key : l) {
int pos = 0;
if(duplicateTrackerMap.get(key) != null){
pos = 1+ duplicateTrackerMap.get(key);
}
duplicateTrackerMap.put(key, pos);
positionList.add(map.get(key).get(pos));
}
System.out.println("Sort index -->" + positionList);
}
}
int x[] = { 20, 40, 70, 80, 50, 30 };
int[] array = new int[x.length];
for (int i = 0; i < x.length; i++) {
array[i] = i;
}
for (int i = (x.length - 1); i >= 0; i--) {
for (int j = 1; j <= i; j++) {
int oneMi = j - 1;
if (x[oneMi] > x[j]) {
int temp = x[oneMi];
x[oneMi] = x[j];
x[j] = temp;
int swi = array[oneMi];
array[oneMi] = array[j];
array[j] = swi;
}
}
}
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
I need to have an algorithm that changes values in one array if it is in the second array. The result is that the first array should not have any values that are in the second array.
The arrays are of random length (on average ranging from 0 to 15 integers each), and the content of each array is a list of sorted numbers, ranging from 0 to 90.
public void clearDuplicates(int[] A, int[] B){
for(int i = 0; i < A.length; i++){
for(int j = 0; j < B.length; j++)
if(A[i] == B[j])
A[i]++;
}
}
My current code does not clear all of the duplicates. On top of that it might be possible it will creat an index out of bounds, or the content can get above 90.
Although your question is not very clear, this might do the job. Assumptions:
The number of integers in A and B is smaller than 90.
The array A is not sorted afterwards (use Arrays.sort() if you wish to
fix that).
The array A might contain duplicates within itself afterwards.
public void clearDuplicates(int[] A, int[] B) {
// Initialize a set of numbers which are not in B to all numbers 0--90
final Set<Integer> notInB = new HashSet<>();
for (int i = 0; i <= 90; i++) {
notInB.add(i);
}
// Create a set of numbers which are in B. Since lookups in hash set are
// O(1), this will be much more efficient than manually searching over B
// each time. At the same time, remove elements which are in B from the
// set of elements not in B.
final Set<Integer> bSet = new HashSet<>();
for (final int b : B) {
bSet.add(b);
notInB.remove(b);
}
// Search and remove duplicates
for (int i = 0; i < A.length; i++) {
if (bSet.contains(A[i])) {
// Try to replace the duplicate by a number not in B
if (!notInB.isEmpty()) {
A[i] = notInB.iterator().next();
// Remove the added value from notInB
notInB.remove(A[i]);
}
// If not possible, return - there is no way to remove the
// duplicates with the given constraints
else {
return;
}
}
}
}
You can do it just by using int[ ] although it's a bit cumbersome. The only constraint is that there may not be duplicates within B itself.
public void clearDuplicates(int[] A, int[] B) {
//Number of duplicates
int duplicate = 0;
//First you need to find the number of duplicates
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < B.length; j++)
if (A[i] == B[j])
duplicate++;
}
//New A without duplicates
int[] newA = new int[A.length-duplicate];
//For indexing elements in the new A
int notDuplicate = 0;
//For knowing if it is or isn't a duplicate
boolean check;
//Filling the new A (without duplicates)
for (int i = 0; i < A.length; i++) {
check = true;
for (int j = 0; j < B.length; j++) {
if (A[i] == B[j]) {
check = false;
notDuplicate--;//Adjusting the index
}
}
//Put this element in the new array
if(check)
newA[notDuplicate] = A[i];
notDuplicate++;//Adjusting the index
}
}
public class DuplicateRemove {
public static void main(String[] args) {
int[] A = { 1, 8, 3, 4, 5, 6 };
int[] B = { 1, 4 };
print(clear(A, B));
}
public static int[] clear(int[] A, int[] B) {
int a = 0;
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < B.length; j++) {
if (A[i] == B[j]) {
a++;
for (int k = i; k < A.length - a; k++) {
A[k] = A[k + 1];
}
}
}
}
int[] C = new int[A.length - a];
for (int p = 0; p < C.length; p++)
C[p] = A[p];
return C;
}
public static void print(int[] A) {
for (int i = 0; i < A.length; i++)
System.out.println("Element: " + A[i]);
}
}
Here is an example.. I compiled and its working. For any question just let me know :)
maybe you should try the following code:
public void clear (int[] A, int[] B)
{
for (int i=0; i<A.length;i++)
{
for (int j=0; j<B.length; j++)
if(A[i]==B[j])
{
for (int k=i; k<A.length;k++)
A[k]=A[k+1];
j=B.length-1; //so that the cycle for will not be executed
}
}
}