ArrayList Bubblesort with strings - java

The sorting is not working, it doesn't sort the names by the alphabet, I wrote a bubble sort algorithm with int and it worked fine. Can you help me? Is something wrong with the compareTo() method?
public ArrayList<FootballPlayer> sortByNames(ArrayList<FootballPlayer> pList)
{
FootballPlayer z;
for(int i=0; i<pList.size(); i++)
{
for(int j=0; j<pList.size()-i-1;j++)
{
if((pList.get(i).getName()).compareTo(pList.get(j+1).getName())>0)
{
z = pList.get(j);
pList.set(j, pList.get(j+1));
pList.set(j+1,z);
}
}
}
for(int i=0; i<pList.size(); i++)
{
System.out.print(pList.get(i).getName()+";");
System.out.println("");
}
return pList;
}

Your implementation is not BubbleSort! Check Bubble sort or event a bit more advanced Cocktail shaker sort.
public static void bubbleSort(List<String> pList) {
boolean done = false;
for (int i = pList.size(); !done; i--) {
done = true;
for (int j = 0; j + 1 < i; j++) {
if (pList.get(j).compareTo(pList.get(j + 1)) <= 0)
continue;
done = false;
String tmp = pList.get(j);
pList.set(j, pList.get(j + 1));
pList.set(j + 1, tmp);
}
}
}
Output:
List<String> pList = new ArrayList<>();
for (int i = 0; i < 10; i++)
pList.add(String.valueOf(i));
Collections.shuffle(pList);
System.out.println(pList); // [0, 6, 7, 9, 5, 8, 4, 1, 3, 2]
bubbleSort(pList);
System.out.println(pList); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Related

How to implement a descending selection sort

