Okay so I have the following code and no matter what it returns to me a -1. I want to have it so that if the id matches then it returns and index but if it doesn't match after running through the whole data set it returns a negative one. Where am I going wrong here:
public class StudentCollection {
private String[] ids = new String[] {"Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty"}; // keeps identification numbers of students
private String [] names = new String[] {"Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty","Empty"};; // keeps the names of students
private int size = 0; // number of students currently in the collection
private int findIndex(String id) {
int noIndex = 1;
for (int i=0;i<ids.length;i++){
if((ids[i].equalsIgnoreCase(id))){
System.out.println("The index of this student is " +i);
}
else {
noIndex = -1;
System.out.println(noIndex);
break;}
}
return noIndex;
}
Here is the solution where if index is found then its number is returned, else if it isn't after checking whole array, -1 is returned and appropriate Strings are printed.
private int findIndex(String id) {
int noIndex = -1;
for (int i = 0; i < ids.length; i++) {
if (ids[i].equalsIgnoreCase(id)) {
System.out.println("The index of this student is " + i);
return i;
}
}
System.out.println(noIndex);
return noIndex;
}
You can also use Java 8 Stream:
private int findIndex(String id) {
OptionalInt index = IntStream.rangeClosed(0, ids.length-1)
.filter(i -> ids[i].equalsIgnoreCase(id))
.findFirst();
if(index.isPresent()) {
int i = index.getAsInt();
System.out.println("The index of this student is " + i);
return i;
}
System.out.println(-1);
return -1;
}
Right now you have it so when ids[i].equalsIgnoreCase(id)is true, it will set noIndexto -1 (in the else statement) and break the for loop which will make it return -1. When that is false, it will print out the index.
Like everyone else has already posted, here is the code to find the index.
private int findIndex(String id) {
for (int i=0;i<ids.length;i++){
if(ids[i].equalsIgnoreCase(id)){
return i;
}
}
return -1;
}
i think you need something like this :
private int findIndex(String id) {
for (int i=0; i<ids.length; i++){
if(ids[i].equalsIgnoreCase(id)){
System.out.println("The index of this student is " +i);
return i;
}
}
return -1;
}
Related
My findmaxprice method returns the index of the first Car in the array with the maximum price. If it is not found, -1 is returned.
As far as I know, return will stop the for loop. Any advice on how to avoid it while keep the loop search for max price?
public int findmaxprice() {
double max =0;
for(int i =0; i < nCars; i++) {
if(max <= Cars[i].getPrice()) {
max = Cars[i].getPrice();
return i; //the problem is here
}
}
return -1;
}
You almost answered yourself - just don't return in the for loop.
public int findmaxprice() {
double max =0;
int maxIndex = -1;
for( int i =0; i < nCars; i++) {
if(max <= Cars[i].getPrice()) {
max = Cars[i].getPrice();
maxIndex = i;
}
}
return maxIndex;
}
Move the return statement outside of the loop
findmaxprice method: returns the index of the first Car in the array with the maximum price. If it is not found, -1 is returned. as far as i know, return will stop the for loop , any advice on how to avoid it while keep the loop search for max price ?
public int findmaxprice() {
double max =0;
for( int i =0; i < nCars; i++) {
if(max <= Cars[i].getPrice()) {
max = Cars[i].getPrice();
}
}
if(max != 0){
return max;
} else {
return -1;
}
}
The below method will fix your issue. Also, it gives you ability to specify a minimum price above which the car price will be considered for max calculation. You can keep this 0 in function call like findMaxPrice(0)if no such boundation needed.
public int findMaxPrice(int min) {
double max = min;
int maxPriceCarIndex = -1;
for (int i = 0; i < nCars; i++) {
if (max <= Cars[i].getPrice()) {
max = Cars[i].getPrice();
maxPriceCarIndex = i; //reassign the index here
}
}
return maxPriceCarIndex;
}
Maybe you just need the "most expensive" car and not the index of the car, then you could consider using streams
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
public class Test {
public static void main(String[] args) {
new Test().testGetMostExpensiveCar();
}
private void testGetMostExpensiveCar() {
// test null array
Car[] cars = null;
Car mostExpensive = getMostExpensiveCar(cars);
System.out.println(mostExpensive); // prints null
// test empty array
cars = new Car[10];
mostExpensive = getMostExpensiveCar(cars);
System.out.println(mostExpensive); // prints null
//test array with cars
cars[0] = new Car(10.0);
cars[5] = new Car(20.0);
cars[8] = new Car(30.0);
cars[8] = new Car(30.0);
mostExpensive = getMostExpensiveCar(cars);
System.out.println(mostExpensive);// prints Car [price=30.0]
}
/**
* #param cars
* #return the most Expensive car, null if the array is empty or no car is in
* the array
*/
public Car getMostExpensiveCar(Car[] cars) {
if (cars == null) {
return null;
}
return Arrays.stream(cars) // creates a Stream<Car> (take a look at e.g. https://www.baeldung.com/java-8-streams)
.filter(Objects::nonNull) // because there can be "null" values in the array
.max(Comparator.comparing(Car::getPrice)) // compares the car by price asc
.orElse(null); // return null if no element is found
}
private class Car {
private double price;
public Car(double price) {
super();
this.price = price;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
#Override
public String toString() {
return "Car [price=" + price + "]";
}
}
}
I was asked to program a method that receives a scanner, and returns a sorted array of words which contain only letters, with no repetitions (and no bigger in length than 3000). Then, I was asked to program a method that checks whether a certain given string is contained in a given vocabulary. I used a simple binary search method.
This is what I've done:
public static String[] scanVocabulary(Scanner scanner){
String[] array= new String[3000];
int i=0;
String word;
while (scanner.hasNext() && i<3000) {
word=scanner.next();
if (word.matches("[a-zA-Z]+")){
array[i]=word.toLowerCase();
i++;
}
}int size=0;
while (size<3000 && array[size]!=null ) {
size++;
}
String[] words=Arrays.copyOf(array, size);
if (words.length==0 || words.length==1) {
return words;
}
else {
Arrays.sort(words);
int end= removeDuplicatesSortedArr(words);
return Arrays.copyOf(words, end);
}
}
private static int removeDuplicatesSortedArr(String[] array) { //must be a sorted array. returns size of the new array
int n= array.length;
int j=0;
for (int i=0; i<n-1; i++) {
if (!array[i].equals(array[i+1])) {
array[j++]=array[i];
}
}
array[j++]=array[n-1];
return j;
}
public static boolean isInVocabulary(String[] vocabulary, String word){
//binary search
int n=vocabulary.length;
int left= 0;
int right=n-1;
while (left<=right) {
int mid=(left+right)/2;
if (vocabulary[mid].equals(word)){
return true;
}
else if (vocabulary[mid].compareTo(word)>0) {
right=mid-1;
}else {
right=mid+1;
}
}
return false;
}
while trying the following code:
public static void main(String[] args) {
String vocabularyText = "I look at the floor and I see it needs sweeping while my guitar gently weeps";
Scanner vocabularyScanner = new Scanner(vocabularyText);
String[] vocabulary = scanVocabulary(vocabularyScanner);
System.out.println(Arrays.toString(vocabulary));
boolean t=isInVocabulary(vocabulary, "while");
System.out.println(t);
System.out.println("123");
}
I get nothing but-
[and, at, floor, gently, guitar, i, it, look, my, needs, see, sweeping, the, weeps, while]
nothing else is printed out nor returned. Both functions seem to be working fine separately, so I don't get what I'm doing wrong.
I would be very happy to hear your thoughts, thanks in advance :)
This has nothing to do with the console. Your isInVocabulary method is entering an infinite loop in this block:
if (!isInVocabulary(vocabulary, "while")) {
System.out.println("Error");
}
If you were to debug through isInVocabulary, you would see that after a few iterations of the while loop,
left = 0;
right = 2;
mid = 1;
if (vocabulary[mid].equals(word)){
// it doesn't
} else if (vocabulary[mid].compareTo("while") > 0) {
// it doesn't
} else {
right = mid + 1;
// this is the same as saying right = 1 + 1, i.e. 2
}
So you'll loop forever.
My assignment asks me to make a TV show program, where I can input shows, delete, modify and sort them. What I'm stuck on is the sorting part. With the show, it asks for the name, day a new episode premieres, and time. Those are the keys I need to sort it by.
The program prompts the user to input one of those keys, then the program needs to sort (sorting by day will sort alphabetically).
I made a class and used an array. Here is the class:
public class showInfo
{
String name;
String day;
int time;
}
And the method to sort by time in the code:
public static void intSort()
{
int min;
for (int i = 0; i < arr.length; i++)
{
// Assume first element is min
min = i;
for (int j = i+1; j < arr.length; j++)
{
if (arr[j].time < arr[min].time)
{
min = j;
}
}
if (min != i)
{
int temp = arr[i].time;
arr[i].time = arr[min].time;
arr[min].time = temp;
}
}
System.out.println("TV Shows by Time");
for(int i = 0; i < arr.length; i++)
{
System.out.println(arr[i].name + " - " + arr[i].day + " - " + arr[i].time + " hours");
}
}
When I call it and output it in the main, it only shows "TV Shows by Time" and not the list. Why is this?
Also, I need to make ONE method that I will be able to use to sort both the day AND the name (both Strings). How can I do this without using those specific arrays (arr[i].name, arr[i].day) in the method?
Any help would be greatly appreciated! Thanks in advance!
In this part of your code
if (min != i) {
int temp = arr[i].time;
arr[i].time = arr[min].time;
arr[min].time = temp;
}
You're just changing the time when you should move the whole object instead. To fix it, the code must behave like this:
if (min != i) {
//saving the object reference from arr[i] in a temp variable
showInfo temp = arr[i];
//swapping the elements
arr[i] = arr[min];
arr[min] = temp;
}
I̶t̶ ̶w̶o̶u̶l̶d̶ ̶b̶e̶ ̶b̶e̶t̶t̶e̶r̶ ̶t̶o̶ ̶u̶s̶e̶ ̶ Arrays#sort ̶w̶h̶e̶r̶e̶ ̶y̶o̶u̶ ̶p̶r̶o̶v̶i̶d̶e̶ ̶a̶ ̶c̶u̶s̶t̶o̶m̶ ̶̶C̶o̶m̶p̶a̶r̶a̶t̶o̶r̶̶ ̶o̶f̶ ̶t̶h̶e̶ ̶c̶l̶a̶s̶s̶ ̶b̶e̶i̶n̶g̶ ̶s̶o̶r̶t̶e̶d̶ ̶(̶i̶f̶ ̶y̶o̶u̶ ̶a̶r̶e̶ ̶a̶l̶l̶o̶w̶e̶d̶ ̶t̶o̶ ̶u̶s̶e̶ ̶t̶h̶i̶s̶ ̶a̶p̶p̶r̶o̶a̶c̶h̶)̶.̶ ̶S̶h̶o̶r̶t̶ ̶e̶x̶a̶m̶p̶l̶e̶:̶
showInfo[] showInfoArray = ...
//your array declared and filled with data
//sorting the array
Arrays.sort(showInfoArray, new Comparator<showInfo>() {
#Override
public int compare(showInfo showInfo1, showInfo showInfo2) {
//write the comparison logic
//basic implementation
if (showInfo1.getTime() == showInfo2.getTime()) {
return showInfo1.getName().compareTo(showInfo2.getName());
}
return Integer.compare(showInfo1.getTime(), showInfo2.getTime());
}
});
//showInfoArray will be sorted...
Since you have to use a custom made sorting algorithm and support different ways to sort the data, then you just have to change the way you compare your data. This mean, in your current code, change this part
if (arr[j].time < arr[min].time) {
min = j;
}
To something more generic like
if (compare(arr[j], arr[min]) < 0) {
min = j;
}
Where you only need to change the implementation of the compare method by the one you need. Still, it will be too complex to create and maintain a method that can support different ways to compare the data. So the best option seems to be a Comparator<showInfo>, making your code look like this:
if (showInfoComparator.compare(arr[j], arr[min]) < 0) {
min = j;
}
where the showInfoComparator holds the logic to compare the elements. Now your intSort would become into something more generic:
public static void genericSort(Comparator<showInfo> showInfoComparator) {
//your current implementation with few modifications
//...
//using the comparator to find the minimum element
if (showInfoComparator.compare(arr[j], arr[min]) < 0) {
min = j;
}
//...
//swapping the elements directly in the array instead of swapping part of the data
if (min != i) {
int temp = arr[i].time;
arr[i].time = arr[min].time;
arr[min].time = temp;
}
//...
}
Now, you just have to write a set of Comparator<showInfo> implementations that supports your custom criteria. For example, here's one that compares showInfo instances using the time field:
public class ShowInfoTimeComparator implements Comparator<showInfo> {
#Override
public int compare(showInfo showInfo1, showInfo showInfo2) {
//write the comparison logic
return Integer.compare(showInfo1.getTime(), showInfo2.getTime());
}
}
Another comparator that uses the name field:
public class ShowInfoNameComparator implements Comparator<showInfo> {
#Override
public int compare(showInfo showInfo1, showInfo showInfo2) {
//write the comparison logic
return showInfo1.getName().compareTo(showInfo2.getName());
}
}
Now in your code you can call it like this1:
if (*compare by time*) {
genericSort(showInfoArray, new ShowInfoTimeComparator());
}
if (*compare by name*) {
genericSort(showInfoArray, new ShowInfoNameComparator());
}
if (*another custom rule*) {
genericSort(showInfoArray, new ShowInfoAnotherCustomRuleComparator());
}
where now you can implement a custom rule like compare showInfo objects using two or more fields. Taking as example your name and day fields (as stated in the question):
public class ShowInfoNameAndDayComparator implements Comparator<showInfo> {
#Override
public int compare(showInfo showInfo1, showInfo showInfo2) {
//write the comparison logic
int nameComparisonResult = showInfo1.getName().compareTo(showInfo2.getName());
if (nameComparisonResult == 0) {
return showInfo1.getDay().compareTo(showInfo2.getDay());
}
return nameComparisonResult;
}
}
1: There are other ways to solve this instead using lot of if statements, but looks like that's outside the question scope. If not, edit the question and add it to show another ways to solve this.
Other tips for your current code:
Declare the names of the classes using CamelCase, where the first letter of the class name is Upper Case, so your showInfo class must be renamed to ShowInfo.
To access to the fields of a class, use proper getters and setters instead of marking the fields as public or leaving the with default scope. This mean, your ShowInfo class should become into:
public class ShowInfo {
private String name;
private String day;
private int time;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
//similar for other fields in the class
}
Use selection sort algorithm which is easy to implement,
for (int i = 0; i < arr.length; i++)
{
for (int j = i + 1; j < arr.length; j++)
{
if (arr[i].time > arr[j].time) // Here ur code that which should be compare
{
ShowInfo temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
no need to check min element. go through this wiki http://en.wikipedia.org/wiki/Selection_sort
Why not you use a Collection for this sort of a thingy to work. Moreover, in your added example, you are simply changing one attribute of a given object, while sorting, though you not changing the position of the object as a whole, inside the given list.
Create a List which will contain the references of all the Shows, now compare each attribute of one Show with another, in the List. Once the algorithm feels like, that swapping needs to be done, simply pick the reference from the List, save it in a temp variable, replace it with a new reference at this location, and set duplicate to the one stored in the temp variable. You are done, List is sorted :-)
Here is one small example for the same, for help :
import java.io.*;
import java.util.*;
public class Sorter {
private BufferedReader input;
private List<ShowInfo> showList;
public Sorter() {
showList = new ArrayList<ShowInfo>();
input = new BufferedReader(
new InputStreamReader((System.in)));
}
private void createList() throws IOException {
for (int i = 0; i < 5; i++) {
System.out.format("Enter Show Name :");
String name = input.readLine();
System.out.format("Enter Time of the Show : ");
int time = Integer.parseInt(input.readLine());
ShowInfo show = new ShowInfo(name, time);
showList.add(show);
}
}
private void performTask() {
try {
createList();
} catch (Exception e) {
e.printStackTrace();
}
sortByTime(showList);
}
private void sortByTime(List<ShowInfo> showList) {
int min;
for (int i = 0; i < showList.size(); i++) {
// Assume first element is min
min = i;
for (int j = i+1; j < showList.size(); j++) {
if (showList.get(j).getTime() <
showList.get(min).getTime()) {
min = j;
}
}
if (min != i) {
ShowInfo temp = showList.get(i);
showList.set(i, showList.get(min));
showList.set(min, temp);
}
}
System.out.println("TV Shows by Time");
for(int i = 0; i < showList.size(); i++) {
System.out.println(showList.get(i).getName() +
" - " + showList.get(i).getTime());
}
}
public static void main(String[] args) {
new Sorter().performTask();
}
}
class ShowInfo {
private String name;
int time;
public ShowInfo(String n, int t) {
name = n;
time = t;
}
public String getName() {
return name;
}
public int getTime() {
return time;
}
}
EDIT 2 :
For sorting By Name you can use this function :
private void sortByName(List<ShowInfo> showList) {
int min;
for (int i = 0; i < showList.size(); i++) {
// Assume first element is min
min = i;
for (int j = i+1; j < showList.size(); j++) {
int value = (showList.get(j).getName()).compareToIgnoreCase(
showList.get(min).getName());
if (value < 0)
min = j;
}
if (min != i) {
ShowInfo temp = showList.get(i);
showList.set(i, showList.get(min));
showList.set(min, temp);
}
}
System.out.println("TV Shows by Time");
for(int i = 0; i < showList.size(); i++) {
System.out.println(showList.get(i).getName() +
" - " + showList.get(i).getTime());
}
}
EDIT 3 :
Added Comparable<?> Interface, to the existing class to perform sorting based on specified input. Though one can improve on the logic, by using Enumeration, though leaving it for the OP to try his/her hands on :-)
import java.io.*;
import java.util.*;
public class Sorter {
private BufferedReader input;
private List<ShowInfo> showList;
private int command;
public Sorter() {
showList = new ArrayList<ShowInfo>();
input = new BufferedReader(
new InputStreamReader((System.in)));
command = -1;
}
private void createList() throws IOException {
for (int i = 0; i < 5; i++) {
System.out.format("Enter Show Name :");
String name = input.readLine();
System.out.format("Enter Time of the Show : ");
int time = Integer.parseInt(input.readLine());
ShowInfo show = new ShowInfo(name, time);
showList.add(show);
}
}
private void performTask() {
try {
createList();
} catch (Exception e) {
e.printStackTrace();
}
System.out.format("How would you like to sort : %n");
System.out.format("Press 0 : By Name%n");
System.out.format("Press 1 : By Time%n");
try {
command = Integer.parseInt(input.readLine());
} catch (Exception e) {
e.printStackTrace();
}
sortList(showList);
}
private void sortList(List<ShowInfo> showList) {
int min;
for (int i = 0; i < showList.size(); i++) {
// Assume first element is min
min = i;
for (int j = i+1; j < showList.size(); j++) {
showList.get(j).setValues(command);
int value = showList.get(j).compareTo(showList.get(min));
if (value < 0) {
min = j;
}
}
if (min != i) {
Collections.swap(showList, i, min);
}
}
System.out.println("TV Shows by Time");
for(int i = 0; i < showList.size(); i++) {
System.out.println(showList.get(i).getName() +
" - " + showList.get(i).getTime());
}
}
public static void main(String[] args) {
new Sorter().performTask();
}
}
class ShowInfo implements Comparable<ShowInfo> {
private String name;
private int time;
private int command;
public ShowInfo(String n, int t) {
name = n;
time = t;
}
public String getName() {
return name;
}
public int getTime() {
return time;
}
public void setValues(int cmd) {
command = cmd;
}
public int compareTo(ShowInfo show) {
int lastCmp = 1;
if (command == 0) {
lastCmp = name.compareTo(show.name);
} else if (command == 1) {
if (time < show.time) {
lastCmp = -1;
} else if (time == show.time) {
lastCmp = 0;
} else if (time > show.time) {
lastCmp = 1;
}
}
return lastCmp;
}
}
I'm using the Arrays.sort method to sort an array of my own Comparable objects. Before I use sort the array is full, but after I sort the array and print it to System nothing is printing out. EDIT. the array prints nothing at all. not empty line(s), just nothing.
here is the code for my method which uses sort :
public LinkedQueue<Print> arraySort(LinkedQueue<Print> queue1)
{
Print[] thing = new Print[queue1.size()];
LinkedQueue<Print> newQueue = new LinkedQueue<Print>();
for(int i = 0; i <queue1.size(); i++)
{
Print ob = queue1.dequeue();
thing[i] = ob;
System.out.println(thing[i]); //printing works here
}
Arrays.sort(thing);
for(int j = 0;j<thing.length-1;j++)
{
System.out.println(thing[j]); //printing does not work here
newQueue.enqueue(thing[j]);
}
return newQueue;
}
and here is the class for the Comparable object called Print.
public class Print implements Comparable<Print>
{
private String name;
private int numPages,arrivalTime,startTime,endTime;
public Print(String n, int p, int time, int sTime, int eTime)
{
name = n;
numPages = p;
arrivalTime = time;
startTime = sTime;
endTime = eTime;
}
public int getPages()
{
return numPages;
}
public int compareTo(Print other)
{
if(this.getPages()<other.getPages())
return -1;
else if(this.getPages()>other.getPages())
return 1;
else
return 0;
}
public String toString()
{
return name+"("+numPages+" pages) - printed "+startTime+"-"+endTime+" minutes";
}
}
Your last for loop doesn't print the last element in the array. If the array has only one element, it won't print anything at all. Change to:
for (int j = 0; j < thing.length; j++) //clean code uses spaces liberally :)
{
System.out.println(thing[j]);
newQueue.enqueue(thing[j]);
}
or (if supported by the JDK/JRE version used):
for (Print p : thing)
{
System.out.println(p);
newQueue.enqueue(p);
}
I hope the problem is this part of code
for(int i = 0; i <queue1.size(); i++)
{
Print ob = queue1.dequeue();
thing[i] = ob;
System.out.println(thing[i]); //printing works here
}
replace the above with
for(int i = 0; !queue1.isEmpty() ; i++)
{
Print ob = queue1.dequeue();
thing[i] = ob;
System.out.println(thing[i]); //printing works here
}
i have a task where i need to find the mode of an array. which means i am looking for the int which is most frequent. i have kinda finished that, but the task also says if there are two modes which is the same, i should return the smallest int e.g {1,1,1,2,2,2} should give 1 (like in my file which i use that array and it gives 2)
public class theMode
{
public theMode()
{
int[] testingArray = new int[] {1,1,1,2,2,2,4};
int mode=findMode(testingArray);
System.out.println(mode);
}
public int findMode(int[] testingArray)
{
int modeWeAreLookingFor = 0;
int frequencyOfMode = 0;
for (int i = 0; i < testingArray.length; i++)
{
int currentIndexOfArray = testingArray[i];
int frequencyOfEachInArray = howMany(testingArray,currentIndexOfArray);
if (frequencyOfEachInArray > frequencyOfMode)
{
modeWeAreLookingFor = currentIndexOfArray;
frequencyOfMode = modeWeAreLookingFor;
}
}
return modeWeAreLookingFor;
}
public int howMany(int[] testingArray, int c)
{
int howManyOfThisInt=0;
for(int i=0; i < testingArray.length;i++)
{
if(testingArray[i]==c){
howManyOfThisInt++;
}
}
return howManyOfThisInt;
}
public static void main(String[] args)
{
new theMode();
}
}
as you see my algorithm returns the last found mode or how i should explain it.
I'd approach it differently. Using a map you could use each unique number as the key and then the count as the value. step through the array and for each number found, check the map to see if there is a key with that value. If one is found increment its value by 1, otherwise create a new entry with the value of 1.
Then you can check the value of each map entry to see which has the highest count. If the current key has a higher count than the previous key, then it is the "current" answer. But you have the possibility of keys with similar counts so you need to store each 'winnning' answer.
One way to approach this is to check each map each entry and remove each entry that is less than the current highest count. What you will be left with is a map of all "highest counts". If you map has only one entry, then it's key is the answer, otherwise you will need to compare the set of keys to determine the lowest.
Hint: You're updating ModeWeAreLookingFor when you find a integer with a strictly higher frequency. What if you find an integer that has the same frequency as ModeWeAreLookingFor ?
Extra exercice: In the first iteration of the main loop execution, you compute the frequency of '1'. On the second iteration (and the third, and the fourth), you re-compute this value. You may save some time if you store the result of the first computation. Could be done with a Map.
Java code convention states that method names and variable name should start with a lower case character. You would have a better syntax coloring and code easier to read if you follow this convention.
this might work with a little modification.
http://www.toves.org/books/java/ch19-array/index.html#fig2
if ((count > maxCount) || (count == maxCount && nums[i] < maxValue)) {
maxValue = nums[i];
maxCount = count;
}
since it seems there are no other way, i did a hashmap after all. i am stuck once again in the logics when it comes to comparing frequencys and and the same time picking lowest integer if equal frequencys.
public void theMode()
{
for (Integer number: intAndFrequencyMap.keySet())
{
int key = number;
int value = intAndFrequencyMap.get(number);
System.out.println("the integer: " +key + " exists " + value + " time(s).");
int lowestIntegerOfArray = 0;
int highestFrequencyOfArray = 0;
int theInteger = 0;
int theModeWanted = 0;
if (value > highestFrequencyOfArray)
{
highestFrequencyOfArray = value;
theInteger = number;
}
else if (value == highestFrequencyOfArray)
{
if (number < theInteger)
{
number = theInteger;
}
else if (number > theInteger)
{
}
else if (number == theInteger)
{
number = theInteger;
}
}
}
}
Completed:
import java.util.Arrays;
public class TheMode
{
//Probably not the most effective solution, but works without hashmap
//or any sorting algorithms
public TheMode()
{
int[] testingArray = new int[] {2,3,5,4,2,3,3,3};
int mode = findMode(testingArray);
System.out.println(Arrays.toString(testingArray));
System.out.println("The lowest mode is: " + mode);
int[] test2 = new int[] {3,3,2,2,1};
int mode2=findMode(test2);
System.out.println(Arrays.toString(test2));
System.out.println("The lowest mode is: " +mode2);
int[] test3 = new int[] {4,4,5,5,1};
int mode3 = findMode(test3);
System.out.println(Arrays.toString(test3));
System.out.println(The lowest mode is: " +mode3);
}
public int findMode(int[] testingArray)
{
int modeWeAreLookingFor = 0;
int frequencyOfMode = 0;
for (int i = 0; i < testingArray.length; i++)
{
int currentIndexOfArray = testingArray[i];
int countIntegerInArray = howMany(testingArray, currentIndexOfArray);
if (countIntegerInArray == frequencyOfMode)
{
if (modeWeAreLookingFor > currentIndexOfArray)
{
modeWeAreLookingFor = currentIndexOfArray;
}
}
else if (countIntegerInArray > frequencyOfMode)
{
modeWeAreLookingFor = currentIndexOfArray;
frequencyOfMode = countIntegerInArray;
}
}
return modeWeAreLookingFor;
}
public int howMany(int[] testingArray, int c)
{
int howManyOfThisInt=0;
for(int i=0; i < testingArray.length;i++)
{
if(testingArray[i]==c){
howManyOfThisInt++;
}
}
return howManyOfThisInt;
}
public static void main(String[] args)
{
new TheMode();
}
}
Glad you managed to solve it. As you will now see, there is more than one way to approach a problem. Here's what I meant by using a map
package util;
import java.util.HashMap;
import java.util.Map;
public class MathUtil {
public static void main(String[] args) {
MathUtil app = new MathUtil();
int[] numbers = {1, 1, 1, 2, 2, 2, 3, 4};
System.out.println(app.getMode(numbers));
}
public int getMode(int[] numbers) {
int mode = 0;
Map<Integer, Integer> numberMap = getFrequencyMap(numbers);
int highestCount = 0;
for (int number : numberMap.keySet()) {
int currentCount = numberMap.get(number);
if (currentCount > highestCount) {
highestCount = currentCount;
mode = number;
} else if (currentCount == highestCount && number < mode) {
mode = number;
}
}
return mode;
}
private Map<Integer,Integer> getFrequencyMap(int[] numbers){
Map<Integer, Integer> numberMap = new HashMap<Integer, Integer>();
for (int number : numbers) {
if (numberMap.containsKey(number)) {
int count = numberMap.get(number);
count++;
numberMap.put(number, count);
} else {
numberMap.put(number, 1);
}
}
return numberMap;
}
}