import java.util.HashMap;
public class StudentDatabase {
private HashMap<String, int[]> quizmarks;
public static final int NUM_QUIZZES = 10;
public static final int MIN_GRADE = 0;
public static final int MAX_GRADE = 100;
public StudentDatabase(){
quizmarks = new HashMap<String, int[]>();
}
public String formatName(String name){
String caps = "";
String lowercase = "";
if(name != null && name.length() > 0){
caps = name.substring(0,1).toUpperCase();
}
if(name.length() > 1){
lowercase = name.substring(1).toLowerCase();
}
return caps + lowercase;
}
public void addStudent(String studentName){
if(studentName != null){
int[] marks = new int[NUM_QUIZZES];
quizmarks.put(formatName(studentName), marks);
}
}
public int[] getQuizzes(String student){
if(student != null){
System.out.println(quizmarks.get(student));
}
return null;
}
public void changeQuizMark
(String studentName, int whichQuiz, int newMark){
if(studentName!= null){
quizmarks.get(studentName);
}
if(whichQuiz <= NUM_QUIZZES){
quizmarks.get(whichQuiz);
}
if(newMark > MIN_GRADE && newMark < MAX_GRADE){
}
quizmarks.put(studentName, new int[]{newMark});
}
}
For some reason Arrays were not fully taught to us and we have been encouraged to go online to get help with it so i'm trying to figure out first of all why its saying in the addStudents method that it "cannot convert an int to an int[]" when i'm pretty sure both sides are int[] arrays when i'm trying to assign "marks".
I'm also unsure, because I can't get past this error, how my changeQuiz, and newMarks fields are actually going to assign to the right part of the array. Each student should have an array of ten quizmarks basically. And i'm insanely stuck.
I apologize i'm trying to work on the formatting but its only my second time here and I completely forget how to format, its giving me major issues and i'm trying to follow the instructions as best as I can.
Your main mistake is here:
quizmarks.put(studentName, new int[]{newMark})
You don't add new mark to already existed array of marks but create a new array with only new mark therefore deleting an old marks array. All you need is to get array you need and modify its element by index. Also made few minor improvements:
import java.util.Arrays;
import java.util.HashMap;
public class StudentDatabase {
private HashMap<String, int[]> quizmarks;
public static final int NUM_QUIZZES = 10;
public static final int MIN_GRADE = 0;
public static final int MAX_GRADE = 100;
public StudentDatabase() {
quizmarks = new HashMap<>();
}
private String formatName(String name) {
String caps = "";
String lowercase = "";
if (name != null && name.length() > 0) {
caps = name.substring(0, 1).toUpperCase();
}
if (name.length() > 1) {
lowercase = name.substring(1).toLowerCase();
}
return caps + lowercase;
}
public void addStudent(String studentName) {
if (studentName != null) {
int[] marks = new int[NUM_QUIZZES];
quizmarks.put(formatName(studentName), marks);
}
}
public void showQuizzes(String student) {
System.out.println(Arrays.toString(quizmarks.get(student)));
}
public void changeQuizMark(String studentName, int whichQuiz, int newMark) {
if (whichQuiz < NUM_QUIZZES && newMark >= MIN_GRADE && newMark =< MAX_GRADE) {
quizmarks.get(studentName)[whichQuiz] = newMark;
}
}
}
Related
I'm having an issue dealing with my java code here.
I was sure I've used al recommandation I've founded online. But it still doesn't work.
import java.util.*;
import java.util.concurrent.*;
import java.util.Map;
public class GradeCounterImpl implements GradeCounter {
ConcurrentHashMap<String, GradeCount> save;
public GradeCount[] count(String[] grades, int nThreads) {
if (grades == null) {
return new GradeCount[0];
}
if (grades.length == 0) {
return new GradeCount[0];
}
save = new ConcurrentHashMap<>();
class WorkUnit implements Runnable {
final String[] positions;
public WorkUnit(String[] i) {
this.positions = i;
}
public void run() {
for (String pos : positions)
if (pos != null) {
if (save.containsKey(pos)) {
save.get(pos).count++;
} else {
save.put(pos, new GradeCount(pos, 1));
}
}
}
}
int divide = (grades.length / nThreads);
ExecutorService exe = Executors.newFixedThreadPool(nThreads);
for (int i = 0; i < nThreads; i++)
exe.execute(new WorkUnit(arrayBetween(i * divide, (i + 1) * divide, grades)));
exe.shutdown();
try {
exe.awaitTermination(30, TimeUnit.MINUTES);
} catch (InterruptedException error) {
error.printStackTrace();
}
Collection<GradeCount> c = save.values();
return c.toArray(new GradeCount[c.size()]);
}
private String[] arrayBetween(int start, int end, String[] target) {
String[] ans = new String[end - start];
for (int i = start; i < end; i++)
if (i < target.length)
ans[i - start] = target[i];
return ans;
}
}
public class GradeCount implements Comparable<GradeCount> {
public String grade;
public int count;
public GradeCount(final String grade, final int count) {
this.grade = grade;
this.count = count;
}
public int compareTo(final GradeCount other) {
final int gradeCmp = this.grade.compareTo(other.grade);
return gradeCmp == 0 ? Integer.compare(this.count, other.count) : gradeCmp;
}
}
What it's to do ?
The code must be counting every String appearing in the grades array and saving the results in the hashmap and then returning their values.
What's the problem ?
The code isn't (as you can guest with the title) not working fine. It doesn't count well and I'm having huge difference between big arrays tests.
Observations :
When I test with small arrays (0 - 50 values), the program run well
Now : What should I do ?
Thanks you for reading all here and I hope you can help me.
The problem is here:
if (save.containsKey(pos)) {
save.get(pos).count++;
} else {
save.put(pos, new GradeCount(pos, 1));
}
You have a ConcurrentHashMap but your GradeCounter is not synchornized, hence call to count++ will not correct
I think your GradeCount look like {grade, count} so I suggest you to use Map<String, AtomicInteger> isntead
I have a file with over 1000 names it also include the sex and how many people have the name.
example
Sarah F 2000
I am trying to print the first 10 lines that was created from my for loop, but for some reason what i tried is only printing the last line 10 times.
import java.util.*;
import java.io.*;
import java.util.Collections;
public class NameYear
{
private String year;
ArrayList<OneName> oneName = new ArrayList<OneName>();
public NameYear(String year)
{
String line = "";
String Top = "";
Scanner sc = null;
try
{
sc = new Scanner(new File
("/home/mathcs/courses/cs225/koch/names/yob"+year+".txt"));
}
catch (Exception e)
{
System.out.println("Error Year should be between 1880 and 2013 not "+ year);
System.exit(1);
}
while(sc.hasNextLine())
{
// read a line from the input file via sc into line
line = sc.nextLine();
StringTokenizer stk = new StringTokenizer(line, ",");
String name = stk.nextToken();
char sex = stk.nextToken().charAt(0);
int count = Integer.parseInt(stk.nextToken());
OneName list = new OneName(name, sex, count);
oneName.add(list);
}
for (int i = 0 ; i < 10; i++)
{
System.out.println(descending());
}
public String descending()
{
String x = "";
Collections.sort(oneName, new OneNameCountCompare());
for(OneName b: oneName)
{
x = b.toString();
}
return x;
OneName file
public class OneName
{
private String Name;
private char Sex;
private int Count;
public OneName(String name, char sex, int count)
{
Name = name;
Sex = sex;
Count = count;
}
public String getName()
{
return Name;
}
public char getSex()
{
return Sex;
}
public int getCount()
{
return Count;
}
public void setName(String name)
{
if (name.length() < 1)
{
throw new NullPointerException("Baby name is missing");
}
Name = name;
}
private char M;
private char F;
public void setSex(char sex)
{
if( sex != M)
{
if(sex != F)
{
throw new IllegalArgumentException("Sex has to be M or F");
}
}
Sex = sex;
}
public void setCount(int count)
{
if(count < 0)
{
throw new IllegalArgumentException("Count cant be negative");
}
Count = count;
}
public String toString()
{
return String.format("%s %c %d", Name, Sex, Count);
}
}
OneNameCount
import java.util.Comparator;
import java.util.Collections;
public class OneNameCountCompare implements Comparator<OneName>
{
public int compare(OneName b1, OneName b2)
{
if(b1.getCount() <b2.getCount())
{
return 1;
}
else
{
return -1;
}
}
}
Main Program
import java.io.*;
import java.util.*;
public class TopNames
{
public static void main(String args[])
{
String line = ""; // string var to hold entire line
if (args.length < 1)
{
System.out.println("\nYou forgot to put a Year on the command line.");
System.exit(1);
};
String inFile = args[0]; // file name off command line
String year = inFile;
NameYear list = new NameYear(year);
}
}
Your descending function returns one string, and always the same string (the last one in the order after sorting the collection). It doesn't matter how often you call it, if the data doesn't change, you'll always get back that same, last, string.
If you want the first 10 after sorting, descending would need to return a List<String> containing those 10:
public List<String> descending()
{
List<String> x = new ArrayList<String>(10);
Collections.sort(oneName, new OneNameCountCompare());
for(OneName b: oneName)
{
x.add(b.toString());
if (x.size() == 10) // Or don't use enhanced for, use an index instead
{
break;
}
}
return x;
}
Then when printing it, replace your for (int i = 0 ; i < 10; i++) loop with:
for (String s : descending())
{
System.out.println(s);
}
Your error is here:
for (int i = 0 ; i < 10; i++) {
System.out.println(descending());
}
public String descending() {
String x = "";
Collections.sort(oneName, new OneNameCountCompare());
for(OneName b: oneName) {
x = b.toString();
}
return x;
}
First of all in your for loop you are not using the i variable that is your count indicator. This means that the descending() method has no any awareness of i, how he could return something different?
Try to modify descending() in something like this:
public String descending(int i) {
String x = "";
Collections.sort(oneName, new OneNameCountCompare());
OneName b = oneName.get(i);
x = b.toString();
return x;
}
My program is working fine on all parts except one. I am attempting to post as little code as possible. Please let me know if more is needed.
How do I find the name that occurs the most in a String, or StringBuilder? The "getWinner" method is where I am having trouble. I want to find the name (or winner) that occurs the most in a string. If their is a tie, the name that appears first is sufficient. Thanks in advance!
import java.util.ArrayList;
public class BallotBox
{
private ArrayList<String> ballots;
public BallotBox()
{
ballots = new ArrayList<String>();
}
public void addVote(String candidate)
{
ballots.add(candidate);
}
//****below is the method that's presenting a problem.****
public String getWinner()
{
StringBuilder candidates = new StringBuilder();
String winner = "";
for(int i = 0; i < ballots.size(); i++)
{
}
return winner;
}
public int getVoteCount(String candidate)
{
int count = 0;
for(int i = 0; i < ballots.size(); i++)
{
if(ballots.get(i).equals(candidate))
{
count++;
}
}
return count;
}
public String getResults()
{
StringBuilder resultTable = new StringBuilder();
ArrayList<String> printed = new ArrayList<String>();
for (String candidate : ballots)
{
if (!printed.contains(candidate))
{
resultTable.append(String.format("%s (%d)\n", candidate, getVoteCount(candidate)));
printed.add(candidate);
}
}
return resultTable.toString();
}
}
You can try to convert the list to a Set and use the Collections.frequency method.
Set<String> uniqueSet = new HashSet<String>(list);
for (String temp : uniqueSet)
{
System.out.println(temp + ": " + Collections.frequency(list, temp));
}
You'll get the output as shown below.
d: 1
b: 2
c: 2
a: 4
Check the link for more details
http://www.mkyong.com/java/how-to-count-duplicated-items-in-java-list/
You can use a HashMap to keep the votes for every candidate, and update the winner as soon as you find a new winner (more votes than the current winner):
public String getWinner()
{
final Map<String, Integer> votesCount = new HashMap<String, Integer>();
String winner = ballots.get(0);
int winnerVotes = 1;
for(final String ballot : ballots)
{
if (!votesCount.containsKey(ballot))
votesCount.put(ballot, 0);
votesCount.put(ballot, votesCount.get(ballot)+1);
if (votesCount.get(ballot)>winnerVotes)
{
winner = ballot;
winnerVotes = votesCount.get(ballot);
}
}
return winner;
}
Here is a working example. Hope this explains how the above code can be used in your application.
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class BallotBox
{
private ArrayList<String> ballots;
public BallotBox()
{
ballots = new ArrayList<String>();
ballots.add("John");
ballots.add("Eric");
ballots.add("Mary");
ballots.add("Eric");
ballots.add("Mary");
ballots.add("Mary");
ballots.add("John");
ballots.add("Mary");
}
public void addVote(String candidate)
{
ballots.add(candidate);
}
// ****below is the method that's presenting a problem.****
public String getWinner()
{
String winner = "";
// To check who has the highest votes.
int highestVotes = 0;
Set<String> uniqueSet = new HashSet<String>(ballots);
for (String temp : uniqueSet)
{
// The count of each Candidate's votes.
int count = Collections.frequency(ballots, temp);
// The winner is the one with the highest votes.
if(count > highestVotes)
{
highestVotes = count;
winner = temp;
}
}
return winner;
}
public static void main(String[] args)
{
BallotBox ballotBox = new BallotBox();
System.out.println(ballotBox.getWinner());
}
}
Following is the question which I am trying to solve-
In a one day international, the bowling figures of all the bowlers have been provided. The objective is to create an array of Bowler and return it. Note that the objects should appear in the same order in the array as they appear in the input.
The input is provided a string. The string has space demarcated details of each bowler provided as Name-Overs-Maiden-Runs-Wickets, like , “Zaheer-10-1-55-0 Harbhajan-8.4-0-44-2 Ishant-10-0-71-1″.Define a function that takes and prints the array of Bowler returned.
There is some error in the code but I am unable to detect it.
public class MakeArrayOfBowlers{
String name;
double over;
int maiden;
int runs;
int wickets;
public MakeArrayOfBowlers(String input){
String[] str=input.split("-");
this.name=str[0];
this.over=Double.parseDouble(str[1]);
this.maiden=Integer.parseInt(str[2]);
this.runs=Integer.parseInt(str[3]);
this.wickets=Integer.parseInt(str[4]);
}
public MakeArrayOfBowlers[] makeBowlers (String input){
MakeArrayOfBowlers str= (MakeArrayOfBowlers) new MakeArrayOfBowlers("Zaheer-10-1-55-0 Harbhajan-8.4-0-44-2 Ishant-10-0-71-1");
String[] str1 = input.split(" ");
MakeArrayOfBowlers bowler[]= new MakeArrayOfBowlers[str1.length];
for(int i = 0; i < str1.length; i++){
bowler = new MakeArrayOfBowlers[str1.length];
MakeArrayOfBowlers obj = new MakeArrayOfBowlers(str1[i]);
bowler[i] = obj;
}
return bowler;
}
}
You should make a own class bowler (constructor should be better but its your example ;)):
public class Bowler {
private String name;
private double over;
private int maiden;
private int runs;
private int wickets;
public Bowler(String input){
String[] str=input.split("-");
this.name=str[0];
this.over=Double.parseDouble(str[1]);
this.maiden=Integer.parseInt(str[2]);
this.runs=Integer.parseInt(str[3]);
this.wickets=Integer.parseInt(str[4]);
}
public String getName() {
return name;
}
public double getOver() {
return over;
}
public int getMaiden() {
return maiden;
}
public int getRuns() {
return runs;
}
public int getWickets() {
return wickets;
}
}
Than split your string and add it for every bowler:
public class MakeArrayOfBowlers {
public static Bowler[] makeBowlers(String input) {
String[] splitArray = input.split(" ");
Bowler[] bowler = new Bowler[splitArray.length];
for (int i = 0; i < splitArray.length; i++) {
bowler[i] = new Bowler(splitArray[i]);
}
return bowler;
}
public static void main(String[] args) {
Bowler[] bowlers = makeBowlers("Zaheer-10-1-55-0 Harbhajan-8.4-0-44-2 Ishant-10-0-71-1");
for (Bowler bowler : bowlers) {
System.out.println(bowler.getName()+"-"+bowler.getOver()+"-"+bowler.getMaiden()+"-"+bowler.getRuns()+"-"+bowler.getWickets());
}
}
}
You're re-initializing the bowler array inside the for-loop. Try removing that line (the first line inside your loop).
public MakeArrayOfBowlers[] makeBowlers (String input){
String[] str1 = input.split(" ");
MakeArrayOfBowlers bowlers[]= new MakeArrayOfBowlers[str1.length];
for(int i = 0; i < str1.length; i++){
MakeArrayOfBowler bowler = new MakeArrayOfBowlers(str1[i]);
bowlers[i] = obj;
}
return bowlers;
}
From your main function call
MakeArrayOfBowlers o = new MakeArrayOfBowlers();
MakeArrayOfBowlers[] b = o.makeBowlers("Zaheer-10-1-55-0 Harbhajan-8.4-0-44-2 Ishant-10-0-71-1");
I have this assignment that I need use a static method to get student IDs then within that static method evaluate them if the students have passed or failed their classes. It is a bit challenging for me because the static method should only take one argument.
Can this be accomplished by not changing private variables to private static variables?
Any direction is much appreciated.
import java.util.ArrayList;
public class Grade {
public static void main(String[] args) {
ArrayList<GradeDetail> gradeList = new ArrayList<GradeDetail>() ;
System.out.println("Student ID: ");
for(String s : args) {
boolean match = false;
for(GradeDetail grade : GradeDetail.values()) {
if(s.equals(grade.getCode())) {
gradeList.add(grade);
match = true;
}
}
if(!match) {
System.out.printf("unknown student ID entered!");
}
}
System.out.println("Students who passed: ");
//Some function here
System.out.println("Students who failed: ")
//Some function here
return;
}
}
enum GradeDetail {
JOHN (101, 90)
, ROB (102, 50)
, JAMES (103, 55)
;
private final int studentID;
private final int studentGrade;
GradeDetail(int id, int sGrade) {
studentID = id;
studentGrade = sGrade;
}
public int getID() {return studentID;}
public int getGrade() {return studentGrade;}
}
I honestly don't know how to go about this..
Enums are for Static data such as the value of the grade A, B, C. You would never store transient values like John's grade in an Enum. Why don't you try using the enum for the static values.
enum GradeRange {
A (100, 90),
B (89, 80),
C (79, 70);
private final int high;
private final int low;
GradeRange(int high, int low) {
high = high;
low = low;
}
public GradeRange getGrade(int percent) {
for (GradeRange gradeRange : GradeRange.values() {
if (percent <= high && percent >= low)
return gradeRange;
}
}
}
PS - I did not test this code
It would be appropriate to store your data in a class like
class GradeDetail {
public final String sName ;
public final int iId ;
public final int iGrade;
public GradeDetail(String s_name, int i_id, int i_grade) {
sName = s_name;
iId = i_id;
iGrade = i_grade;
}
}
You would then create instances with
GradeDetail gdJohn = new GradeDetail("John", 101, 90)
and access it, for example, with
gdJohn.iGrade;
This should hopefully get you started on the right path.