Removing a redundant variable/shortening code - java

I need to remove the "min" variable and still allow the sorting program to run however, I am confused on where exactly to start.
int[] A = {13, 5, 2, 0, 3, 1, 21, 1, 8};
for (int k=0; k<A.length-1; k++) {
int min = A[k];
int minPosition = k;
for (int i=k+1; i<A.length; i++) {
if (A[i] < min) {
min = A[i];
minPosition = i;
}
}
int temp = A[k];
A[k] = A[minPosition];
A[minPosition] = temp;
}
for (int i=0; i<A.length; i++) {
System.out.println (A[i]);
}

You have both min and minPosition:
int min = A[k];
int minPosition = k;
Start by removing the declaration for min altogether (delete the line int min = A[k]), delete the line min = A[i], and finally, edit the if statement from this:
if (A[i] < min) {
...
}
to this:
if (A[i] < A[minPosition]) {
...
}

You have 2 variables that are doing the same job :
i) min which keeps track of the minimum in the array
ii) minPosition which is index of the min value.
You can simply compare everytime with the element at minPosition and swap it in the end.
class Main {
public static void main(String args[]) {
int[] A = { 13, 5, 2, 0, 3, 1, 21, 1, 8 };
for (int k = 0; k < A.length - 1; k++) {
// int min = A[k];
int minPosition = k;
for (int i = k + 1; i < A.length; i++) {
if (A[i] < A[minPosition]) {
minPosition = i;
}
}
int temp = A[k];
A[k] = A[minPosition];
A[minPosition] = temp;
}
// for (int i = 0; i < A.length; i++) {
System.out.println(Arrays.toString(A));
// }
}
}

Related

how can fix the error in this code and how can change from for loop to recursion ? i'm beginner in programming :)

i try to make method that can be find the profit for some input and calculation.
but i think there a problem in a length of Array or somewhat i don't know.
also i wanna try it by using recursive but how to implement ?
please i need your helps ^_^
thanks
public class MatlabLAB2 {
public static void main(String[] args) {
int capital = 100;
int nDay = 7;
int[] buyP = {5, 20, 7, 10, 4, 80, 1};
int[] sellP = {25, 50, 100, 3, 10, 2, 95};
findProfit(capital, nDay, buyP, sellP);
}
public static void findProfit(int capital, int NDay, int[] BuyingP, int[] SellingP) {
int[] Array = new int[NDay];
int Profit = 0;
for (int i = 0; i <= BuyingP.length; i++) {
for (int j = i; j <= SellingP.length; j++) {
for (int k = 0; k <= NDay-1; k++) {
Array[k] = (capital / BuyingP[i]) * SellingP[j];
}
Profit = findMaxOfArray(Array);
}
}
System.out.println(Profit);
}
public static int findMaxOfArray(int[] a) {
int max = 0;
for (int i = 0; i <= a.length-1; i++) {
if (a[i] >= max) {
max = a[i];
}
}
return max;
}
}
the result:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 7
at matlab.lab.pkg2.MatlabLAB2.findProfit(MatlabLAB2.java:24)
at matlab.lab.pkg2.MatlabLAB2.main(MatlabLAB2.java:11)
Java Result: 1
You are iterating the loop till
(int i = 0; i <= BuyingP.length; i++)
it should be iterated till
(int i = 0; i < BuyingP.length; i++)
same with j loop
You have two options to fix this.
1.
public static void findProfit(int capital, int NDay, int[] BuyingP, int[] SellingP) {
int[] Array = new int[NDay];
int Profit = 0;
for (int i = 0; i <= BuyingP.length-1; i++) {
for (int j = i; j <= SellingP.length-1; j++) {
for (int k = 0; k <= NDay-1; k++) {
Array[k] = (capital / BuyingP[i]) * SellingP[j];
}
Profit = findMaxOfArray(Array);
}
}
System.out.println(Profit);
}
2.
public static void findProfit(int capital, int NDay, int[] BuyingP, int[] SellingP) {
int[] Array = new int[NDay];
int Profit = 0;
for (int i = 0; i < BuyingP.length; i++) {
for (int j = i; j < SellingP.length; j++) {
for (int k = 0; k <= NDay-1; k++) {
Array[k] = (capital / BuyingP[i]) * SellingP[j];
}
Profit = findMaxOfArray(Array);
}
}
System.out.println(Profit);
}
Because in your code your array goes from 0 to 6 and you are trying to take array[7] which is out of your array's bound.

