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);
}
Related
I need for homework to get the most "popular" number in an array (the number in the highest frequency), and if there are several numbers with the same number of shows, get some number randomly.
After more then three hours of trying, and either searching the web, this is what I got:
public int getPopularNumber(){
int count = 1, tempCount;
int popular = array[0];
int temp = 0;
for ( int i = 0; i < (array.length - 1); i++ ){
if ( _buses[i] != null )
temp = array[i];
tempCount = 0;
for ( int j = 1; j < _buses.length; j++ ){
if ( array[j] != null && temp == array[j] )
tempCount++;
}
if ( tempCount > count ){
popular = temp;
count = tempCount;
}
}
return popular;
}
This code work, but don't take into account an important case- if there is more than one number with the same count of shows. Then it just get the first one.
for example: int[]a = {1, 2, 3, 4, 4, ,5 ,4 ,5 ,5}; The code will grab 4 since it shown first, and it's not random as it should be.
Another thing- since it's homework I can't use ArrayList/maps and stuff that we still didn't learn.
Any help would be appreciated.
Since they didn't give you any time complexity boundary, you can "brute force" the problem by scanning the the array N^2 times. (disclaimer, this is the most intuitive way of doing it, not the fastest or the most efficient in terms of memory and cpu).
Here is some psuedo-code:
Create another array with the same size as the original array, this will be the "occurrence array"
Zero its elements
For each index i in the original array, iterate the original array, and increment the element in the occurrence array at i each time the scan finds duplicates of the value stored in i in the original array.
Find the maximum in the occurrence array
Return the value stored in that index in the original array
This way you mimic the use of maps with just another array.
If you are not allowed to use collection then you can try below code :
public int getPopularNumber(){
int inputArr[] = {1, 2, 3, 4, 4, 5 ,4 ,5 ,5}; // given input array
int[] tempArr = new int[inputArr.length];
int[] maxValArr = new int[inputArr.length];
// tempArr will have number as index and count as no of occurrence
for( int i = 0 ; i < inputArr.length ; i++){
tempArr[inputArr[i]]++;
}
int maValue = 0;
// find out max count of occurrence (in this case 3 for value 4 and 5)
for( int j = 0 ; j < tempArr.length ; j++){
maValue = Math.max(maValue, tempArr[j]);
}
int l =0;
// maxValArr contains all value having maximum occurrence (in this case 4 and 5)
for( int k = 0 ; k < tempArr.length ; k++){
if(tempArr[k] == maValue){
maxValArr[l] = k;
l++;
}
}
return maxValArr[(int)(Math.random() * getArraySize(maxValArr))];
}
private int getArraySize(int[] arr) {
int size = 0;
for( int i =0; i < arr.length ; i++){
if(arr[i] == 0){
break;
}
size++;
}
return size;
}
that's hard as hell :D
After some trying, I guess I have it (If there will be 2 numbers with same frequency, it will return first found):
int mostPopNumber =0;
int tmpLastCount =0;
for (int i = 0; i < array.length-1; i++) {
int tmpActual = array[i];
int tmpCount=0;
for (int j = 0; j < array.length; j++) {
if(tmpActual == array[j]){
tmpCount++;
}
}
// >= for the last one
if(tmpCount > tmpLastCount){
tmpLastCount = tmpCount;
mostPopNumber = tmpActual;
}
}
return mostPopNumber;
--
Hah your code give me idea- you cant just remember last most popular number, btw I've found it solved there Find the most popular element in int[] array
:)
EDIT- after many, and many years :D, that works well :)
I've used 2D int and Integer array - you can also use just int array, but you will have to make more length array and copy actual values, Integer has default value null, so that's faster
Enjoy
public static void main(String[] args) {
//income array
int[] array= {1,1,1,1,50,10,20,20,2,2,2,2,20,20};
//associated unique numbers with frequency
int[][] uniQFreqArr = getUniqValues(array);
//print uniq numbers with it's frequency
for (int i = 0; i < uniQFreqArr.length; i++) {
System.out.println("Number: " + uniQFreqArr[i][0] + " found : " + uniQFreqArr[i][1]);
}
//get just most frequency founded numbers
int[][] maxFreqArray = getMaxFreqArray(uniQFreqArr);
//print just most frequency founded numbers
System.out.println("Most freq. values");
for (int i = 0; i < maxFreqArray.length; i++) {
System.out.println("Number: " + maxFreqArray[i][0] + " found : " + maxFreqArray[i][1]);
}
//get some of found values and print
int[] result = getRandomResult(maxFreqArray);
System.out.println("Found most frequency number: " + result[0] + " with count: " + result[1]);
}
//get associated array with unique numbers and it's frequency
static int[][] getUniqValues(int[] inArray){
//first time sort array
Arrays.sort(inArray);
//default value is null, not zero as in int (used bellow)
Integer[][] uniqArr = new Integer[inArray.length][2];
//counter and temp variable
int currUniqNumbers=1;
int actualNum = inArray[currUniqNumbers-1];
uniqArr[currUniqNumbers-1][0]=currUniqNumbers;
uniqArr[currUniqNumbers-1][1]=1;
for (int i = 1; i < inArray.length; i++) {
if(actualNum != inArray[i]){
uniqArr[currUniqNumbers][0]=inArray[i];
uniqArr[currUniqNumbers][1]=1;
actualNum = inArray[i];
currUniqNumbers++;
}else{
uniqArr[currUniqNumbers-1][1]++;
}
}
//get correctly lengthed array
int[][] ret = new int[currUniqNumbers][2];
for (int i = 0; i < uniqArr.length; i++) {
if(uniqArr[i][0] != null){
ret[i][0] = uniqArr[i][0];
ret[i][1] = uniqArr[i][1];
}else{
break;
}
}
return ret;
}
//found and return most frequency numbers
static int[][] getMaxFreqArray(int[][] inArray){
int maxFreq =0;
int foundedMaxValues = 0;
//filter- used sorted array, so you can decision about actual and next value from array
for (int i = 0; i < inArray.length; i++) {
if(inArray[i][1] > maxFreq){
maxFreq = inArray[i][1];
foundedMaxValues=1;
}else if(inArray[i][1] == maxFreq){
foundedMaxValues++;
}
}
//and again copy to correctly lengthed array
int[][] mostFreqArr = new int[foundedMaxValues][2];
int inArr= 0;
for (int i = 0; i < inArray.length; i++) {
if(inArray[i][1] == maxFreq){
mostFreqArr[inArr][0] = inArray[i][0];
mostFreqArr[inArr][1] = inArray[i][1];
inArr++;
}
}
return mostFreqArr;
}
//generate number from interval and get result value and it's frequency
static int[] getRandomResult(int[][] inArray){
int[]ret=new int[2];
int random = new Random().nextInt(inArray.length);
ret[0] = inArray[random][0];
ret[1] = inArray[random][1];
return ret;
}
I'm trying to find the mode for my program, a user inputs an amount of numbers from 0-100 as many as they want, I'm attempting to find the mode of these numbers but each time I attempt to find the mode it gives me back a 3, I've found everything else, I just need the help with the mode.
import java.util.Scanner;
public class deveation {
public static void main(String Args[]) {
Scanner kbReader = new Scanner(System.in);
int sum = 0;
int bob[] = new int[101];
int total = 0;
int a = 0;
int min = 0;
int max = 100;
int mode = 0;
boolean stay_in_loop = true;
while (stay_in_loop) {
System.out.println("Please enter interger(s) from 0-100: ");
int number = kbReader.nextInt();
if (number < 0) {
stay_in_loop = false;
}
else {
total++;
bob[number]++;
}
}
int median = total / 2 + 1;
while (median > 0) {
median -= bob[a];
a++;
}
a--;
boolean findit = true;
while (findit) {
if (bob[min] != 0)
findit = false;
else
min++;
}
boolean findme = true;
while (findme) {
if (bob[max] != 0)
findme = false;
else
max--;
}
for (int p = 0; p < 101; p++) {
if (bob[p] > mode) {
mode = bob[p];
}
for (int j = 0; j < 101; j++)
if (bob[j] <= mode)
//I don't know why I'm getting three for this
{
}
}
for (int i = 0; i < 101; i++) {
sum += bob[i] * i;
}
System.out.println(sum);
System.out.println(sum /= total);
System.out.println(a);
System.out.println(min);
System.out.println(max);
System.out.println(mode);
//You should start putting down these comments
}
}
Mode is the number(s) that is repeated most often. I would get rid of the inner for loop that you have.
for (int p = 0; p<101; p++) {
if (bob[p]>mode) {
mode=bob[p];
}
}
I am not sure why you say you are always getting three. At the end of the above loop, the mode variable will contain the largest count for a number in your bob array.
You can then loop back through the list (or store the values while looping through it) and print out the numbers that have a count that match your the value of your mode.
for (int p = 0; p < 101; p++) {
if (bob[p] == mode) {
System.out.println("Mode Number: " + p);
}
}
Remember that mode can be more than one number.
You make mode = bob[p], but bob[p] is just how many times the number appeared in your array. The mode should really be p.
For example, suppose that the bob array is:
[2, 1, 3, 1, 1, 2]
This means that 0 appears twice, 1 appears once, 2 appears three times and so on. The mode in this case is 2, which is given by the array index, and not by the value stored in the array.
To find the mode, then, we need to loop through the count array (bob), and keep two variables, the mode and the highest count until now. There is no need to loop twice or use nested loops.
int count = 0;
int mode = 0;
for (int p = 0; p < bob.length; p++) {
// If the count of the p element is greater than the greatest count until now
if (bob[p] > count) {
// Update the greatest count
count = bob[p];
// p is the new mode
mode = p;
}
}
Try using something like a hashmap where the key would the number and the value would be the number of occurences. And you can just keep track of the highest value. Also you should be able to do this in O(n) time meaning in one loop through the array. There are plenty of examples online of finding the mode.
i'm new to this, Say if you typed 6 6 6 1 4 4 4 in the command line, my code gives the most frequent as only 6 and i need it to print out 6 and 4 and i feel that there should be another loop in my code
public class MostFrequent {
//this method creates an array that calculates the length of an integer typed and returns
//the maximum integer...
public static int freq(final int[] n) {
int maxKey = 0;
//initiates the count to zero
int maxCounts = 0;
//creates the array...
int[] counts = new int[n.length];
for (int i=0; i < n.length; i++) {
for (int j=0; j < n[i].length; j++)
counts[n[i][j]]++;
if (maxCounts < counts[n[i]]) {
maxCounts = counts[n[i]];
maxKey = n[i];
}
}
return maxKey;
}
//method mainly get the argument from the user
public static void main(String[] args) {
int len = args.length;
if (len == 0) {
//System.out.println("Usage: java MostFrequent n1 n2 n3 ...");
return;
}
int[] n = new int[len + 1];
for (int i=0; i<len; i++) {
n[i] = Integer.parseInt(args[i]);
}
System.out.println("Most frequent is "+freq(n));
}
}
Thanks...enter code here
Though this may not be a complete solution, it's a suggestion. If you want to return more than one value, your method should return an array, or better yet, an ArrayList (because you don't know how many frequent numbers there will be). In the method, you can add to the list every number that is the most frequest.
public static ArrayList<Integer> freq(final int[] n) {
ArrayList<Integer> list = new ArrayList<>();
...
if (something)
list.add(thatMostFrequentNumber)
return list;
}
The solutions looks like this:
// To use count sort the length of the array need to be at least as
// large as the maximum number in the list.
int[] counts = new int[MAX_NUM];
for (int i=0; i < n.length; i++)
counts[n[i]]++;
// If your need more than one value return a collection
ArrayList<Integer> mf = new ArrayList<Integer>();
int max = 0;
for (int i = 0; i < MAX_NUM; i++)
if (counts[i] > max)
max = counts[i];
for (int i = 0; i < MAX_NUM; i++)
if (counts[i] == max)
mf.add(i);
return mf;
Well you can just do this easily by using the HashTable class.
Part 1. Figure out the frequency of each number.
You can do this by either a HashTable or just a simple array if your numbers are whole numbrs and have a decent enough upper limit.
Part 2. Find duplicate frequencies.
You can just do a simple for loop to figure out which numbers are repeated more than once and then print them accordingly. This wont necessarily give them to you in order though so you can store the information in the first pass and then print it out accordingly. You can use a HashTable<Integer,ArrayList<Integer> for this. Use the key to store frequency and the ArrayList to store the numbers that fall within that frequency.
You can maintain a "max" here while inserting into our HashTable if you only want to print out only the things with most frequency.
Here is a different way to handle this. First you sort the list, then loop through and keep track of the largest numbers:
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
int n[] = { 6, 4, 6, 4, 6, 4, 1 };
List<Integer> maxNums = new ArrayList<Integer>();
int max = Integer.MIN_VALUE;
Integer lastValue = null;
int currentCount = 0;
Arrays.sort(n);
for( int i : n ){
if( lastValue == null || i != lastValue ){
if( currentCount == max ){
maxNums.add(lastValue);
}
else if( currentCount > max ){
maxNums.clear();
maxNums.add(lastValue);
max = currentCount;
}
lastValue = i;
currentCount = 1;
}
else {
currentCount++;
}
System.out.println("i=" + i + ", currentCount=" + currentCount);
}
if( currentCount == max ){
maxNums.add(lastValue);
}
else if( currentCount >= max ){
maxNums.clear();
maxNums.add(lastValue);
}
System.out.println(maxNums);
}
}
You can try it at: http://ideone.com/UbmoZ5
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.
I am trying to write a program that generates all the subsets of an entered set in java. I think i nearly have it working.
I have to use arrays (not data structures)
The entered array will never be greater than 20
Right now when i run my code this is what i get:
Please enter the size of A: 3
Please enter A: 1 2 3
Please enter the number N: 3
Subsets:
{ }
{ 1 }
{ 1 2 }
{ 1 2 3 }
{ 2 3 }
{ 2 3 }
{ 2 }
{ 1 2 }
this is the correct number of subsets (2^size) but as you can see it prints a few duplicates and not some of the subsets.
Any ideas where I am going wrong in my code?
import java.util.Scanner;
public class subSetGenerator
{
// Fill an array with 0's and 1's
public static int [] fillArray(int [] set, int size)
{
int[] answer;
answer = new int[20];
// Initialize all elements to 1
for (int i = 0; i < answer.length; i++)
answer[i] = 1;
for (int a = 0; a < set.length; a++)
if (set[a] > 0)
answer[a] = 0;
return answer;
} // end fill array
// Generate a mask
public static void maskMaker(int [] binarySet, int [] set, int n, int size)
{
int carry;
int count = 0;
boolean done = false;
if (binarySet[0] == 0)
carry = 0;
else
carry = 1;
int answer = (int) Math.pow(2, size);
for (int i = 0; i < answer - 1; i++)
{
if (count == answer - 1)
{
done = true;
break;
}
if (i == size)
i = 0;
if (binarySet[i] == 1 && carry == 1)
{
binarySet[i] = 0;
carry = 0;
count++;
} // end if
else
{
binarySet[i] = 1;
carry = 1;
count++;
//break;
} // end else
//print the set
System.out.print("{ ");
for (int k = 0; k < size; k++)
if (binarySet[k] == 1)
System.out.print(set[k] + " ");
System.out.println("}");
} // end for
} // maskMaker
public static void main (String args [])
{
Scanner scan = new Scanner(System.in);
int[] set;
set = new int[20];
int size = 0;
int n = 0;
// take input for A and B set
System.out.print("Please enter the size of A: ");
size = scan.nextInt();
if (size > 0)
{
System.out.print("Please enter A: ");
for (int i = 0; i < size; i++)
set[i] = scan.nextInt();
} // end if
System.out.print("Please enter the number N: ");
n = scan.nextInt();
//System.out.println("Subsets with sum " + n + ": ");
System.out.println("Subsets: ");
System.out.println("{ }");
maskMaker(fillArray(set, size), set, n, size);
} // end main
} // end class
The value of i always goes from 0 to N-1 and then back to 0. This is not useful to generate every binary mask you need only one time. If you think about it, you need to move i only when you have generate all possible masks up to i-1.
There is a much easier way to do this if you remember every number is already internally represented in binary in the computer and everytime you increment it Java is doing the adding and carrying by itself. Look for bitwise operators.