The method I have to create should take as parameter an array of integers and return the integer array with its contents sorted in descending order — largest to smallest.
Note - no libraries should be used in your implementation for this method.
I've attempted to use a regular selection sort and using a swap at the end but syntax errors just occurred:
public static int[] reverseSelectionSort(int[] arrayToBeSorted) {
// implementation of Task 3 goes here
for(int i = 0; i < arrayToBeSorted.length; i++){
int maxPosition=i;
int minPosition=i;
for(int j = i+1; j < arrayToBeSorted.length - i; j++){
if(arrayToBeSorted[j] < arrayToBeSorted[minPosition]){
minPosition = j;
}
if(arrayToBeSorted[j] > arrayToBeSorted[maxPosition]){
maxPosition = j;
}
}
swap(arrayToBeSorted,minPosition,maxPosition);
swap(arrayToBeSorted,maxPosition,i);
swap(arrayToBeSorted,minPosition,arrayToBeSorted.length-i-1);
}
return arrayToBeSorted; // change this to return the sorted array
}
public static void main(String[] args) {
int[] array2 = {3, 6, 8, 3, 5, 7, 1};
int[] sorted = reverseSelectionSort(array2);
System.out.print("task: [");
for (int i = 0; i < sorted.length; i++) {
if (i > 0) {
System.out.print(", ");
}
System.out.print(sorted[i]);
}
System.out.println("]");
}
If you call the method on the array [3, 6, 8,
3, 5, 7, 1], then the method should return the array [8, 7, 6, 5, 3, 3, 1].
Once you add the implementation of swap to your code (and put it all inside a class), it produces exactly the output you wanted it to. Maybe you thought swap was a java uitl, which it is for Collections, but an array is not a Collection.
So very little has changed in the below:
public class soSelect{ //embed in class, added
public static int[] reverseSelectionSort(int[] arrayToBeSorted) {
// implementation of Task 3 goes here
for(int i = 0; i < arrayToBeSorted.length; i++){
int maxPosition=i;
int minPosition=i;
for(int j = i+1; j < arrayToBeSorted.length - i; j++){
if(arrayToBeSorted[j] < arrayToBeSorted[minPosition]){
minPosition = j;
}
if(arrayToBeSorted[j] > arrayToBeSorted[maxPosition]){
maxPosition = j;
}
}
swap(arrayToBeSorted,minPosition,maxPosition);
swap(arrayToBeSorted,maxPosition,i);
swap(arrayToBeSorted,minPosition,arrayToBeSorted.length-i-1);
}
return arrayToBeSorted; // change this to return the sorted array
}
public static void swap(int[] a, int i, int j){ //had to implement it
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void main(String[] args) {
int[] array2 = {3, 6, 8, 3, 5, 7, 1};
int[] sorted = reverseSelectionSort(array2);
System.out.print("task: [");
for (int i = 0; i < sorted.length; i++) {
if (i > 0) {
System.out.print(", ");
}
System.out.print(sorted[i]);
}
System.out.println("]");
}
}//added outer brace
I ran it in java doodle and it printed:
task: [8, 7, 6, 5, 3, 3, 1]
I did not test beyond that, but this should at least get you unstuck, or, at best, finished. For sure you could compare with the implementation to which the above comment points you.

Getting the Elements that has duplicates in an int array Java

This post - "Java + Count duplicates from int array without using any Collection or another intermediate Array", was also a sample exercise in my book at school, but what I want to do is get the elements that has duplicates without sorting it.
What I did is I removed the duplicates of arrays first, to get only the unique elements and then I compare it to the original array and count how many times the element has been found. But the problem is it doesn't print the correct elements which has duplicates.
int[] num = {7, 2, 6, 1, 4, 7, 4, 5, 4, 7, 7, 3, 1};
the correct output should be: 7, 1, 4
but instead it outputs: 7, 6, 1
This is my codes:
//method for removing duplicates
public static int[] removeDuplicates(int[] n) {
int limit = n.length;
for(int i = 0; i < limit; i++) {
for(int j = i + 1; j < limit; j++) {
if(n[i] == n[j]) {
for(int k = j; k < limit - 1; k++) {
n[k] = n[k + 1];
}
limit--;
j--;
}
}
}
int[] uniqueValues = new int[limit];
for(int i = 0; i < uniqueValues.length; i++) {
uniqueValues[i] = n[i];
}
return uniqueValues;
}
//method for getting elements that has duplicates
public static int[] getDuplicatedElements(int[] n) {
int[] nCopy = n.clone();
int[] u = removeDuplicates(nCopy);
int count = 0;
int limit = u.length;
for(int i = 0; i < u.length; i++) {
for(int j = 0; j < n.length; j++) {
if(u[i] == n[j]) {
count++;
}
}
if(count == 1) {
for(int k = i; k < limit - 1; k++) {
u[k] = u[k + 1];
}
limit--;
}
count = 0;
}
int[] duplicated = new int[limit];
for(int i = 0; i < duplicated.length; i++) {
duplicated[i] = u[i];
}
return duplicated;
}
//main
public static void main(String[] args) {
int[] num = {7, 2, 6, 1, 4, 7, 4, 5, 4, 7, 7, 3, 1};
//printing original values
System.out.print(Arrays.toString(num));
System.out.println();
int[] a = getDuplicatedElements(num);
System.out.print("Elements with Duplicates: " + Arrays.toString(a));
}
What's the error in my codes here? Please help thanks...
You have two issues:
public static int[] getDuplicatedElements(int[] n) {
int[] nCopy = n.clone();
int[] u = removeDuplicates(nCopy);
System.out.println ("unique " + Arrays.toString (u));
int count = 0;
int limit = u.length;
for(int i = 0; i < limit; i++) { // you must use limit instead of u.length
// in order for the loop to terminate
for(int j = 0; j < n.length; j++) {
if(u[i] == n[j]) {
count++;
}
}
if(count == 1) {
for(int k = i; k < limit - 1; k++) {
u[k] = u[k + 1];
}
limit--;
i--; // you must decrement i after you find a unique element in u
// otherwise you'll be skipping elements in the u array
}
count = 0;
}
int[] duplicated = new int[limit];
for(int i = 0; i < duplicated.length; i++) {
duplicated[i] = u[i];
}
return duplicated;
}
With those fixes, you'll get the expected output:
Elements with Duplicates: [7, 1, 4]
It's fairly simple when using a stream
int[] num = {7, 2, 6, 1, 4, 7, 4, 5, 4, 7, 7, 3, 1};
List<Integer> list = Arrays.stream(num).boxed().collect(Collectors.toList());
list.stream().filter(i -> Collections.frequency(list, i) > 1)
.collect(Collectors.toSet()).forEach(System.out::println);

Finding the biggest nondecreasing Subset in a list using Brute Force approach?

We have a number list which is (5, 12, 4, 6, 7, 12, 5, 55, 13, 14) and I have to find the biggest nondecreasing subset which is (4, 6, 7, 12) .
Also it should be solved by brute force approach. I tried to solve it but I am not sure that it is a brute force solution. Any tips would be helpful! (Pseudocode, java code or any help...)
public static void main(String[] args) {
int[] nonDecrease = { 5, 12, 4, 6, 7, 12, 5, 55, 13, 14 };
ArrayList list = new ArrayList();
ArrayList temp = new ArrayList();
list.add(nonDecrease[0]);
int counter = 0;
int a = 0;
for (int i = 1; i < nonDecrease.length; i++) {
if (nonDecrease[i - 1] < nonDecrease[i]) {
list.add(nonDecrease[i]);
counter = list.size();
} else if (nonDecrease[i - 1] > nonDecrease[i] && counter >= a) {
a = list.size();
if (list.size() >= temp.size() && counter >= a) {
temp = list;
System.out.println(temp + "t");
}
list.clear();
list.add(nonDecrease[i]);
}
}
}
}
With bruteforce, you can try this approach. Note that you have maxLength = maxList.size() so you don't have to store the extra maxLength variable.
List<Integer> maxList = new ArrayList();
for (int i = 0; i < nonDecrease.length - 1;) {
int prev = nonDecrease[i];
List<Integer> currentMaxList = new ArrayList();
currentMaxList.add(prev);
int j = i + 1;
for (; j < nonDecrease.length; j++) {
if (nonDecrease[j] >= prev) {
prev = nonDecrease[j];
currentMaxList.add(prev);
} else {
break;
}
}
if (currentMaxList.size() > maxList.size()) {
// Found new longer
maxList = currentMaxList;
}
// The non-decreasing break at `j` so we continue the next search at j:
i = j;
}

