Printing 0's instead of keyboard input - java

So the program is supposed to allow the user to input 10 scores and the print those scores in ascending order on the following line. For some reason it allows me to input the scores, but the following line is just filled with 0s instead of sorting the input in ascending order. I'm not sure why, but any input would be helpful.
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out
.println("Enter up to 35 scores between 0 and 100, -1 to stop:");
int[] score = new int[35];
int count = 0;
int sum = 0;
String scores = "";
for (int i = 0; i < score.length; i++) {
score[i] = keyboard.nextInt();
if (score[i] >= 0) {
scores = scores + score[i] + " ";
count++;
sum = sum + score[i];
} else
i = score.length + 1;
}
for (int i = 1; i < score.length; i++) {
int x;
int temp;
x = score[i];
temp = score[i];
for (x = i - 1; x >= 0 && score[x] > temp; x--) {
score[x + 1] = score[x];
}
score[x + 1] = temp;
}
System.out.printf("The %d scores you entered are: \n%s", count, scores);
System.out.println();
System.out.printf("The %d scored sorted in nondecreasing order are:\n",
count);
int k=1;
for (k=1; k <= count; k++) {
if (k % 11 == 0) {
System.out.println();
} else {
System.out.printf("%5d", score[k]);
}
}
for (int i = 1; i <= count; i++) {
if (i % 11 == 0) {
System.out.println();
} else {
System.out.printf("%5d", score[i]);
}
for (int j = 1; j < count; j++) {
if (Integer.compare(score[i], score[j]) < 0) {
int temp = score[i];
score[i] = score[j];
score[j] = temp;
}
}
}

I agree with comment about learning to debug. The way you have written your code, it is apparent that you are very beginner so here is the answer to help you. To answer your question, you have several logical mistakes in your program.
You can simply use break to exit out of the first for loop. so in the else statement just write break; instead of i = score.length + 1;
Next... mistake is that you are sorting entire array... However as you may have entered only 5 or 6 elements before entering -1, your first 5 or 6 elements will have values and all other values in that score array as 0. If you sort the entire array, you will obviously be going to bring 0's to the front and actual scores to the back of the array. This is the answer for your question. Sort from i = 0 to i < count. This will fix some of your issues, but you have many more issues.
There are several other issues. I hope you will be able to debug and find out.

Related

Numerically listing Arrays

So my code is having a problem. Here's what I want to do: have one array have the original set of numbers (up to 10 numbers) and then copy and paste those numbers onto the second array. And then afterwards, the second area lists those numbers from the first array numerically (going from the lowest number to the highest).
The problem is... my second output is giving me a good output with the lowest numbers going to the highest numbers, however, at the same time, I'm getting a long list of repeated numbers and a ton of zeros if I stop my code with the -9000 input. Can anyone tell me what the problem is and how to fix it? I don't want to sort this second array with the Array.sort() option, by the way. No importing anything but the scanner:
public static void main(String[] args) {
System.out.println("Input up to '10' numbers for current array: ");
int[] array1 = new int[10];
int i;
Scanner scan = new Scanner(System.in);
for (i = 0; i < 10; i++) {
System.out.println("Input a number for " + (i + 1) + ": ");
int input = scan.nextInt();
if (input == -9000) {
break;
} else {
array1[i] = input;
}
}
System.out.println("\n" + "Original Array: ");
for (int j = 0; j < i; j++) {
System.out.println((j + 1) + ": " + array1[j]);
}
System.out.println("\n" + "Organized Array: ");
int[] array2 = new int[i];
for (i = 0; i < array1[i]; i++) {
System.out.println(+array1[i]);
for (int j = 0; j < i; j++) {
int temp;
boolean numerical = false;
while (numerical == false) {
numerical = true;
for (i = 0; i < array1.length - 1; i++) {
if (array2[i] > array2[i + 1]) {
temp = array2[i + 1];
array2[i + 1] = array2[i];
array2[i] = temp;
numerical = false;
}
}
}
}
for (i = 0; i < array2.length; i++) {
System.out.println(array2[i]);
}
}
}
You have several issues that you need to fix to make your program run:
You have forgotten to copy array1 into array2:
The output that you think is coming from sorting array2 is actually from the process of sorting.
int[] array2 = new int[i];
for (int j = 0; j < i; j++) {
array2[j] = array1[j];
}
You placed the output of sorted array inside the loop that does sorting:
Check the level of curly braces, and move the output loop to after the sorting loop
for (i = 0; i < array2.length; i++) {
System.out.println(array2[i]);
}
Your sorting algorithm has an extra loop:
Having the outermost loop makes no sense: your bubblesort algorithm works perfectly without it, so you should remove the loop, and move its body up by one level of nesting:
for (i = 0; i < array1[i]; i++) { // Remove the loop
... // <<== Keep the body
}
Your innermost loop reuses i incorrectly:
Replace loop variable i with another variable, e.g. m
for (int m = 0 ; m < array2.length - 1; m++) {
if (array2[m] > array2[m + 1]) {
temp = array2[m + 1];
array2[m + 1] = array2[m];
array2[m] = temp;
numerical = false;
}
}
Demo.
in your for loop you set i limit to array1[i] value not to array lenght, surely it is wrong.
you are reusing the same index i, inside the other loops of the outer big 'for' loop, so the i value will be messed up by inner loops
you never copied the array1 values to array2