How to shift elements to left after removing array element?

I was asked to write, to remove the element (lets say k=30) from the array and shift the other elements to its left without using inbuilt methods.
I have tried the below approach.
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = new int[] { 1, 2, 30, 4, 5, 30, 6 };
int k = 30;
int count = 0;
System.out.println("---Original Array------");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
for (int i = 0; i < arr.length; i++) {
if (arr[i] == k)
count++;
}
for (int j = 0; j < count; j++) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == k) {
for (int l = i; l < arr.length - 1; l++) {
arr[l] = arr[l + 1];
}
}
}
}
System.out.println("---Modified Array------");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
I need output like this: [1 2 4 5 6 0 0]
But the output from the above logic is: [1 2 4 5 6 6 6]
Also, I'm worried about using nested for loops here. Is there any way that we can reduce the time complexity with out using any inbuilt methods?
Here is another variant:
int[] arr = new int[] { 1, 2, 30, 4, 5, 30, 6 };
int k = 30;
int j = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] != k) {
arr[j++] = arr[i];
}
}
while (j < arr.length) {
arr[j++] = 0;
}
In order to not change your approach drastically, I would suggest adding another iteration of the array at the end, to insert 0s to count-many indices from the end of your array.
This would be as simple as adding the following snippet:
// nested for loop
// ...
// set trailing elements to 0s
for (int i = 0; i < count ; i++)
arr[arr.length-1-i] = 0;
System.out.println("\n---Modified Array------");
// ...
There are some cleaner/more-efficient ways of solving this problem.
Based exactly on your approach, I went ahead and made a modification to your nested loop to not require another iteration.
for (int j = 0; j < count; j++) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == k) {
for (int l = i; l < arr.length - 1; l++)
arr[l] = arr[l + 1];
// since we have performed the shifting, we can safely set the last element to 0
arr[arr.length-1] = 0; // <----- this was missing!!
}
}
}
The following code gives the desired result:
int [] arr = { 1, 2, 30, 4, 5, 30, 6 };
int k = 30;
int elementCount = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == k) {
++elementCount;
}
}
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == k) {
count++;
for (int j = i; j < arr.length-1; j++) {
arr[j] = arr[j+1];
}
arr[arr.length-1] = 0;
}
if (count == elementCount) {
break;
}
}
I don't know if it helps. This is a simplified aproach, that is easier to read and understand(at least for people that learned C), that does removal as required....
public static void main(String[] args) {
int[] arr = new int[] { 1, 2, 30, 4, 5, 30, 6 };
int k = 30;
int i=0;
int j=0;
for(;j<arr.length;i++,j++){
if((arr[i]=arr[j])==k) i--;
}
while(i<j)arr[i++]=0;
System.err.println(Arrays.toString(arr));
}
output:[1, 2, 4, 5, 6, 0, 0]
First version with a small fix on your code. You issue is that the shifted elements need to be replaced by zero. Which require basically an if statement with the arr.length - count
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = new int[] { 1, 2, 30, 4, 5, 30, 6 };
int k = 30;
int count = 0;
System.out.println("---Original Array------");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println("");
for (int i = 0; i < arr.length; i++) {
if (arr[i] == k)
count++;
}
for (int j = 0; j < count; j++) {
for (int i = 0; i < arr.length; i++) {
if(i >= arr.length - count){
arr[i] = 0;
}else {
if (arr[i] == k) {
for (int l = i; l < arr.length - 1; l++) {
arr[l] = arr[l + 1];
}
}
}
}
}
System.out.println("---Modified Array------");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println("");
}
Which gives output
---Original Array------
1 2 30 4 5 30 6
---Modified Array------
1 2 4 5 6 0 0
Now, we can simplify the code also
public static void main(String[] args) {
int[] arr = new int[] { 1, 2, 30, 4, 5, 30, 6 };
int k = 30;
int count = 0;
System.out.println("---Original Array------");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println("");
for(int i = 0; i < arr.length; i++){
if(arr[i]==k){
count++;
}else{
arr[i-count] = arr[i];
}
}
for(int i = 1; i <= count; i++){
arr[arr.length - i] = 0;
}
System.out.println("---Modified Array------");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println("");
}
which give the same output