Java matching arrays

The method which takes two integer arrays. The method returns an integer array containing all the elements in array int[]a that are also present in array int[]b in their original sequential order in int[]a.
This is what it should output :
input: {1, 2, 3, 4, 5, 6, 7, 3, 8, 9, 2, 10}, {3, 2, 7, 12, 3, 9, 5, 2}
output: {2, 3, 5, 7, 3, 9, 2}
input: {4, 7, 1, 6, 9, 2, 3, 1}, {8, 5, 2, 1, 9, 4}
output: {4, 1, 9, 2, 1}
I tried something like this just to test it out to get my head around it but I still couldn't.
public static void arraysMatching(int[] s1, int[] s2) {
ArrayList<Integer> storage = new ArrayList<Integer>();
for (int i = 0; i <= s1.length; i++) {
for (int j = 0; j <= s2.length; j++) {
if (s2[j] == s1[i]) {
storage.add(s2[j]);
break;
}
}
break;
}
System.out.println(storage);
}
Test cases:
int [] m1 = {1, 2, 3, 4, 5, 6, 7, 3, 8, 9, 2, 10};
int [] m2 = {3, 2, 7, 12, 3, 9, 5, 2};
System.out.println(Arrays.toString(arraysMatching(m1, m2)));
Should print out [2, 3, 5, 7, 3, 9, 2]
To add to Codors answer, have the method return int[]:
public static int[] arraysMatching(int[] s1, int[] s2) {
ArrayList<Integer> storage = new ArrayList<>();
//for (int i = 0; i <= s1.length; i++) {
//wrong. change <= to < or better:
for (int i : s1) {
//for (int j = 0; j <= s2.length; j++) {
//wrong. change <= to < or better:
for (int j : s2) {
if (j == i) {
storage.add(j);
break;
}
}
}
//if you can use streams do
//return storage.stream().mapToInt(i->(int)i).toArray();
//alternatively
int[] returnArray = new int[storage.size()];
for(int i=0; i< storage.size(); i++) {
returnArray[i]=storage.get(i);
}
return returnArray;
}
So you can use it with System.out.println(Arrays.toString(arraysMatching(m1, m2)));
To my understanding, the second break statement terminates the outer loop too early; furthermore, the indexing goes one step too far in both loop termination conditions. Change the implementation as follows.
public static void arraysMatching(int[] s1, int[] s2) {
ArrayList<Integer> storage = new ArrayList<Integer>();
for (int i = 0; i < s1.length; i++) {
for (int j = 0; j < s2.length; j++) {
if (s2[j] == s1[i]) {
storage.add(s2[j]);
break;
}
}
}
System.out.println(storage);
}
Edit:
If the result is not to be printed but to be returned, the signature and the body have to be changed as follows.
public static ArrayList<Integer> arraysMatching(int[] s1, int[] s2) {
ArrayList<Integer> storage = new ArrayList<Integer>();
for (int i = 0; i < s1.length; i++) {
for (int j = 0; j < s2.length; j++) {
if (s2[j] == s1[i]) {
storage.add(s2[j]);
break;
}
}
}
return storage;
}
Edit:
If the return type is required to be Integer[], the implementation has to be changed as follows.
public static Integer[] arraysMatching(int[] s1, int[] s2) {
ArrayList<Integer> storage = new ArrayList<Integer>();
for (int i = 0; i < s1.length; i++) {
for (int j = 0; j < s2.length; j++) {
if (s2[j] == s1[i]) {
storage.add(s2[j]);
break;
}
}
}
int[] result = new int[storage.size()];
result = storage.toArray(result);
return result;
}
Edit:
If the return type is required to be int[] and no 'fancy stuff' for result conversion is desired, the code has to be changed as follows.
public static int[] arraysMatching(int[] s1, int[] s2) {
ArrayList<int> storage = new ArrayList<int>();
for (int i = 0; i < s1.length; i++) {
for (int j = 0; j < s2.length; j++) {
if (s2[j] == s1[i]) {
storage.add(s2[j]);
break;
}
}
}
int[] result = new int[storage.size()];
for (int k = 0; k < storage.length(); k++) {
result[k] = storage.get(k);
}
return result;
}