Java - I have a 2D array. How can I add blocks of it together?

I'm not sure if this is the best way to ask my question.
Basically, I have a 2D array that is being built from a text file.
It takes the first two int's for the dimensions. Then fills the array with the remaining data. That part is working fine.
In my array, I need to add each value with each adjacent value. To determine which value, when added with all of its adjacent values, is the highest. I need to do the reverse also, to find the lowest.
What kind of loop or function could I use to accomplish this? I'l create a small example below.
2 4 3 7 8
1 5 7 9 2
2 9 2 5 7
So the 2 would become a 7, the 4 would become a 14, and so on. After the math is done I need to detect which coordinate in the array is the largest number.
For simplicity, lets use the example you provided. The array is 5 by 3. Lets call the array data Try this
int totals[5][3];
for(int x = 0;x<5;x++){
for(int y = 0;y<5;y++){
int total = data[x][y]
if(x>0){
total+= data[x-1][y];
}
if(x<4){
total+= data[x+1][y];
}
if(y>0){
total+= data[x][y-1];
}
if(y<2){
total+= data[x][y+1];
}
totals[x][y] = total;
}
}
Then loop through the arrays and compare the values.
My approach would be the following:
public int largeNeighbor(int[][] numbers) {
int max = 0;
for (int i = 0; i < numbers.length ; i++) {
for (int j = 0; j < numbers[0].length; j++) {
int temp = numbers[i][j];
if (i > 0) {
temp += numbers[i-1][j];
}
if (i < numbers.length - 1) {
temp += numbers[i+1][j];
}
if (j > 0) {
temp += numbers[i][j-1];
}
if (j < numbers[0].length - 1) {
temp += numbers[i][j+1];
}
if (temp > max) {
max = temp;
}
}
}
return max;
}
When given a 2D integer array, the method will compare every value with added neighbors to the current max value.
You explained your situation well but in future questions you should include what you already have in small blocks of code. :)
I did this for fun. Hope someone enjoys.
import java.lang.ArrayIndexOutOfBoundsException;
import java.util.Random;
public class HelloWorld{
int smallest = 10000;
int largest = -1;
int xCoords_small = -1;
int yCoords_small = -1;
int xCoords_large = -1;
int yCoords_large = -1;
//Make it as big as you want!!!!!
int iSize = 5;
int jSize = 3;
int[][] totals = new int[iSize][jSize];
int[][] yourNumbers = new int[iSize][jSize];
Random r = new Random();
//Initializes the array. With random numbers. Yours would read in the
//the file here and initialize the array.
public HelloWorld(){
for(int i = 0; i < iSize; i++){
for(int j = 0; j < jSize; j++){
yourNumbers[i][j] = r.nextInt(10);
}
}
}
//Calculates the total and whether or not it's the largest number and
//tracks position in array and the total number.
//It has crumby error catching but this way you can make your array
//as big as you want without needing to change anything but the two
//two size variables.
public void calculate(){
for(int i = 0; i < iSize; i++){
for(int j = 0; j < jSize; j++){
int total = 0;
try{
total += yourNumbers[i][j];
}catch(ArrayIndexOutOfBoundsException ex ){
//do nothing
}
try{
total += yourNumbers[i-1][j];
}catch(ArrayIndexOutOfBoundsException ex){
//do nothing
}
try{
total += yourNumbers[i][j-1];
}catch(ArrayIndexOutOfBoundsException ex){
//do nothing
}
try{
total += yourNumbers[i+1][j];
}catch(ArrayIndexOutOfBoundsException ex){
//do nothing
}
try{
total += yourNumbers[i][j+1];
}catch(ArrayIndexOutOfBoundsException ex){
//do nothing
}
totals[i][j] = total;
if(total > largest){
largest = total;
xCoords_large = i;
yCoords_large = j;
}
if(total < smallest){
smallest = total;
xCoords_small = i;
yCoords_small = j;
}
System.out.println(total);
}
}
System.out.println(largest + " = Largest Total and it's beginning number in your 2D array. " + xCoords_large+ "," + yCoords_large+ " Its value = " + yourNumbers[xCoords_large][yCoords_large]);
System.out.println(smallest + " = Smallest Total and it's beginning number in your 2D array. " + xCoords_small + "," + yCoords_small + " Its value = " + yourNumbers[xCoords_small][yCoords_small]);
}
public static void main(String []args){
HelloWorld hw = new HelloWorld();
hw.calculate();
}
}

