I have an assignment to count the assignments and comparisons in a selection sort. For some reason my assignment counter isn't incrementing. I've tried adding it above the swap and I've tried incorporating into the swap method - to no avail. Any ideas why it's not working?
Update: The counter doesn't work for this
Integer[] test = {1, 0, 4, 2};
selectionSort(test);
But it does work for this:
selectionSort(new Integer[] {1, 0, 4, 2});
Anyone know why?
public static void selectionSort(Integer[] array)
{
int assignmentCounter = 0;
int comparisonCounter = 0;
int i, j;
for(i = 0; i < array.length; i++)
{
int minIndex = i;
for(j = i + 1; j < array.length; j++)
{
comparisonCounter++;
if(array[j].compareTo(array[minIndex]) < 0)
{
minIndex = j;
assignmentCounter++;
swap(array,minIndex,i);
}
}
}
System.out.println("Selection Sort Comparisons: " + comparisonCounter + "\nSelection Sort Assignments: " + assignmentCounter);
for(int k = 0; k < array.length; k++)
{
System.out.print(array[k] + ", ");
}
System.out.println("\n\n ");
}
Thank you!
When I run this
public static void main(String[] args) {
selectionSort(new Integer[] { 1, 0, 4, 2 });
}
I get the output
Selection Sort Comparisons: 6
Selection Sort Assignments: 2
0, 1, 2, 4,
Are you possibly expecting a static or other local variable also called assignmentCounter to be changed?
The variable assignmentCounter declared in selectionSort is local to that method. Nothing outside of it can see it.
Related
There is a 2D array. int[][] arr= {{1,3,4,1},{5,7,8,9},{6,1,2,1}} . I want to get summation of each columns and get the maximum number. Finally it should be returned {5,7,8,9} . Because it has the maximum summation. I have mentioned i tried code below and it not return correct value. Help me to solve this
Your k is supposed to track the index with the greatest sum. So when you are resetting max you need to say k=i. You said i=k by mistake. Changing it makes your program run as desired.
EDIT: There was once code in the original question, to which this solution referred.
If the max column is expected, then I might have a solution:
import java.util.Arrays;
public class ArrayTest {
public static void main(String args[]) {
/*
* 1 3 4 1
* 5 7 8 9
* 6 1 2 1
*
*/
int[][] arr = {{1, 3, 4, 1}, {5, 7, 8, 9}, {6, 1, 2, 1}};
int m = arr.length;
int n = arr[0].length;
int[] arr2 = new int[n];
int p = 0;
int[][] colArray = new int[n][m];
for (int i = 0; i < n; i++) {
int[] arr_i = new int[m];
//System.out.println("i = " + i);
//System.out.println("p = " + p);
int sum = 0;
for (int j = 0; j < m; j++) {
arr_i[j] = arr[j][p];
sum += arr_i[j];
}
//System.out.println("Col: " + p + " : " + Arrays.toString(arr_i));
colArray[i] = arr_i;
arr2[p] = sum;
p++;
}
System.out.println("Sum: " + Arrays.toString(arr2));
int k = 0;
int max = arr2[0];
for (int i = 0; i < 3; i++) {
if (arr2[i] > max) {
max = arr2[i];
k = i;
}
}
System.out.println("Column index for max: " + k);
System.out.println("Column: " + Arrays.toString(colArray[k]));
}
}
Output:
Sum: [12, 11, 14, 11]
Column index for max: 2
Column: [4, 8, 2]
I recommend you find a way to break down your problem into smaller parts, solve each part with a function, then combine everything into a solution.
Example solution below:
public class Main {
public static long sum(int[] a){
long sum = 0;
for (int i : a) {
sum = sum + i;
}
return sum;
}
public static int[] withMaxSumOf(int[][] as){
// keep one sum for each array
long[] sums = new long[as.length];
// calculate sums
for (int i = 0; i < as.length; i++) {
int[] a = as[i];
sums[i] = sum(a);
}
// find the biggest one
int maxIndex = 0;
long maxSum = sums[0];
for (int i=1;i<sums.length;i++){
if (sums[i] > maxSum){
maxSum = sums[i];
maxIndex = i;
}
}
// return array that had biggest sum
return as[maxIndex];
}
public static void main(String[] args){
int[][] arr= {{1,3,4,1},{5,7,8,9},{6,1,2,1}};
// find the one with max sum
int[] max = withMaxSumOf(arr);
// print it
for (int i = 0; i < max.length; i++) {
int x = max[i];
if (i > 0) System.out.print(", ");
System.out.print(x);
}
System.out.println();
}
}
I think this might be your problem:
for(int i=0;i<3;i++) {
if(arr2[i]>max) {
max=arr2[i];
i=k;
}
}
I think that i=k really needs to be k=i.
Note also that it's worthwhile using better variable names. index instead of i, for instance. What is k? Call it "indexForHighestSum" or something like that. It doesn't have to be that long, but k is a meaningless name.
Also, you can combine the summation loop with the find-highest loop.
In the end, I might write it like this:
public class twoDMax {
public static void main(String args[]) {
int[][] arr= { {1,3,4,1}, {5,7,8,9}, {6,1,2,1} };
int indexForMaxRow = 0;
int previousMax = 0;
for(int index = 0; index < 4; ++index) {
int sum = 0;
for(int innerIndex = 0; innerIndex < 4; ++innerIndex) {
sum += arr[index][innerIndex];
}
if (sum > previousMax) {
previousMax = sum;
indexForMaxRow = index;
}
System.out.println(indexForMaxRow);
for(int index = 0; index < 4; ++index) {
System.out.println(arr[indexForMaxRow][index]);
}
}
}
I did a few other stylish things. I made use of more obvious variable names. And I am a little nicer about whitespace, which makes the code easier to read.
public static void main( String args[] ) {
int[][] arr = { { 1, 3, 4, 1 }, { 5, 7, 8, 9 }, { 6, 1, 2, 1 } };
int indexOfMaxSum = 0;
int maxSum = 0;
for ( int i = 0; i < arr.length; i++ ) {
int[] innerArr = arr[ i ]; // grab inner array
int sum = 0; // start sum at 0
for ( int j : innerArr ) {
// iterate over each int in array
sum += j; // add each int to sum
}
if ( sum > maxSum ) {
// if this sum is greater than the old max, store it
maxSum = sum;
indexOfMaxSum = i;
}
}
System.out.println( String.format( "Index %d has the highest sum with a sum of %d", indexOfMaxSum, maxSum ) );
int [] arrayWithLargestSum = arr[indexOfMaxSum]; // return me
}
why isn't this code working?
I'm supposed to write a function which removes the odd numbers from an array. here is my code but I don't know where it went wrong. It's giving me an error.
public class Test{
public static int [] removeOdd(int[] input){
int c = 0;
for(int i=0; i<input.length; i++){
if(input[i]%2==0){
c++;
}
}
int [] a = new int[c];
for(int i=0; i<input.length; i++){
if(input[i]%2==0){
a[i] = input[i];
}
}
return a;
}
public static void main(String [] args){
int [] mixedArray = {21, 33, 44, 66, 11, 1, 88, 45, 10, 9};
for (int i = 0; i < mixedArray.length; i++) {
System.out.print(mixedArray[i] + " ");
}
System.out.println();
int [] noOdd = Test.removeOdd(mixedArray);
for (int i = 0; i < noOdd.length; i++) {
System.out.print(noOdd[i] + " ");
}
}
Thanks in advance :)
You need another index variable to access the items of a and not use i:
public static int [] removeOdd(int[] input){
int c = 0;
for(int i=0; i<input.length; i++){
if(input[i]%2==0){
c++;
}
}
int [] a = new int[c];
int k = 0;
for(int i=0; i<input.length; i++){
if(input[i]%2==0){
a[k] = input[i];
k++;
}
}
return a;
}
The index variable i iterates through input and its values do not match and will exceed the permitted values of the indexes of a so I have used k.
The problem is here:
int [] a = new int[c];
for(int i=0; i<input.length; i++){
if(input[i]%2==0){
a[i] = input[i];
}
}
This loop will iterate through the whole input array, and try to insert just the even ones into a, but a is smaller than input, because you allocated space equal to the amount of just the even numbers in input.
In your test case, your a will have size 4, but will try to access the position 6, giving you an out of bound exception.
The problem is that you are trying to insert at a[i] which you could visualise like this:
index: 0 1 2 3 4
input: [1 2 3 4 5]
a: [ 2 4 ]
However, your a array is smaller than your input array, because you have reduced the size to account for the lack of odd numbers. You actually want to do this:
index: 0 1 2 3 4
input [1 2 3 4 5]
a [2 4]
Notice how the index of both even numbers has changed. You were trying to keep it the same.
One way to solve this would be to keep a separate counter variable which tracks where you're up when inserting into a.
int[] a = new int[c];
int sizeOfA = 0;
for (int i = 0; i < input.length; i++)
{
if (input[i] % 2 == 0)
{
a[sizeOfA] = input[i];
sizeOfA++;
}
}
You can simplify the method removeOdd using Streams:
import java.util.Arrays;
public class Test {
public static int[] removeOdd(int[] input) {
return Arrays.stream(input).filter(i -> i % 2 == 0).toArray();
}
public static void main(String[] args) {
int[] mixedArray = { 21, 33, 44, 66, 11, 1, 88, 45, 10, 9 };
for (int i = 0; i < mixedArray.length; i++) {
System.out.print(mixedArray[i] + " ");
}
System.out.println();
int[] noOdd = Test.removeOdd(mixedArray);
for (int i = 0; i < noOdd.length; i++) {
System.out.print(noOdd[i] + " ");
}
}
}
Question:
You have an array of positive and negative integers, print all subsetsum which is equal to zero.
I have implemented only a simple test case here and the exception I get is ArrayIndexOutOfBoundsException.
Please help why the value is not incremented.
package app;
public class Array1
{
public static void subset(int p[])
{
int u = 0;
int s[] = new int[p.length];
if (p[0] < 0)
for (int i=0;i<p.length;i++)
{
for (int j = 0; j < p.length; j++) {
int k = p[i] + p[j];
if (k == 0)
{
System.out.println(p[i]);
System.out.println(p[j]);
s[u] = p[i];
u++; // Why u value is not incremented?
System.out.println(s[u]);
s[u] = p[j];
u++; // Why u value is not incremented?
System.out.println(s[u]);
}
}
}
for(int i = 0; i < s.length; i++)
System.out.println(s[i]);
}
public static void main(String s[])
{
subset(new int[] {-1, -2, -3, -4, 4, 3, 2, 1});
}
}
The problem is, int s[]=new int[p.length]; as the number of pairs can be more that (input array length itself) is the reason you get ArrayIndexOutOfBoundsException.
You can use a dynamic list for this purpose:
List<Integer> s = new ArrayList<Integer>();
// s.add(<elem>); // no need for variable u - increment :)
OK, so I found this question from a few days ago but it's on hold and it won't let me post anything on it.
***Note: The values or order in the array are completely random. They should also be able to be negative.
Someone recommended this code and was thumbed up for it, but I don't see how this can solve the problem. If one of the least occurring elements isn't at the BEGINNING of the array then this does not work. This is because the maxCount will be equal to array.length and the results array will ALWAYS take the first element in the code written below.
What ways are there to combat this, using simple java such as below? No hash-maps and whatnot. I've been thinking about it for a while but can't really come up with anything. Maybe using a double array to store the count of a certain number? How would you solve this? Any guidance?
public static void main(String[] args)
{
int[] array = { 1, 2, 3, 3, 2, 2, 4, 4, 5, 4 };
int count = 0;
int maxCount = 10;
int[] results = new int[array.length];
int k = 0; // To keep index in 'results'
// Initializing 'results', so when printing, elements that -1 are not part of the result
// If your array also contains negative numbers, change '-1' to another more appropriate
for (int i = 0; i < results.length; i++) {
results[i] = -1;
}
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
count++;
}
}
if (count <= maxCount) { // <= so it admits number with the SAME number of occurrences
maxCount = count;
results[k++] = array[i]; // Add to 'results' and increase counter 'k'
}
count = 0; // Reset 'count'
}
// Printing result
for (int i : results) {
if (i != -1) {
System.out.println("Element: " + i + ", Number of occurences: " + maxCount);
}
}
}
credit to: https://stackoverflow.com/users/2670792/christian
for the code
I can't thumbs up so I'd just like to say here THANKS EVERYONE WHO ANSWERED.
You can also use an oriented object approach.
First create a class Pair :
class Pair {
int val;
int occ;
public Pair(int val){
this.val = val;
this.occ = 1;
}
public void increaseOcc(){
occ++;
}
#Override
public String toString(){
return this.val+"-"+this.occ;
}
}
Now here's the main:
public static void main(String[] args) {
int[] array = { 1,1, 2, 3, 3, 2, 2, 6, 4, 4, 4 ,0};
Arrays.sort(array);
int currentMin = Integer.MAX_VALUE;
int index = 0;
Pair[] minOcc = new Pair[array.length];
minOcc[index] = new Pair(array[0]);
for(int i = 1; i < array.length; i++){
if(array[i-1] == array[i]){
minOcc[index].increaseOcc();
} else {
currentMin = currentMin > minOcc[index].occ ? minOcc[index].occ : currentMin;
minOcc[++index] = new Pair(array[i]);
}
}
for(Pair p : minOcc){
if(p != null && p.occ == currentMin){
System.out.println(p);
}
}
}
Which outputs:
0-1
6-1
Explanation:
First you sort the array of values. Now you iterate through it.
While the current value is equals to the previous, you increment the number of occurences for this value. Otherwise it means that the current value is different. So in this case you create a new Pair with the new value and one occurence.
During the iteration you will keep track of the minimum number of occurences you seen.
Now you can iterate through your array of Pair and check if for each Pair, it's occurence value is equals to the minimum number of occurences you found.
This algorithm runs in O(nlogn) (due to Arrays.sort) instead of O(n²) for your previous version.
This algorithm is recording the values having the least number of occurrences so far (as it's processing) and then printing all of them alongside the value of maxCount (which is the count for the value having the overall smallest number of occurrences).
A quick fix is to record the count for each position and then only print those whose count is equal to the maxCount (which I've renamed minCount):
public static void main(String[] args) {
int[] array = { 5, 1, 2, 2, -1, 1, 5, 4 };
int[] results = new int[array.length];
int minCount = Integer.MAX_VALUE;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
results[i]++;
}
}
if (results[i] <= minCount) {
minCount = results[i];
}
}
for (int i = 0; i < results.length; i++) {
if (results[i] == minCount) {
System.out.println("Element: " + i + ", Number of occurences: "
+ minCount);
}
}
}
Output:
Element: 4, Number of occurences: 1
Element: 7, Number of occurences: 1
This version is also quite a bit cleaner and removes a bunch of unnecessary variables.
This is not as elegant as Iwburks answer, but I was just playing around with a 2D array and came up with this:
public static void main(String[] args)
{
int[] array = { 3, 3, 3, 2, 2, -4, 4, 5, 4 };
int count = 0;
int maxCount = Integer.MAX_VALUE;
int[][] results = new int[array.length][];
int k = 0; // To keep index in 'results'
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
count++;
}
}
if (count <= maxCount) {
maxCount = count;
results[k++] = new int[]{array[i], count};
}
count = 0; // Reset 'count'
}
// Printing result
for (int h = 0; h < results.length; h++) {
if (results[h] != null && results[h][1] == maxCount ) {
System.out.println("Element: " + results[h][0] + ", Number of occurences: " + maxCount);
}
}
Prints
Element: -4, Number of occurences: 1
Element: 5, Number of occurences: 1
In your example above, it looks like you are only using ints. I would suggest the following solution in that situation. This will find the last number in the array with the least occurrences. I assume you don't want an object-oriented approach either.
int [] array = { 5, 1, 2, 40, 2, -1, 3, 2, 5, 4, 2, 40, 2, 1, 4 };
//initialize this array to store each number and a count after it so it must be at least twice the size of the original array
int [] countArray = new int [array.length * 2];
//this placeholder is used to check off integers that have been counted already
int placeholder = Integer.MAX_VALUE;
int countArrayIndex = -2;
for(int i = 0; i < array.length; i++)
{
int currentNum = array[i];
//do not process placeholders
if(currentNum == placeholder){
continue;
}
countArrayIndex = countArrayIndex + 2;
countArray[countArrayIndex] = currentNum;
int count = 1; //we know there is at least one occurence of this number
//loop through each preceding number
for(int j = i + 1; j < array.length; j++)
{
if(currentNum == array[j])
{
count = count + 1;
//we want to make sure this number will not be counted again
array[j] = placeholder;
}
}
countArray[countArrayIndex + 1] = count;
}
//In the code below, we loop through inspecting each number and it's respected count to determine which one occurred least
//We choose Integer.MAX_VALUE because it's a number that easily indicates an error
//We did not choose -1 or 0 because these could be actual numbers in the array
int minNumber = Integer.MAX_VALUE; //actual number that occurred minimum amount of times
int minCount = Integer.MAX_VALUE; //actual amount of times the number occurred
for(int i = 0; i <= countArrayIndex; i = i + 2)
{
if(countArray[i+1] <= minCount){
minNumber = countArray[i];
minCount = countArray[i+1];
}
}
System.out.println("The number that occurred least was " + minNumber + ". It occured only " + minCount + " time(s).");
I want to print the contents of the second half of an array, or copy it to another new array.
I have this method:
public static void evaluateF3(int[] anArray) {
int[] array2 = new int[anArray.length/2];
for( int i = 0; i<array2.length; i++) {
for(int j= (anArray)/2; j<anArray.length;j++) {
array2[i]= anArray[j];
System.out.print(" "+ array2[i]);
}
}
}
However it prints the same number of times as the inside for loop, when I only want to print once. I've tried taking the statement outside of the for loop, but then it just says it cannot find 'i'. How do I solve this problem?
Why don't you put it outside the inner loop, but still inside the outer loop, then it should print out properly.
Btw: you got a compile error in your second loop. Either you meant to say j= anArray.length; or j = anArray.length/2. In either case you forgot the .length
I figured out your problem you dont need the second loop
public static void evaluateF3(int[] anArray) {
int[] array2 = new int[anArray.length / 2];
for (int i = 0; i < array2.length; i++) {
array2[i] = anArray[i + (array2.length)];
System.out.print(" " + array2[i]);
}
}
Let me know!
Maybe you're looking to do something like this?
public static void evaluateF3(int[] anArray) {
int[] array2 = new int[anArray.length/2];
for(int i = 0, j= array2.length; j<anArray.length;i++, j++) {
array2[i]= anArray[j];
System.out.print(" "+ array2[i]);
}
}
int[] a = { 1, 2, 3, 4, 5, 6, 7, 8 };
evaluateF3(a); // 5 6 7 8
int[] a = { 0, 1, 1, 0, 0, 0, 2, 2 };
evaluateF3(a); // 0 0 2 2
You cannot divide an array int[] over 2: (anArray)/2
I believe an example of the code you're looking for is as follows:
public static void evaluateF3(int[] array1) {
int[] array2 = new int[array1.length / 2];
System.arraycopy(array1, array1.length / 2, array2, 0, array2.length);
for (int i = 0; i < array2.length; i++)
{
System.out.println(array2[i]);
}
}
I think(1) you want to copy the upper half of elements into a new array. Then you just need one for loop (if you want to do it with loops):
public static void evaluateF3(int[] anArray) {
// assuming that anArray.size() is even!!
int[] array2 = new int[anArray.length/2];
for(int i = 0; i < array2.length; i++) {
array2[i]= anArray[i + anArray.length/2];
System.out.print(" "+ array2[i]);
}
}
(1) Just read your comment to another answer, I think I got it right
for( int i = 0; i<array2.length; i++)
{
for(int j= (anArray.length)/2; j<anArray.length;j++)
{
array2[i]= anArray[j];
}
System.out.print(" "+ array2[i]);
}
That would print the value of each index in the array2. Do you want it to print once after both of the loops?