Java Multidimensional array and integer occurrences

I have this integer array called numList which has
[4, 4, 3, 3, 3, 2, 1, 1, 1, 1, -1, -12, -12, -12, -12]
I would like to create a multidimensional array which can store
Which left side represents the number and the right side determines the number of occurrences.
The attempt i tried... i got nowhere.
// Declaring the new multi-dimensional array.
int [] [] newArray = new int [6] [2];
// Counter 3.
int counter3 = 0;
// Get first occurrence.
while (numList[counter3] < numList.length){
for (int counter3:numList){
newArray[] ([counter3]++);
}
Assuming your numbers are in order as they are in your example numList, then you could do this:
int[] numList = { 4, 4, 3, 3, 3, 2, 1, 1, 1, 1, -1, -12, -12, -12, -12 };
int[][] newArray = new int[6][2];
int index = 0;
for (int i = 0; i < numList.length;) {
int count = 0;
for (int x = 0; x < numList.length; x++)
if (numList[x] == numList[i]) count++;
newArray[index][0] = numList[i];
newArray[index][1] = count;
index++;
i += count;
}
for (int x = 0; x < newArray.length; x++) {
for (int i = 0; i < newArray[0].length; i++)
System.out.print(newArray[x][i] + " ");
System.out.println();
}
This way, you don't have to deal with imports as in the other answers (and this is shorter), but this only works if you have ordered numbers. There are some good sorting algorithms out there, though.
Edit: I changed it so that it can take numbers in any order of any size.
int[] numList = { 6, 6, 5, 5, 4, 4, 3, 2, 1, 1, 1, 7, 6, 5, 7, 8, 65, 65, 7 };
int[][] newArray = new int[1][2];
int index = 0;
for (int i = 0; i < numList.length;) {
try {
int count = 0;
boolean isUnique = true;
for (int x = 0; x < i; x++)
if (numList[x] == numList[i]) {
isUnique = false;
break;
}
if (isUnique) {
for (int x = 0; x < numList.length; x++)
if (numList[x] == numList[i]) count++;
newArray[index][0] = numList[i];
newArray[index][1] = count;
index++;
}
i++;
} catch (ArrayIndexOutOfBoundsException e) {
int tmpArray[][] = newArray;
newArray = new int[tmpArray.length + 1][tmpArray[0].length];
for (int row = 0; row < tmpArray.length; row++)
for (int col = 0; col < 2; col++)
newArray[row][col] = tmpArray[row][col];
}
}
for (int x = 0; x < newArray.length; x++) {
for (int i = 0; i < newArray[0].length; i++)
System.out.print(newArray[x][i] + " ");
System.out.println();
}
So, at this point, it would probably be shorter to use the maps from the other answer. The only benefit of my second answer not worrying about imports.
private Map<Integer, Integer> segregateArray(List<Integer> list) {
Map<Integer, Integer> result = new HashMap<>();
for (Integer i : list) {
if (result.containsKey(i)) {
result.put(i, result.get(i) + 1);
} else {
result.put(i, 1);
}
}
return result;
}
This should work. If you still need to return array use this:
private int[][] segregateArray(int[]list) {
Map<Integer, Integer> resultHelper = new HashMap<>();
for (int i : list) {
if (resultHelper.containsKey(i)) {
resultHelper.put(i, resultHelper.get(i) + 1);
} else {
resultHelper.put(i, 1);
}
}
int[][] result = new int[resultHelper.size()][2];
int arrayIterator=0;
for(Integer key : resultHelper.keySet())
{
result[arrayIterator][0]=key;
result[arrayIterator][1]=resultHelper.get(key);
arrayIterator++;
}
return result;
}
In the real life project you probably should avoid implementing a functionality like this yourself using a low level array mechanism (you added an extensive test suite, didn't you? :) and opt for one of available libraries.
In Java 8 this can be done nicely using closures similarly to what has been described here: Count int occurrences with Java8.
In Java 7 and earlier I would use one of the collection libraries such as Guava, which contains a Multiset collection delivering exactly what you're after.

Categories

Resources