Can't find five lowest values in an array...max works while min array is not assigned values

I'm very close to completing this, all I need is help on finding the five lowest values from a text file by using arrays. I figured out how to find the five highest values, but my min array to find the lowest values always outputs five 0's.
Output: //obviously dependent on individual text file
Total amount of numbers in text file is 10
Sum is: 1832
1775 14 9 9 7 //max
0 0 0 0 0 //min
Any help is much appreciated!
import java.util.Scanner;
import java.io.*;
public class HW3
{
public static void main(String[] args) throws IOException
{
File f = new File("integers.txt");
Scanner fr = new Scanner(f);
int sum = 0;
int count = 0;
int[] max = new int[5];
int[] min = new int[5];
int temp;
while(fr.hasNextInt())
{
count++;
fr.nextInt();
}
Scanner fr2 = new Scanner(new File("integers.txt"));
int numbers[] = new int[count];
for(int i=0;i<count;i++)
{
numbers[i]=fr2.nextInt(); //fills array with the integers
}
for(int j:numbers)//get sum
{
sum+=j;
}
for (int j=0; j < 5; j++) //finds five highest
{
for (int i=0; i < numbers.length; i++)
{
if (numbers[i] > max[j])
{
temp = numbers[i];
numbers[i] = max[j];
max[j] = temp;
}
}
}
for (int j=0; j < 5; j++) //finds five lowest...array not assigned values
{
for (int i=0; i < numbers.length; i++)
{
if (numbers[i] < min[j])
{
temp = numbers[i];
numbers[i] = min[j];
min[j] = temp;
}
}
}
System.out.println("Total amount of numbers in text file is " + count);
System.out.println("Sum is: " + sum);
System.out.println(max[0] + " " + max[1] + " " + max[2] + " " + max[3] + " " + max[4]);
System.out.println(min[0] + " " + min[1] + " " + min[2] + " " + min[3] + " " + min[4]);
}
}
Your min array will be initialized with zero values. So the values in numbers will always be higher (assuming there are no negatives).
I'd suggest that you initialize min[j] with numbers[0] before the inner loop.
for (int j=0; j < 5; j++) //finds five highest
{
min[j] = numbers[0]; // Add this line
for (int i=0; i < numbers.length; i++)
{
Try debugging your code by entering inside your nested min loop the following line:
System.out.println("the value of numbers[i] is: " + numbers[i]);
so it looks like this:
for (int j=0; j < 5; j++) //finds five lowest...array not assigned values
{
for (int i=0; i < numbers.length; i++)
{
if (numbers[i] < min[j])
{
System.out.println("the value of numbers[i] is: " + numbers[i]);
temp = numbers[i];
numbers[i] = min[j];
min[j] = temp;
}
}
}
You'll notice something interesting. The innermost nested part doesn't even start.
Try putting that line into the nested max loop in its respective location instead... and it will run fine and show the max array values. You are getting zero values for the min array because (other than initial assigning) the innermost part of the nested min loop isn't being started somehow, so it fails to run and searched values do not get assigned to the min array.
The outer nested parts of the min loop run fine if you try debugging them with a similar line. It's this part that won't start and something's wrong with:
if (numbers[i] < min[j])
{
System.out.println("the value of numbers[i] is: " + numbers[i]);
temp = numbers[i];
numbers[i] = min[j];
min[j] = temp;
}
(Update)
In the min loop, numbers[i] from i=0 to i=4 have a value of 0 after completing the max loop.
You only need to add one line and use int i=5 instead of int i=0 inside your min loop:
for (int j=0; j < 5; j++) //finds five lowest...array not assigned values
{
min[j] = max[4]; // added line
for (int i=5; i < numbers.length; i++) // change to int i=5
{
if (numbers[i] < min[j])
{...
As the other answer states, your problem is that you did not take into account the arrays beginning at 0. In Java, it sets default values for that data structure. For primitives, this will normally be 0 or false. However, when you move into data structures, you will have problems with null pointer exceptions if you fail to initialize your objects. For this reason, I would urge you to get into the habit of setting the values in your data structures before you ever use them. This will save you A LOT of debugging time in the future.
If you know the values in advance, you can set them manually with {0,0,0,0,0} notation, or your can initialize using a for loop:
for(int i = 0; i < array.length; i++)
array[i] = init_value;
I would recommend that you also look into trying to consolidate as much as possible. For example, in your code you go through the same data 4 times:
1) read the integers from the file into an integer array
2) sum all of the numbers in the integer array
3) look for max
4) look for min
I'm not sure if you've covered functions yet, but one example of consolidating this might look like:
while(fr2.hasNextInt()){
int i = fr2.nextInt();
sum += i;
checkHighest(i);
checkLowest(i);
}
You then define these functions and put the meat elsewhere. This lets you only worry about the loops in one place.
You have 2 problems.
First was explained by Tom Elliott.
The second problem is that also the max[] array is initialized with 0, and when you search for max values you change the value from max array (which is 0) with the value from the numbers array, so the numbers array becomes filled with 0s.
A quick solve (though not the best) would be to copy the numbers array in a temp array and use that temp when searching for min values.
In case you didn't exactly understood what I said, try to make a print of the numbers array after you found the 5 max values.
Just curious , Cant you just sort it(using quick sort) select top five and bottom five ?
- if you can use sorting I think this should work then
int sum = 0;
int count = 0;
int[] max = {Integer.MIN_VALUE,Integer.MIN_VALUE,Integer.MIN_VALUE,Integer.MIN_VALUE,Integer.MIN_VALUE};
int[] min = {Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE};
int temp;
int visited[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (int j : numbers)// get sum
{
sum += j;
}
int tempindex;
for (int j = 0; j < 5; j++) // finds five highest
{
for (int i = 0; i < numbers.length; i++) {
if (visited[i] != 1) {
if (numbers[i] > max[j]) {
max[j] = numbers[i];
tempindex = i;
}
}
}
visited[tempindex] = 1;
}
for (int j = 0; j < 5; j++) // finds five lowest...array not assigned
// values
{
for (int i = 0; i < numbers.length; i++) {
if (visited[i] != 1) {
if (numbers[i] < min[j]) {
min[j] = numbers[i];
tempindex = i;
}
}
}
visited[tempindex] = 1;
}

Random Dice Generator

A run is a sequence of adjacent repeated values . Write a program that generates a sequence of random die tosses and that prints the die values, marking only the longest run. The program should take as input the total number of die tosses (ex 10), then print:
1 6 6 3 (2 2 2 2 2) 5 2
Im quite confused on how to compare each number in order to get the correct output. Maybe using an array to store the values. Any answers or input will be of help thank you!
import java.util.Random;
import java.util.Scanner;
public class Dice
{
Random generator = new Random();
Scanner keyboard = new Scanner(System.in);
public void DiceCount()
{
int count;
int sides = 6;
int number;
System.out.println("How many die? ");
count = keyboard.nextInt();
for(int i=0; i < count; i++)
{
number = generator.nextInt(sides);
System.out.print(number);
}
}
}
First, replace int number; with int[] numbers = new int[count];. Next, replace number = ... with numbers[i] = ....
This will give you an array of random numbers (don't print them yet!). As you generate your numbers, note how many equal numbers you get in a row (add a special counter for that). Also add variable that stores the length of the longest run so far. Every time you get a number that's equal to the prior number, increment the counter; otherwise, compare the counter to the max, change the max if necessary, and set the counter to 1. When you update the max, mark the position where the run starts (you can tell from the current position and the length of the run).
Now it's time to detect the longest run: go through the numbers array, and put an opening parenthesis where the run starts. Put a closing parenthesis when you reach the end of the run, and finish the printing to complete the output for the assignment.
import java.util.Random;
import java.util.Scanner;
public class Dice {
Random generator = new Random();
Scanner keyboard = new Scanner(System.in);
public void DiceCount() {
int sides = 6;
System.out.println("How many die? ");
int count = keyboard.nextInt();
int[] array = new int[count];
int longestLength = 1, currentLength = 1, longestLengthIndex = 0, currentLengthIndex = 1;
int currentNum = -1;
for (int i = 0; i < count; i++) {
array[i] = generator.nextInt(sides);
System.out.print(array[i] + " ");
if (currentNum == array[i]) {
currentLength++;
if (currentLength > longestLength) {
longestLengthIndex = currentLengthIndex;
longestLength = currentLength;
}
} else {
currentLength = 1;
currentLengthIndex = i;
}
currentNum = array[i];
}
System.out.println();
for (int i = 0; i < count; i++)
System.out.print((i == longestLengthIndex ? "(" : "") + array[i] + (i == (longestLengthIndex + longestLength - 1) ? ") " : " "));
}
}
Note: this will only take the first longest range. So if you have 1123335666 it will do 112(333)5666.
If you need 112(333)5(666) or 1123335(666) then I leave that to you. It's very trivial.
import java.util.Random;
public class Dice {
public static void main(String[] args) {
//make rolls
Random rand = new Random();
int[] array = new int[20];
int longestRun = 1;
int currentRun = 1;
int longestRunStart = 0;
int currentRunStart = 1;
System.out.print("Generated array: \n");
for (int i = 0; i < array.length; i++) {
array[i] = rand.nextInt(6); //add random number
System.out.print(array[i] + " "); //print array
if (i != 0 && array[i - 1] == array[i]) {
//if new number equals last number...
currentRun++; //record current run
if (currentRun > longestRun) {
longestRunStart = currentRunStart; //set index to newest run
longestRun = currentRun; //set above record to current run
}
} else {
//if new number is different from the last number...
currentRun = 1; //reset the current run length
currentRunStart = i; //reset the current run start index
}
}
//record results
System.out.print("\nIdentifying longest run: \n");
for (int i = 0; i < longestRunStart; i++) { System.out.print(array[i] + " "); } //prints all numbers leading up to the run
System.out.print("( "); //start parentheses
for (int i = longestRunStart; i < (longestRunStart + longestRun); i++) { System.out.print(array[i] + " "); } //prints the run itself
System.out.print(") "); //end parentheses
for (int i = (longestRunStart + longestRun); i < 20; i++) { System.out.print(array[i] + " "); } //all remaining numbers
}
}```

Finding Multiple Modes In An Array

I'm trying to write a java method which finds all the modes in an array. I know there is a simple method to find the mode in an array but when there are more than one single mode my method outputs only one of them. I've tried to find a way but am nit sure how to approach this problem. Can anyone help me out to find all the modes in the array? Thanks.
Yes here is my code which outputs only one mode even if multiple modes exist.
public static int mode(int a[]){
int maxValue=0, maxCount=0;
for (int i = 0; i < a.length; ++i){
int count = 0;
for (int j = 0; j < a.length; ++j){
if (a[j] == a[i]) ++count;
}
if (count > maxCount){
maxCount = count;
maxValue = a[i];
}
}
return maxValue;
}
okay here's an example:
30
30
30
34
34
23
In this set of numbers there is only one mode, which is 30.
30
30
30
34
34
34
23
But in this set there are two modes, 30 and 34. I want my code to be able to output both of them, whereas it only prints one. It prints only 30.
The following code will return you an Integer[] containing the modes. If you need an int[] instead, you still need to convert the Integer instances to ints manually. Probably not the most efficient version, but its matches closely to your code
public static Integer[] mode(int a[]){
List<Integer> modes = new ArrayList<Integer>( );
int maxCount=0;
for (int i = 0; i < a.length; ++i){
int count = 0;
for (int j = 0; j < a.length; ++j){
if (a[j] == a[i]) ++count;
}
if (count > maxCount){
maxCount = count;
modes.clear();
modes.add( a[i] );
} else if ( count == maxCount ){
modes.add( a[i] );
}
}
return modes.toArray( new Integer[modes.size()] );
}
After a long night of programming, I finality got a program that will print out the mode/modes of an array. Or will even tell you if there isn't a mode (say, if no input occurred more than once or all the inputs occurred the same amount of times: ex. 1, 1, 2, 2, 3, 3, 4, 4). Some limitations of the program are that you must enter more than one number, and you cannot enter more than 10000 numbers or a negative number (if you wanted to enter a negative number, you would just have to tweak all the for loops involving the values[][] array. Some cool things about my program are that it prints out how many times each of you inputs occurred along with the mode of your array. And all of the print outs grammar change according to the amount of info (Ex. The mode of your array is 2; The modes of your array are 1 & 2; The modes of your array are 0, 2, 5, & 8). There is also a bubble sort function example in the program for anyone who thought that they needed a sorter function in their mode program. Hope this helps, I included a lot of pseudo code to help anyone who doesn't see how my logic progress throughout the program. (FYI: It is java, and was compiled in BlueJ)
import java.util.Scanner;
public class Mode
{
public static void main (String args [])
{
Scanner scan = new Scanner(System.in);
int MAX_INPUTS = 10000; boolean flag = false;
System.out.print ("Input the size of your array: ");
int size; // How many nubers will be in the user array
do
{
size = scan.nextInt();
if (size == 1)
{
System.out.print ("\nError. You must enter a number more than 1.\n\n");
continue;
}
else if (size > MAX_INPUTS || size < 0)
{
System.out.print ("\nError. You muste enter a number less than " + MAX_INPUTS + " or greater than 0\n\n");
continue;
}
else
flag = true; // a ligit answer has been entered.
}
while (flag != true);
int array[] = new int[size], values[][] = new int[2][MAX_INPUTS + 1], ticks = 0;
System.out.print ("\nNow input the numbers for your array.\n\n");
/* Taking inputs from the user */
while (ticks < size)
{
System.out.print ("Number " + (ticks + 1) + ": ");
array[ticks] = scan.nextInt();
if (array[ticks] > MAX_INPUTS || array[ticks] < 0)
{
System.out.print ("\nError. Number cannot be greater than " + MAX_INPUTS + " or less than 0\n\n");
continue;
}
++ticks;
}
/*
* values[][] array will hold the info for how many times numbers 0 - 10000 appear in array[]. Column 0 will hold numbers from 0 -1000, and column 1 will hold the number of
* of repititions the number in column 0 occured in the users inputed array.
*/
for (int i = 0; i < MAX_INPUTS; ++i) // Initalize Column zero with numbers starting at zeor, and ending and MAX_INPUTS.
values[0][i] = i;
for (int i = 0; i < size; ++i) // Find the repatitions of the numbers in array[] that correspond to the number in column zere of values[][].
for (int j = 0; j < MAX_INPUTS; ++j)
if (array[i] == j)
++values[1][j];
sort (array, size);
System.out.print ("\n\nHere are the numbers you entered.\n\n"); // show the values the user entered in ascending order.
for (int i = 0; i < size; ++i)
{
if (i == size - 1) // the last inputed number
System.out.print (array[i]); // don't allow an extra comma.
else
System.out.print (array[i] + ", ");
}
// Show the user how many times each of the values he/she entered occured.
System.out.print ("\n\nThis is the amount of times each of the values you entered occured:\n");
for (int i = 0; i < MAX_INPUTS; ++i)
{
if (values[1][i] == 1)
System.out.print (i + " was entered " + values[1][i] + " time\n"); // avoid: 2 was entered 1 times
else if (values[1][i] != 0)
System.out.print (i + " was entered " + values[1][i] + " times\n"); // avoid: 2 was entered 2 time
}
/* -------------------------------------------------------------------- | Finding the Mode/Modes | -------------------------------------------------------------------- */
/* The process begins with creating a second array that is the exactly the same as the values[][] (First for loop). Then I sort the duplicate[] array to find the mode
* (highest number in the duplicate[]/values[][] arrays. Int max is then assigned the highest number. Remembering that the values[][] array: column 0 contains numbers ranging
* from 1 to 10000, it keeps track of where the numbers in column were originally located, in which you can compare to the duplicate array which is sorted. Then I can set
* up a flag that tells you whether there is more than one mode. If so, the printing of these modes will look neater and the grammar can be changed accordingly.
*/
int duplicate[] = new int [10001], mode[] = new int [size], max, mode_counter = 0;
boolean multi_mode = false, all_same;
for (int i = 0; i < MAX_INPUTS; ++i)
duplicate[i] = values[1][i]; // copy values array.
sort (duplicate, MAX_INPUTS);
max = duplicate[MAX_INPUTS - 1]; // the last number in the sorted array is the greatest.
all_same = test (duplicate, MAX_INPUTS, size, max); // this is the test to see if all the numbers in the user array occured the same amount of times.
int c = 0; // a counter
/* The mode of the user inputed array will be recorded in the values array. The sort of the duplicate array told me what was the higest number in that array. Now I can
* see where that highest number used to be in the original values array and recored the corresponding number in the column zero, which was only filled with numbers 0 -
* 10000. Thus telling me the mode/modes.
*/
for (int i = 0; i < MAX_INPUTS; ++i)
{
if (values[1][i] == max)
{
mode[c++] = values[0][i];
++mode_counter;
}
}
if (mode[1] != 0) //mode[0] (the first cell, has a number stored from the last for loop. If the second cell has a number other than zero, that tells me there is more than 1 mode.
multi_mode = true;
if (multi_mode == false)
System.out.print ("\nThe mode of your array is " + mode[0]); // For correct grammer.
else if (all_same == true)
System.out.print ("\nAll of the numbers entered appeared the same amount of times. "); // See the boolean function for more details
else // If here there is more than one mode.
{
System.out.print ("\nThe modes of yoru array are ");
for (int i = 0; i < mode_counter; ++i)
{
if (mode_counter > 2 && i == (mode_counter - 1)) // If there is more than two modes and the final mode is to be printed.
System.out.print ("& " + mode[i]);
else if (mode_counter == 2)
{ // This is true if there is two modes. The else clause will print the first number, and this will print the amper sign and the second mode.
System.out.print (mode[0] + " & " + mode[1]);
break;
}
else
System.out.print (mode[i] + ", ");
}
}
}
public static void sort (int list[], int max) // Its the bubble sort if you're wondering.
{
int place, count, temp;
for (place = 0; place < max; ++place)
for (count = max - 1; count > place; --count)
if (list[count - 1] > list[count])
{
temp = list[count-1];
list[count - 1] = list[count];
list[count] = temp;
}
}
/* The test to see if there isn't a mode. If the amount of the mode number is the same as the amount of numbers there are in the array is true, or if the size entered by the
* user (input) modulo the mode value is equal to zero (say, all the numbers in an array of ten were entered twice: 1, 1, 2, 2, 3, 3, 4, 4, 5, 5). */
public static boolean test (int list[], int limit, int input, int max)
{
int counter = 0, anti_counter = 0;
for (int i = 0; i < limit; ++i)
if (list[i] == max)
++counter; // count the potential modes
else if (list[i] !=0 && list[i] != max)
++anti_counter; // count every thing else except zeros.
if (counter == input || (input % max == 0 && anti_counter == 0) )
return true;
else
return false;
}
}
Even though this probably isn't the most efficient solution, it will print all the highest modes:
public static int mode(int a[]) {
int maxValue=-1, maxCount=0;
for (int i = 0; i < a.length; i++) {
int count = 0;
for (int j = 0; j < a.length; j++) {
if (a[j] == a[i])
count++;
}
}
if (count > maxCount) {
maxCount = count;
maxValue = a[i];
}
}
//loop again and print only the highest modes
for (int i = 0; i < a.length; i++) {
int count = 0;
for (int j = 0; j < a.length; j++) {
if (a[j] == a[i])
count++;
}
}
if (count == maxCount) {
System.out.println(a[i]);
}
}
}
Hope this helps. This is my answer. Hope it helps
public List mode(double[] m) {
HashMap<Double, Double> freqs = new HashMap<Double, Double>();
for (double d : m) {
Double freq = freqs.get(d);
freqs.put(d, (freq == null ? 1 : freq + 1));
}
List<Double> mode = new ArrayList<Double>();
List<Double> frequency = new ArrayList<Double>();
List<Double> values = new ArrayList<Double>();
for (Map.Entry<Double, Double> entry : freqs.entrySet()) {
frequency.add(entry.getValue());
values.add(entry.getKey());
}
double max = Collections.max(frequency);
for(int i=0; i< frequency.size();i++)
{
double val =frequency.get(i);
if(max == val )
{
mode.add(values.get(i));
}
}
return mode;
}
Handling multiple mode values:
Here initially I am taking a map to get the frequencies of each element. After finding the max repeating value I am storing its map value.
While iterating to the map I am checking if this value is repeating for some key and is not 1, if it is then I am adding that key as well. This will get me the multiple modes
public static void mode(int a[]){
int count=0;
Map<Integer,Integer> map=new HashMap<>();
for(int i=0;i<a.length;i++)
{
map.put(a[i],map.getOrDefault(a[i],0)+1);
}
Set<Integer> set=new HashSet<>();
int maxValue=0;
for(int i=0;i<a.length;i++)
{
int ct=0;
for(int j=0;j<a.length;j++)
{
if(a[i]==a[j])
ct++;
}
if(ct>count)
{
count=ct;
maxValue=a[i];
}
}
set.add(maxValue);
int k=map.get(maxValue);
if(k!=1)
{
for(Map.Entry m:map.entrySet())
{
if((int)m.getValue()==k)
set.add((int)m.getKey());
}
}
System.out.println("Mode: "+set);
}

Categories