Related
I've written the following method that uses selection sort to sort an array:
public T[] selection(T[] arr)
{
T temp, min;
for(int i = 0; i < arr.length-1; i++)
{
for(int j = i + 1; j < arr.length; j++)
{
min = arr[i];
if(min.compareTo(arr[j]) > 0)
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
return arr;
}
However, I am having trouble distinguishing my algorithm from a bubble sort. Does my sorting method pass for a selection sort method?
Your algorithm is actually something called exchange sort.
In selection sort, you run a pass over the array to locate the smallest element. Whenever an element is found smaller than the smallest one discovered so far, you make a note of its position, but don’t move or swap it. Only once you’ve finished scanning the array elements do you swap the item you found to an earlier spot in the array. This means you always do a total of at most n - 1 swaps, one per iteration of the outer loop.
That doesn’t correspond with what you have in your code, because you’re performing multiple swaps per iteration of the outer i loop. The algorithm you have is called exchange sort. It’s a legal sorting algorithm, and like selection sort at the end of each iteration of the outer i loop you’ll have correctly placed another element, but it runs slower than a true selection sort because you’re making many more swaps than are needed.
Your implementation is definitely similar to the selection sort, but the swap should happen outside the nested loop. Within the innermost loop you should only save the index of the smallest element among the ones left to sort (I've misread you if placement during my first editing of the answer).
The main difference between selection sort and bubble sort is mainly, but not entirely, in their nested loop. In fact, the selection sort tries in its nested loop to find the smallest element after i and then places it at the i-th position. In this way, at each iteration of the outer loop it is guaranteed that the i-th element corresponds to the smallest among the ones left to sort (from i to n-1).
public void selectionSort(int[] arr){
int temp, min;
// At every iteration, the outer loop checks whether the i-th element is already at the right place,
// i.e. being the smallest value among the ones that follow it
for (int i = 0; i < arr.length-1; i++) {
//Assuming that the element in position i is the smallest among the ones left to sort
min = i;
//At every iteration of the outer loop, the innermost loop checks if there's a smaller value than the one in position i
for (int j = i + 1; j < arr.length; j++) {
//If a smaller value than the min-th element is found then j is stored as the current smallest index
if (arr[min] > arr[j]) {
min = j;
}
}
//Swapping the smallest element found with the one in position i.
//If min is still equal to i then no actual swap happens
temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
On the other hand, the bubble sort algorithm achieves the same thing but instead of traversing from left to right, it iterates from right to left carrying with it the new smallest element it encounters.
public void bubbleSort(int[] vet) {
int temp;
//At every iteration, the outermost loop checks if there are any elements after i which are smaller than it
for (int i = 0; i < vet.length - 1; i++) {
// The innermost loop starts from the right bound 'till the i index.
// Every time this loop finds in [j-1] a bigger element than the one in [j],
// then these two are swapped to carry along the smaller element in position j during the traverse.
// Instead if the element in [j-1] is smaller than the one in [j],
// then it leaves them like that and keeps carrying [j-1] along instead of [j].
for (int j = vet.length - 1; j >= i + 1; j--) {
if (vet[j] < (vet[j - 1])) {
temp = vet[j];
vet[j] = vet[j - 1];
vet[j - 1] = temp;
}
}
}
}
public final class SelectionSort {
public static void sortAsc(int[] arr) {
for (int i = 0; i < arr.length - 1; i++)
swap(arr, i, getMinIndex(arr, i));
}
private static int getMinIndex(int[] arr, int i) {
int minIndex = i;
for (; i < arr.length; i++)
if (arr[i] < arr[minIndex])
minIndex = i;
return minIndex;
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
I've been looking at a for-loop that reverses the elements in an array, but I do not quite understand what's going on inside it. This is the code:
int middleIndex = (array.length) / 2;
for (int i = 0; i < middleIndex; i++) {
int temporaryVariable = array[i];
array[i] = array[array.length - 1 - i];
array[array.length - 1 - i] = temporaryVariable;
}
What exactly does the two lines below int temporaryVariable = array[i] do? How exactly does it reverse the elements?
It effectively reverses the elements of the array by swapping first with last element, second with second_last etc. In this way the number of operations are ayrray_length / 2.
The 2 lines after int temporaryVariable = array[i]; simply swap the i'th element with the i'th from last element, and we run this loop half time the number of elements in array.
First of all remember that array indexes start from 0.
So the index of the last element is the array.length - 1.
Those 3 lines are swapping the first item with the last item, then the 2nd item with the 2nd-from-last item, etc. The temporaryVariable is used as a temporary place to store one of the values during swapping, so that it doesn't get lost when it is overwritten by the other value.
Take a copy of the value at i:
int temporaryVariable = array[i];
Put item i from the end of the array (array.length - 1 - i) instead of it.
array[i] = array[array.length - 1 - i];
Put the temporarily stored item which was item i at i from the end (array.length - 1 - i).
array[array.length - 1 - i] = temporaryVariable;
The loop stops when i reaches the middle of the array. (If the array has an odd number of elements the middle one stays where it is.)
This algorithm is taking N/2 iterations of swapping values stored in an array. It starts from the beggining of the array (Index 0) and goes until its half(index N/2). It swaps the first element(indexed 0) with the last one (indexed N - 1 - 0), then swaps the second element(indexed 0 + 1) with the one before the last one(indexed N - 1 - (0 + 1)), and so on.
another part was to return the second biggest number, but for some reason it returns the third biggest number, which is really weird.
This is the code:
public static int returnSecondBiggest(int[] array) {
int largestElement = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > largestElement) {
largestElement = array[i];
}
}
int secondBiggest = Integer.MIN_VALUE;
for (int i = 0; i < array.length; i++) {
if (array[i] > secondBiggest && array[i] != largestElement) {
secondBiggest = array[i];
}
}
return secondBiggest;
}
How does it return the third when the code should return the second? I'm so lost.
I was looking over some basic questions that might be asked in an interview. Using basic for loops (No hash maps etc)I want to sum up all the matching elements in an array.For example, 6 matching elements will result in (Matched: 6) and a total of 36 in the example below.An example of this could be rolling dice, and the score is the total of all the dice that match.
public static void main(String[] args) {
int arr[] = {6,6,6,6,6,6};
int matched = 1;
int value = 0;
int total = 0;
for(int i=0;i<arr.length;i++){
for(int j=(i+1);j<arr.length;j++){
if(ar[i] == ar[j]){
matched++;
value = ar[i];
break;
}
}
total = (matched * value);
} // End for loop
System.out.println("Matched:"+(matched)+"");
System.out.println("Total:"+total);
}
But, if the array was for example...
int arr[] = {6,1,1,6,6,6};
The output I get will be (Matched:5) and an a total of 30.Can could I store the matching pair of 1's and add them to the total using as little basic code as possible?
Interpreting the question as "provide the total number of values that occur more than once and their sum", and taking into account that nothing "fancy" (sic) such as a map can be used:
int[] array = {6, 1, 1, 6, 6, 6};
int sum = 0;
int matches = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (i != j && array[i] == array[j]) {
sum += array[i];
matches++;
break;
}
}
}
System.out.println(matches); // 6
System.out.println(sum); // 26
If you are allowed to use arrays - if not too fancy - then you could use 3 loops:
The first finds minimum and maximum elements
The second determines the occurrence of each item
The third calculates the totals
In Java this would look like this:
public static void main(String[] args) {
int[] array = {6, 3, 3, 6, 6, 6, 4, 4, 20};
int min = array[0];
int max = array[0];
// Find min max
for (int i : array) {
if (i < min) {
min = i;
}
if (i > max) {
max = i;
}
}
// Use array to sum up all elements
int[] holderArray = new int[max - min + 1];
for (int i : array) {
holderArray[i - min]++;
}
// Calculate occurrence and sums
for(int i = 0; i < holderArray.length; i++) {
if(holderArray[i] > 0) {
System.out.printf("number: %2d; count: %2d; sum: %2d%n", i + min, holderArray[i], (i + min) * holderArray[i]);
}
}
}
This prints out:
number: 3; count: 2; sum: 6
number: 4; count: 2; sum: 8
number: 6; count: 4; sum: 24
number: 20; count: 1; sum: 20
I don't completely understand your question, but based from what I understood, you want to get the sum of all matched numbers if its greater than 1? In that case there is a O(n) solution that you could use.
Create an empty Map then iterate over the array, and if the current number is not within the map add it to the map with value 1, if the current element is already existing in the map then just increment it's value (val++), at the end you will have a map and for each key (each distinct number) you will have the number of matched numbers from the array as the value. All you need to do is iterate over the pairs of key,val multiply each key*val then sum up the multiplied values and you get your correct total. And if you need just the number of matched, you can in another variable sum up just the vals.
So for lets say array [1,1,5,1,5,2,2,5,1], your map will something like:
{1:4, 2:2, 5:3},
and your totals:
total matches: 9
total: 23
I hope this helps!
Here is a code fragment I just wrote. This method takes in an array of integers and creates a map of each unique integer and it's count in the list. In the second part of the method, the HashMap object countOfNumbersMap is iterated and the sum of each element is printed.
private void findSumOfMatchingNumbers(int array[]) {
HashMap<Integer, Integer> countOfNumbersMap = new HashMap<>();
// Setting up the map of unique integers and it's count
for (int i = 0 ; i < array.length ; i++) {
if (countOfNumbersMap.containsKey(array[i])) {
int currentCount = countOfNumbersMap.get(array[i]);
countOfNumbersMap.put(array[i], currentCount + 1);
} else {
countOfNumbersMap.put(array[i], 1);
}
}
for (Integer integer : countOfNumbersMap.keySet()) {
int sum = countOfNumbersMap.get(integer) * integer;
System.out.println(String.format("Number = %d, Sum = %d", integer, sum));
}
}
The worst case runtime of the program is O(n).
If the range of your integers is limited, the easiest way to do this would be to create a histogram (i.e. create an array, where under index i you store the number of occurrences of the number i).
From that, it's easy to find elements that occur more than once, and sum them up. This solution has a complexity of O(n+k), where k is the range of your integers.
Another solution is to sort the array,then the matching numbers will be next to each other, and it's easy to count them. This has O(nlogn) complexity.
If these methods are not allowed, here is a solution in O(n^2) that only uses for loops:
Sum up the whole array
With a double loop, find all elements that are unique, subtract them from the sum, and count their number.
The remaining sum is the sum of all elements occurring more than once, and the count of unique elements subtracted from the length of the array gives the number of matching element.
I have the methods to find the smallest and largest value, and also to place them where they need to be. I also have a method to call those methods, and shrink to a subarray. The problem is, even though it is sorting, I can't print the array once I've moved into the subarray. Please help, there has to be a better way and I've banged my head against the wall for a while now.
package mySort;
import java.util.Arrays;
public class MyAlg {
public static int findSmall(int[] input){
int sm = input[0];
for(int i = 0; i <= input.length - 1; i++){
if(sm < input[i])
sm = input[i];
}
input[0] = sm;
return sm;
}
public static int findLarge(int[] input){
int lg = input[input.length -1];
for(int i = 0; i <= input.length - 1; i++){
if(input[i] > lg)
lg = input[i];
}
input[input.length -1] = lg;
return lg;
}
public static int[] sort(int[] input){
findSmall(input);
findLarge(input);
for(int i = 0; i<= (input.length - 1) / 2; i++){
int[] tmp = Arrays.copyOfRange(input, i + 1, input.length - 2 );
findSmall(tmp);
findLarge(tmp);
}
}
}
I am not sure if you are required to use an array or not, but if you are free to use whatever data structure you like I would recommend a TreeSet. This data structure implements SortedSet which means as the objects are added they are sorted already for you. Then you can use methods such as
first() - to return the lowest value
last() - to return the highest value
Then you could remove those highest and lowest elements or use these methods after that
ceiling(int) - highest number lower than given int
floor(int) - smallest number higher than given int
Lmk if you need more help or just need an implementation for an array.
Unfortunately your code is quite flawed, so I just rewrote everything. The below code will sort any int[] by placing the smallest int in the input array in the left most unfilled position of a new array and placing the biggest in the right most unfilled position of a new array, until the new array is a sorted version of the input array. Enjoy
private static int[] sort(int[] input) {
//create an empty array the same size as input
int[] sorted = new int[input.length];
//create another empty array the same size as input
int[] temp = new int[input.length];
// copy input into temp
for (int i = 0; i <= (input.length - 1); i++) {
temp[i] = input[i];
}
//create variables to tell where to put big and small
//in the sorted array
int leftIndex = 0;
int rightIndex = sorted.length - 1;
//create variables to hold the biggest and smallest values in
//input. For now we'll give them the values of the first element
//in input, they'll change
int big = input[0];
int small = input[0];
// sort
//sort the array as you described
while (temp.length != 0) {
//find the biggest and smallest value in temp
big = findBig(temp);
small = findSmall(temp);
//place the biggest at the end of the sorted array
//and place the smallest at the beginning of the sorted array
sorted[leftIndex] = small;
sorted[rightIndex] = big;
//move the left index of the sorted array up, so we don't over write
//the element we put in on the next iteration, same for the right index to,
//but down
leftIndex++;
rightIndex--;
if(temp.length != 1){
//remove the biggest and smallest values from the temp array
temp = removeElement(temp, big);
temp = removeElement(temp, small);
}else{
//only remove one element in the event the array size is odd
//also not at this point leftIndex == rightIndex as it will be the last
//element
temp = removeElement(temp, big);
}
//repeat, until the temp array is empty
}
// print out the content of the sorted array
for (int i = 0; i <= (sorted.length - 1); i++) {
System.out.println("Index " + i + ": " + sorted[i]);
}
//return the sorted array
return sorted;
}
//find the smallest number in an int array and return it's value
private static int findSmall(int[] input) {
int smallest = input[0];
for (int i = 0; i <= (input.length - 1); i++) {
if (smallest > input[i]) {
smallest = input[i];
}
}
return smallest;
}
//find the biggest value in an int array and return it's value
private static int findBig(int[] input) {
int biggest = input[0];
for (int i = 0; i <= (input.length - 1); i++) {
if (biggest < input[i]) {
biggest = input[i];
}
}
return biggest;
}
//remove an element from an int array, based on it's value
private static int[] removeElement(int[] input, int elementValue) {
//create a temp array of size input - 1, because there will be one less element
int[] temp = new int[input.length - 1];
//create variable to tell which index to remove, set to 0 to start
//will change unless it is right
int indexToRemove = 0;
//find out what the index of the element you want to remove is
for (int i = 0; i <= (input.length - 1); i++) {
if (input[i] == elementValue) {
//assign the value to
indexToRemove = i;
break;
}
}
//variable that says if we've hit the index we want to remove
boolean removeFound = false;
for (int i = 0; i <= (input.length - 1); i++) {
//check if we are at the index we want to remove
if (indexToRemove == i) {
//if we are say so
removeFound = true;
}
//done if we aren't at the index we want to remove
if (i != indexToRemove && removeFound == false) {
//copy input to temp as normal
temp[i] = input[i];
}
//done if we've hit the index we want to remove
if (i != indexToRemove && removeFound == true) {
//note the -1, as we've skipped one and need the to decrement
//note input isn't decremented, as we need the value as normal
//note we skipped the element we wanted to delete
temp[i - 1] = input[i];
}
}
//return the modified array that doesn't contain the element we removed
//and it is 1 index smaller than the input array
return temp;
}
}
Also, I'd place all of these methods into a class Sort, but I wrote it in this way to mimic the way you wrote your code to a certain extent. This would require you to create a getSorted method, and I'd also change the sort method to a constructor if it was placed in a class Sort.
I have written an algorithm to solve your this problem. Using divide and conquer we can solve this problem effectively. Comparing each value to every one the smallest and the largest value can be found. After cutting off 2 values the first one(smallest) and the last one (largest) the new unsorted array will be processed with the same algorithm to find the smallest and largest value.
You can see my algorithm in [GitHub] (https://github.com/jabedhossain/SortingProblem/)
Although its written in C++, the comments should be enough to lead you through.
I have an ArrayList which contain 10 elements and a variable int = 12. Now I want to count how many elements are in array and if are less than 12 to start to count again from 0 and stop to index 2 and remove it, until I will have one element in my array. I tried the following:
int j = 12;
int l = 0;
// Here I check if j is less than array.size
while (j < array.size()) {
for (int i = 0; i < array.size(); i++) {
if (j == i + 1) {
array.remove(i);
}
}
}
// Here is for j greater than array.size
while (array.size() != 1) {
for (int i = 0; i < array.size(); i++) {
l = j - array.size();
if (l < array.size()) {
array.remove(l);
}
}
}
System.out.println(array);
UPDATE:
MyArray = {1,2,3,4,5,6,7,8,9,10};
int=12;
MyArray contain just 10 elements, but I want to delete the index with number 12, as long as index 12 does not exist I should start to count again from zero, and the number 12 is at index 2, That's why I should delete the index with number 2. The second iteration MyArray will contain just 9 elements, and again 12-9=3, I should delete the index with number 3, until I will have just one element in MyArray
Instead of looping twice through the array to remove the last n elements until the length of the list equals j, you could simply use:
while (j < array.size()) {
array.remove(j - 1);
}
If you always want to remove index 2, you could do:
while (array.size() >= 3) { // otherwise you will get a ArrayIndexOutOfBoundsException
array.remove(2);
}
However, you will have two elements left in your ArrayList instead of 1 (at index 0 and 1). You cannot delete ìndex 2 at that point, because it is not a valid index any longer.
Thus, you could either remove index 0/1 afterwards or what I think you want to achieve:
while (array.size() >= 2) { // otherwise you will get a ArrayIndexOutOfBoundsException
array.remove(1);
}
Then only one element will remain in your list at index 0.
Edit: for the update of your question it is
int originalSize = array.size();
while (array.size() >= originalSize - j) { // otherwise you will get a ArrayIndexOutOfBoundsException
array.remove(originalSize - j);
}
However, you will always be left with size - j items in your list. You cannot remove index 3, for example, until you have only one element in your list.
An answer to the updated question:
When you have a list of length 10 and you want to delete the "12th element" you can use the modulo operator:
ArrayList<...> someList = ...;
int toDelete = 12;
int deleteInRange = toDelete % someList.size();
someList.remove(deleteInRange);
The modulo operator will deliver the rest of the integerdivision 12 / 10 (toDelete % someList.size())
You can use this code snippet in a loop in order to remove multiple elements.
If you always want to remove index 2, you could do:
l = j - array.size();
Change this line as below:
int sum = 0;
sum = l - array.size();
if (sum > 0) {
array.remove(sum);
} else {
sum = array.size() - l;
array.remove(sum);
}