I'm trying to search an ArrayList and find the highest student mark. The values are randomly inputted. I have written code that works if the values are in order. But when I try to enter values in a random order, the loop always returns the last value entered! (Which is starting to frustrate me a little as I thought it worked!) It's probably something simple but I have missed the point again.
One other note .getName retrieves the student name with the highest mark.
Here is the code:
public String top()
{
int highest = 0;
int k;
for (k = 0; k < people.size();k++)
{
if (people.get(k).getMark() > highest)
{
highest = k;
}
}
return people.get(highest).getName();
}
You're setting highest to the index of the student with the highest mark, not to the highest mark itself. You probably want to keep both:
public String top()
{
int highestIndex = 0;
int highestMark = people.get(0).getMark();
for (int k = 1; k < people.size(); k++)
{
int mark = people.get(k).getMark();
if (mark > highestMark)
{
highestMark = mark;
highestIndex = k;
}
}
return people.get(highestIndex).getName();
}
Note two other changes I've made:
There's no point in declaring k before the loop; in general, it's tidiest to give local variables the smallest scope you can
I've used initial values from the first person in the collection; this will now work with negative marks as well
Separately, you should think about what you want to happen if people is empty. (Currently the code will throw an exception.)
the problem is that highest is the index, so your if condition should be:
if (people.get(k).getMark() > people.get(highest).getMark())
You can also store both the highest value and the index in two variables:
int highestVal = -1;
int highestIdx = -1;
for (int k = 0; k < people.size(); k++)
{
if (people.get(k).getMark() > highestVal)
{
highestVal = people.get(k).getMark();
highestIdx = k;
}
}
return people.get(highestIdx).getName();
You are comparing indices and values.
Try:
if (people.get(k).getMark() > people.get(highest).getMark())
You're confusing what your variables represent. You're comparing the indivduals marks to 'highst', but then you're setting highest to equal the index of that person (k).
So you're comparing indexes with marks...
highest is the index, you are comparing the mark to the index of the mark
if (people.get(k).getMark() > highest)
Instead of comparing to highest in the loop you should compare to people.get(highest).getMark()
Use an extra variable to hold the person's index.
public String top()
{
int highest = 0;
int k;
int topPerson;
for (k = 0; k < people.size();k++)
{
if (people.get(k).getMark() > highest)
{
highest = people.get(k).getMark() ;
topPerson = k;
}
}
return people.get(topPerson).getName();
}
try this one :)
public String top()
{
int highest = 0;
int k;
for (k = 1; k < people.size();k++)
{
if (people.get(k).getMark() > people.get(highest).getMark())
{
highest = k;
}
}
return people.get(highest).getName();
}
Related
Hello all please check the problemHackerRank Problem Statement
This is my solution for the above problem(link)
static int migratoryBirds(List<Integer> arr) {
int ar[]=new int[arr.size()];
for(int i=0;i<arr.size();i++){
ar[i] = Collections.frequency(arr,arr.get(i));
// ar[i] = obj.occuranceOfElement(arr,arr.get(i));
}
int maxAt = 0;
for (int i = 0; i < ar.length; i++) {
maxAt = ar[i] > ar[maxAt] ? i : maxAt;
}
return arr.get(maxAt);
}
my code is unable to handle when the array size is bigger,example 17623 elements in array.
Terminated due to timeout
The problem is in the second for loop which iterates over the array and gives me the index of the largest number in the array.Is there any other way that I could increase the performance.
Your problem is in this part:
for(int i = 0; i < arr.size(); i++)
ar[i] = Collections.frequency(arr, arr.get(i));
This is O(N²): Collections.frequency() iterates over whole list to calculate frequency for only one element. Manually, you can iterate over the list to calculate frequencey for all elements.
Moreover, ther're only 5 birds, so you need only 5 length array.
static int migratoryBirds(int[] arr) {
int max = 1;
int[] freq = new int[6];
for (int val : arr)
freq[val]++;
for (int i = 2; i < freq.length; i++)
max = freq[i] > freq[max] ? i : max;
return max;
}
Your problem is the call to Colletions.frequency, which is an O(N) operation. When you call it from inside a loop it becomes O(N²) and that consumes all your time.
Also, are you sure which implmentation of List you receive? You call list.get(i) which might also be O(N) if the implementation is a LinkedList.
The target of this exercise is to calculate the frequency of each value in one pass over the input. You need a place where you store and increase the number of occurrences for each value and you need to store the largest value of the input.
You have also skipped over a crucial part of the specification. The input has limits which makes solving the problem easier than you now think.
Here's another one:
static int migratoryBirds(List<Integer> arr) {
int freq[]=new int[6];
for(int i=0;i<arr.size();i++){
++freq[arr.get(i)];
}
int maxAt = 1;
for (int i = 2; i < freq.length; i++) {
if (freq[i] > freq[maxAt]) {
maxAt = i;
}
}
return maxAt;
}
We can determine the type number of the most common bird in one loop. This has the time complexity O(n).
static int migratoryBirds(int[] arr) {
int highestFrequency = 0;
int highestFrequencyBirdType = 0;
int[] frequencies = new int[5]; // there are 5 bird types
for (int birdType : arr) {
int frequency = ++frequencies[birdType - 1];
if (frequency > highestFrequency) {
highestFrequency = frequency;
highestFrequencyBirdType = birdType;
} else if (frequency == highestFrequency && birdType < highestFrequencyBirdType) {
highestFrequencyBirdType = birdType;
}
}
return highestFrequencyBirdType;
}
For each element in the array arr we update the overall highestFrequency and are storing the corresponding value representing the highestFrequencyBirdType . If two different bird types have the highest frequency the lower type (with the smallest ID number) is set.
My instructions are: Create a sensor object that refers to element zero. Write a for loop that starts at element 1, loops through all the elements of the arraylist and check to see if the value of the sensor reading is smaller than element zero. I am supposed to assume that element zero has the minimum value already. If the value is smaller, set that as the minimum value. Here is the code I have, but it is not finding the minimum value.
public int findMinReadingIndex() {
ArrayList<SensorReading> sensorReadings = new ArrayList<>();
sensorReadings.get(0);
int minIndex = 0;
for(int i=1; i< sensorReadings.size(); i++) {
if (this.sensorReadings.get(i).getValue() < i)
minIndex = i;
}
return minIndex;
}
It is better to focus on the problem: you have a list, and you want to find an index with minimum value. So you have to write method that accepts List<SensorReading> and retrieves int value. Note, that using get() is not optimal, especially if you do not know concrete implementation of the List. You have to use iterator instead.
public int findMinReadingIndex(List<SensorReading> sensorReadings) {
int minIndex = 0;
int minValue = 0;
int i = 0;
for(SensorReading sensorReading : sensorReadings) {
if(i == 0 || sensorReading.getValue() < minValue) {
minValue = sensorReading.getValue();
minIndex = i;
}
i++;
}
return minIndex;
}
Minor change is below:
public int findMinReadingIndex() {
ArrayList<SensorReading> sensorReadings = new ArrayList<>();
float minReading = sensorReadings.get(0).getValue();
int minIndex = 0;
for(int index = 1; index < sensorReadings.size(); index ++) {
float reading = this.sensorReadings.get(index).getValue();
if (reading < minReading)
minIndex = index;
}
return minIndex;
}
If you using Java 8 one liner code use stream with Comparator API.
SensorReading minVal = sensorReadingList.stream().min(Comparator.comparing(SensorReading::getValue))
.orElseThrow(NoSuchElementException::new);
System.out.println(minVal.getValue());
First of all calling stream() method on the list to get a stream of
values from the list.
After that call to min() method on the stream to get the minimum
value from the list.
We are passing a lambda function as a comparator, sort the list and
deciding the minimum value.
After that we call orElseThrow() to throw an exception if no value
is received from min()
I have an array of grades(g) which is an int[] and I'm trying to find the largest grade in that array. I have tried this:
public static String highestGradeName(int[] g, String[] n) {
String highStudent;
int highest = g[0];
for (int i=1; i < g.length; i++) {
if (highest < g[i]) {
highStudent = n[i+1];
return (highStudent);
}
}
return null;
}
I have another array which is a String array and contains the names of the students, I have the return null there because it said it needed a return statement however I didn't plan on it ever being null. What's causing it to return null instead of highstudent?
I've used the exact code to find the lowest grade and it works fine the only thing I did to this one was change the if statement from highest > g[i] to highest < g[i].
Returning from inside the loop is wrong, as you can always have an even larger number later on in the array. You should keep the index of the highest grade and just return the corresponding name at the end:
public static String highestGradeName(int[] g, String[] n) {
int highest = 0;
for (int i = 1; i < g.length; i++) {
if (g[highest] < g[i]) {
highest = i;
}
}
return n[highest];
}
According to your logic let's break things.
Raw Test Case:
Take {0,1,2} as an integer arrays.
Take {"arya", "jon", "tyrion"} as an string arrays.
highest = 0; // according to your code.
For int i = 1, i < 3; i++
0 < 1
highstudent = 2 // tyrion
// returns tyrion
The reason why you are getting null is your integer at 0 index should be greater or equal to the index at 1.
Now, when you are using a type String in your method. You should return a string and that's what your editor said to have something return. You should use return out of the loop because you need to find the highest student which is only possible after looping all the list.
You can try this:
public static String highestGradeName(int[] g, String[] n) {
int max = 0;
int index = 0;
for (int i = 0; i < g.length; i++) {
if (max < g[i]) {
max = g[i];
index = i;
}
}
return n[index];
}
PS: Imporve code according to mureinik answer, I have one more variable to help you understand easily.
I'm trying to return the first index of the max value of an ArrayList<Integer>. The code below finds the second maximum instead of the first. How do I return the first max value encountered by the loop?
public int findIndexOfMax() {
int maxIndex = 0;
for (int k = 0; k < myFreqs.size(); k++) {
if (myFreqs.get(k) > maxIndex) {
maxIndex = myFreqs.get(k);
}
}
return maxIndex;
}
What gets returned is 'test. 3'. But it should be the first max which is 3 for the letter 'a'.
Number of unique words: 7
1 this
1 is
3 a
3 test.
1 yes
1 test
1 of
The word that occurs most often and its count are: test. 3
You seem to have forgotten to access the element at the maxIndex in your comparison. And you set the index to the value of the element in your if (instead of the index). I think you wanted,
public int findIndexOfMax() {
int maxIndex = 0;
for (int k = 1; k < myFreqs.size(); k++) {
if (myFreqs.get(k) > myFreqs.get(maxIndex)) {
maxIndex = k;
}
}
return maxIndex;
}
I think you are using the integers on the left as index for the Strings on the right and when you use 3 as index for the second time it is overlapping the value "a" with "test".
since there is a tie between "a" and "test." Frequencies, you want to return the first value which is "a" with the occurrence of 3
to do so, you need to find the max value and its position in myFreqs and then get the value of the other ArrayList containing the words at the index of the position of the max value.
int maxElement = 0;
int maxPosition = 0;
for(int i = 0; i < this.myFreqs.size(); i++){
if(this.freqs.get(i) > maxElement){
maxElement = this.freqs.get(i);
maxPosition = i;
}
}
return maxPosition;
now you can simply find the first most frequent word in the arrayList of the words:
words.get(maxFreq)
Hey guys I'm really struggling with trying to print my array index and element value, I posted a question a few days ago and got really helpful advice but cannot seem to get this part right at all, I am able to print the 1st index of the array (distance) but not able to print the entire thing without losing the original index value:
double minVal = Double.MAX_VALUE;
int minIndex = -1;
for (int i=0, max=distances.length; i<max;i++) {
if (distances[i] < minVal) {
minVal = distances[i];
minIndex = i;
//Gets the minimum point and minimum distance
}
}
System.out.println("The Nearest to point K is point: "+minIndex+" with distance "+minVal);
Really sorry to keep bringing this matter up but really have tried and cannot get it to work for the life of me any help or advice would be appreciated.
First, you sort
for (int i=0; i<distances.length; i++) {
for(int j = i+1; j<distances.length; j++)
{
if (distances[i] > distances[j])
{
double temp = distances[j];
distances[j] = distances[i];
distances[i] = temp;
}
}
}
Then, you merely print
for (int i=0; i<distances.length; i++) {
System.out.println(i + " -> " + distances[i]);
}
If you want to keep the original indexes, you can do that too.
the most obvious way would be to have a second paralell array, and sort that along with your original array
example:
if (distances[i] < minVal)
{
double temp = distances[j];
int tempindex = indices[j];
...
the better way would be to make a class with an index(or more appropriately named, an ID), and a value(which is your double), and sort an array of type Distance.
.
Class Distance
{
public int ID;
public double value;
}
Try change the for loop to for(int i=0; max = distances.length && i < max; i++){...}