Finding the mode of an array Java

I've got to find the mode of an array. I am a bit embarrassed to admit that I've been stuck on this for a day. I think I've overthought it a bit - my method just gets longer and longer. The real issue that I keep running into is that when there isn't one mode (two numbers appear with the same frequency) I need to return Double.NaN.
Here's what I've tried:
private double[] data = {1, 1, 2, 2, 2, 3, 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9};
if(data.length != 0){
double maxValue = -1;
int maxCount = 0;
for(int i = 0; i < data.length; i++) {
int count = 0;
for(int j = 0; j < data.length; j++) {
if(data[j] == data[i]) {
count++;
}
}
if(count > maxCount) {
maxValue = (int) data[i];
maxCount = count;
}
}
return maxValue;
}else{
return Double.NaN;
}
This actually returns the mode, but it can't deal with two modes. Here's my most recent attempt, but it's only half complete:
private double[] data = {1, 1, 2, 2, 2, 3, 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9};
public void mode(){
int[] frequency = new int[data.length];
double[] vals = new double[data.length];
for(int i = 0; i < data.length; i++){
frequency[i] = occursNumberOfTimes(data[i]);
}
boolean uniform = false;
for(int g = 0; g < frequency.length && !uniform; g++){
if(frequency[0] != frequency[g]){
uniform = false;
}
int[] arr = new int[frequency.length-1];
for(int j = 1; j < frequency.length; j++){
if(frequency[j] > frequency[j-1]){
int mod = 0;
for(int k = 0; k < arr.length; k++){
if(k == j){
mod += 1;
arr[k] = frequency[k + mod];
}else{
arr[k] = frequency[k + mod];
}
}
}
}
frequency = arr;
}
}
private int occursNumberOfTimes(double value){
int count = 0;
for(int i = 0; i < data.length; i++){
if(data[i] == value){
count++;
}
}
return count;
}
I sorta got lost in the second try, I just can't sort out how to deal with multiple modes. I've written out my thoughts, but I just don't know how. I can't use anything from the Arrays class, which is why I'm lost.
Does it have to be efficient? If not:
double maxValue = -1.0d;
int maxCount = 0;
for (int i = 0; i < data.length; ++i) {
double currentValue = data[i];
int currentCount = 1;
for (int j = i + 1; j < data.length; ++j) {
if (Math.abs(data[j] - currentValue) < epsilon) {
++currentCount;
}
}
if (currentCount > maxCount) {
maxCount = currentCount;
maxValue = currentValue;
} else if (currentCount == maxCount) {
maxValue = Double.NaN;
}
}
System.out.println("mode: " + maxValue);
You could track the two most common elements as was suggested in the comments, but another approach is to keep a boolean flag that indicates if the current most common element is unique. Then:
For each array element e, obtain its count as you're currently doing.
If that count is greater than the current max, set the the most common element (seen so far) to e and set the "unique" flag to true.
Otherwise, if that count is equal to the current max, set the "unique" flag to false.
At the end, just return the mode if "unique" is true, otherwise return NaN.
Here's my long, dumb solution. It works! It's a very roundabout way of getting the mode, but I'm really happy it works. I used the advice I got from some comments and looked at it differently. It was a frustrating few hours, but here it is:
public double mode2(){
if(data.length != 0){
int[] counts = new int[data.length];
double[] vals = new double[data.length];
for(int l = 0; l < data.length; l++){
counts[l] = 1;
}
for(int i = 0; i < data.length; i++){
for(int j = 0; j < data.length; j++){
if((data[i] == data[j]) && (i != j)){
vals[i] = data[i];
counts[i] += 1;
}
}
}
for(int i = 0; i < data.length; i++){
for(int j = 0; j < data.length; j++){
if((vals[i] == vals[j]) && (i != j)){
vals[i] = 0;
counts[i] = 0;
}
}
}
int counter = 0;
for(int k = 0; k < data.length; k++){
if(counts[k] != 0){
counts[counter] = counts[k];
vals[counter] = vals[k];
counter++;
}
}
int[] compactCounts = new int[counter];
double[] compactVals = new double[counter];
for(int k = 0; k < counter; k++){
if(counts[k] != 0){
compactCounts[k] = counts[k];
compactVals[k] = vals[k];
}else{
break;
}
}
for(int g = 1; g < compactVals.length; g++){
if(compactCounts[g] > compactCounts[g-1]){
compactCounts[g-1] = 0;
compactVals[g-1] = 0;
}
}
for(int g = 0; g < compactVals.length-1; g++){
if(compactCounts[g] > compactCounts[g+1]){
compactCounts[g+1] = 0;
compactVals[g+1] = 0;
}
}
int counterTwo = 0;
for(int k = 0; k < compactCounts.length; k++){
if(compactCounts[k] != 0){
compactCounts[counterTwo] = compactCounts[k];
compactVals[counterTwo] = vals[k];
counterTwo++;
}
}
int[] compactCountsTwo = new int[counterTwo];
double[] compactValsTwo = new double[counterTwo];
for(int k = 0; k < counterTwo; k++){
if(counts[k] != 0){
compactCountsTwo[k] = compactCounts[k];
compactValsTwo[k] = compactVals[k];
}else{
break;
}
}
//now populated compactTwos
//We're now setting some lesser values to 0
for(int g = 1; g < compactValsTwo.length; g++){
if(compactCountsTwo[g] > compactCountsTwo[g-1]){
compactCountsTwo[g-1] = 0;
compactValsTwo[g-1] = 0;
}
}
//now setting other lesser values to 0
for(int g = 0; g < compactValsTwo.length-1; g++){
if(compactCountsTwo[g] > compactCountsTwo[g+1]){
compactCountsTwo[g+1] = 0;
compactValsTwo[g+1] = 0;
}
}
//calling methods to shorten our arrays by dropping indexes populated by zeroes
compactValsTwo = doubleTruncator(compactValsTwo);
compactCountsTwo = intTruncator(compactCountsTwo);
//now setting some lesser values to 0
for(int g = 1; g < compactValsTwo.length; g++){
if(compactCountsTwo[g] > compactCountsTwo[g-1]){
compactCountsTwo[g-1] = 0;
compactValsTwo[g-1] = 0;
}
}
//now setting other lesser values to 0
for(int g = 0; g < compactValsTwo.length-1; g++){
if(compactCountsTwo[g] > compactCountsTwo[g+1]){
compactCountsTwo[g+1] = 0;
compactValsTwo[g+1] = 0;
}
}
//calling methods to shorten our arrays by dropping indexes populated by zeroes
compactValsTwo = doubleTruncator(compactValsTwo);
compactCountsTwo = intTruncator(compactCountsTwo);
if(compactValsTwo.length > 1){
return Double.NaN;
}else{
return compactValsTwo[0];
}
}else{
System.out.println("ISSUE");
return Double.NaN;
}
}
public double[] doubleTruncator(double[] a){
int counter = 0;
for(int k = 0; k < a.length; k++){
if(a[k] != 0){
a[counter] = a[k];
counter++;
}
}
double[] b = new double[counter];
for(int i= 0; i < counter; i++){
if(a[i] != 0){
b[i] = a[i];
}else{
break;
}
}
return b;
}
public int[] intTruncator(int[] a){
int counter = 0;
for(int k = 0; k < a.length; k++){
if(a[k] != 0){
a[counter] = a[k];
counter++;
}
}
int[] b = new int[counter];
for(int i= 0; i < counter; i++){
if(a[i] != 0){
b[i] = a[i];
}else{
break;
}
}
return b;
}
Big thanks to everybody who helped. I know it's not great (certainly not as good as the answer from #Perdi Estaquel), but I'm happy that I managed to do it.

Sorting an Array in Java, then printing it

I have an error in my code, since it is not printing all of the elements of the array after it's been sorted. Can someone spot it and help me out? (I am only in my 5th week of Java, so definitely a newbie!)
public class Test01 {
public static void main(String[] args) {
int[] arr = {1, 3, 5, 4, 2};
for (int i = 0; i < arr.length - 1; i++) {
int currentMin = arr[i];
int currentMinIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (currentMin > arr[j]){
currentMin = arr[j];
currentMinIndex = j;
}
}
if (currentMinIndex != i) {
arr[currentMinIndex] = arr[i];
arr[i] = currentMin;
}
System.out.print(arr[i] + " ");
}
}
}
The current output for this is:
1 2 3 4
So I am just missing printing the '5'
thanks for the help!
You are running the loop an index short. Change
for (int i = 0; i < arr.length - 1; i++) { // The -1 is the issue
to
for (int i = 0; i < arr.length ; i++) {
public class Test01 {
public static void main(String[] args) {
int[] arr = {1, 3, 5, 4, 2};
for (int i = 0; i < arr.length; i++) {
int currentMin = arr[i];
int currentMinIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (currentMin > arr[j]){
currentMin = arr[j];
currentMinIndex = j;
}
}
if (currentMinIndex != i) {
arr[currentMinIndex] = arr[i];
arr[i] = currentMin;
}
System.out.print(arr[i] + " ");
}
}
}

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2 MergeSort

I am trying to implement MergeSort Algorithm in Java using eclipse IDE.
I am getting following error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
It contains three methods: merge(), mergeSort() and printArray()
public class MergeSort {
public static void main(String[] args) {
int[] numbers = { 10, 5, 3, 7, 6, 2, 21, 4 };
mergeSort(numbers);
printArray(numbers);
}
public static int[] mergeSort(int[] A) {
int n = A.length;
if (n < 2) {
return A;
}
int mid = n / 2;
int[] left = new int[mid];
int[] right = new int[n - mid];
for (int i = 0; i < mid - 1; i++) {
left[i] = A[i];
}
for (int i = mid; i < n - 1; i++) {
right[i - mid] = A[i];
}
mergeSort(left);
mergeSort(right);
merge(left, right);
return A;
}
public static int[] merge(int[] A, int[] B) {
int[] C = new int[A.length + B.length];
int i = 0;
int j = 0;
int k = 0;
int nL = A.length;
int nR = B.length;
while (i < nL && j < nR) {
if (A[i] <= B[j]) {
C[k] = A[i];
k = k + 1;
i = i + 1;
} else {
C[k] = A[j];
j = j + 1;
}
k = k + 1;
}
while (i < nL) {
C[k] = A[i];
i = i + 1;
k = k + 1;
}
while (j < nR) {
C[k] = B[j];
j = j + 1;
k = k + 1;
}
return C;
}
public static void printArray(int[] A) {
for (int i = 0; i < A.length; i++) {
System.out.println(A[i]);
}
}
}
The first while loop in the merge() method is faulty. You're assigning A[j] to C[k], while it should be B[j]. Also, you're incrementing k twice for if condition.
Change the while loop to:
while (i < nL && j < nR) {
if (A[i] <= B[j]) {
C[k] = A[i];
i = i + 1;
} else {
C[k] = B[j];
j = j + 1;
}
k = k + 1;
}
But, apart from this issue, there are other issues with your code.
Firstly, your looping range is not correct. Currently you're missing out (mid - 1)th and (n - 1)th element. Change your loop to:
for (int i = 0; i < mid; i++) {
left[i] = A[i];
}
for (int i = mid; i < n; i++) {
right[i - mid] = A[i];
}
Secondly, your mergeSort() method creates a new array. You are not using the return value currently. Re-assign the return value to left and right respectively:
left = mergeSort(left);
right = mergeSort(right);
return merge(left, right);
And finally, the final result also you need to re-assign to numbers array:
numbers = mergeSort(numbers);
printArray(numbers);

Categories

Resources