Counting most freq. user in an array - java

int totalEnrolled = studentEnrollments.size();
String mostFreqUser = "";
int count = 0;
System.out
.println("~~~~~~~~~~~~~~~Spring 2016 Enrollment~~~~~~~~~~~~~~~");
for (String userName : studentEnrollments.keySet()) {
System.out.println("Student: " + userName);
ArrayList<String> courses = studentEnrollments.get(userName);
String courseMessage = "Courses: ";
String seperator = "";
// looping through courses
for (String singleCourse : courses) {
// counting how many courses were enrolled
count++;
courseMessage += seperator += singleCourse;
System.out.println(courseMessage);
seperator = ",";
}
}
System.out.println("Total students enrolled: " + totalEnrolled);
System.out.println("Total courses enrolled: " + count);
System.out.println(mostFreqUser);
}
}
Hello, I was wondering how would I make a counter for the most frequent user. Everytime the for loop runs It would calculate who put there username the most. Also one more thing, how come the output prints multiple courses not just one for each name. For example instead of printing a course line for each courses it prints it twice.
for example the expected output looks like
Student: josh
Courses: cs170, cs180
but the output looks like
Student: josh
Courses:cs170
Courses:cs170,cs170
Thank you, please let me know if you need any more details.

Move the print statement outside the inner for loop.
Note: It's spelled "separator".
Don't do a chained +=.
NOTE: If you see the same course name listed multiple times for a student, then your studentEnrollments Map-List is likely wrong, not your displayed code.
The following code also shows how to find the student with the largest number of courses (aka the "mostFreqUser"). There can of course be more than one student with that many courses, but only the first is shown.
System.out.println("~~~~~~~~~~~~~~~Spring 2016 Enrollment~~~~~~~~~~~~~~~");
int courseTotal = 0;
int maxCourseCount = 0;
String maxCourseStudent = "";
for (String student : studentEnrollments.keySet()) {
System.out.println("Student: " + student);
ArrayList<String> courses = studentEnrollments.get(student);
String courseMessage = "Courses: ";
String separator = "";
for (String course : courses) {
courseMessage = courseMessage + separator + course;
separator = ",";
}
System.out.println(courseMessage);
courseTotal += courses.size();
if (courses.size() > maxCourseCount) {
maxCourseCount = courses.size();
maxCourseStudent = student;
}
}
System.out.println("Total students enrolled: " + studentEnrollments.size());
System.out.println("Total courses enrolled: " + count);
System.out.println("Most frequent student: " + maxCourseStudent + " (enrolled in " + maxCourseCount + " courses)");

For the first part you can use a Hashtable. Initialize your hashtable with a value of 1 whenever a user is seen for the first time. Subsequently, increment the hashtable count if a user is seen again. Finally, go through each element of the hashtable to find the largest value.
For the second part, you need to bring the second print statement outside of the for loop.

You are printing courseMessage in course loop. So it will print courseMessage for each course in course collection. That is why you're getting two inputs.
Also following statement will affect your output
courseMessage += seperator += singleCourse;
This should be written as
courseMessage += seperator + singleCourse;
DEMO FOR += PROBLEM
Suppose we have two courses in our list say cs150 and cs160.Initially,
courseMessage = "Courses : ";
separator = "";
For first course, cs150,
courseMessage += separator += singleCourse;
=>
couresMessage += separator = separator + "cs150";
=>
courseMessage += separator = "cs150";
=>
courseMessage += "cs150";
=> courseMessage = "Courses : cs150";
So after first iteration, courseMessage will be Courses : cs150 and separator will be cs150.
Here you modifies value of separator accidentally, which will reflect in consequent iteration and you will get unexpected output.

Related

Name Reversing in strings

Write a method lastNameFirst that takes a string containing a name such as "Harry Smith" or "Mary Jane Lee", and that returns the string with the last name first, such as "Smith, Harry" or "Lee, Mary Jane".
im supposed to check it against
http://wiley.code-check.org/codecheck/files?repo=bjlo2&problem=05_02
i post this
String firstName = name.substring(0, name.indexOf(" "));
String lastName = name.substring(name.indexOf(" "));
String cName = lastName + ", " + firstName;
if ( lastName == " " )
{
cName = firstName;
}
return cName;
I get 0/4 everytime please help im completely lost.
It might be simpler to create an array using the split function of the String class, then join them:
String cName = String.join(", ", Collections.reverse(Arrays.asList(name.split(" "))));
String.join is only in Java 8 I believe, if you're not using 8 you can use something like the following:
String[] names = name.split(" ");
String cName = names[1] + ", " + names[0];
You should also be using the equals method for comparing String and other objects:
String[] names = name.split(" ");
String cName = names[1].equals(" ") ? names[0] : names[1] + ", " + names[0];
Please try this code
String first = name.substring(name.lastIndexOf(" "));
String last = name.substring(0, name.lastIndexOf(" "));
String result = first + "," + last;
Your solution is very close. Here's 2 hints to get to the right solution:
What separates the first and last name is the last, not the first space (consider using str.lastIndexOf(" ")).
As mentioned in the comments, when comparing strings, you can't use str1 == str2, you have to use str1.equals(str2)
You only need the last space in your name, which you can get with String.lastIndexOf(int). Then you test if that is less then 0, if so return the input name. Otherwise, concatenate and return your name in the desired format. Using a ternary (or conditional operator ? :) that might look something like,
int p = name.lastIndexOf(' ');
return (p < 0) ? name : name.substring(p + 1) + ", " + name.substring(0, p);
I put this for that Question and it passed all 4 tests they had.
public static String lastNameFirst(String name)
{
String LastToFirst = "";
if(!name.contains(" ")){
return name;
}
int index = name.indexOf(" ");
int secondIndex = name.indexOf(" ", index + 1);
// exclusive of last index
if(secondIndex != -1) {
LastToFirst += name.substring(secondIndex+1,name.length())+", ";
LastToFirst += name.substring(0,secondIndex);
}
else {
LastToFirst += name.substring(index +1,name.length()) + ", ";
LastToFirst += name.substring(0, index);
return LastToFirst;
}
A better solution for this would be to use an array, and store the characters in there and for the spacing one should add an index variable for where you want the splitting to happen- the string of interest. The solutions above do a good example of expalining this better, they consider cases where it is not a white space, but other symbols making the method more robust. Hope this helps.
I tried this code and all the four arguement works. Hope this helps!!
{
String[] names = name.split(" ");
String cName = "";
if(names.length > 2){
cName = names[2].equals(" ") ? names[0] : names[2] + ", " + names[0] + " " + names[1];
}
else if(names.length == 1){
cName = names[0]
}
else{
cName = names[1].equals(" ") ? names[0] : names[1] + ", " + names[0];
}
return cName;
}
}
public class Names
{
/**
Changes a name so that the last name comes first.
#param name a name such as "Mary Jane Lee"
#return the reversed name, such as "Lee, Mary Jane".
If name has no spaces, it is returned without change.
*/
public static String lastNameFirst(String name)
{
String result = "";
if(!name.contains(" "))
{
String firstOnly = name.substring(0);
return firstOnly;
}
else
{
String first = name.substring(name.lastIndexOf(" ")+1);
String last = name.substring(0, name.lastIndexOf(" "));
result = first + ", " + last;
return result;
}
}
}
This is the correct answer that will get you 4/4.

How would I print out a string of arrays without the last comma?

for (String userName : studentEnrollments.keySet()) {
System.out.println("Student: " + userName);
ArrayList<String> courses = studentEnrollments.get(userName);
String courseMessage = "Courses: ";
for (String singleCourse : courses) {
courseMessage += singleCourse + ", ";
System.out.println(courseMessage);
}
}
After the for loop, it prints out each courses the student is taking. What is the proper way to print out the string with commas without the last comma at the end?
For example: AC130, AC140, AC150, to AC130, AC140, AC150
Use a while with Iterator instead of for loop, then add a coma only if hasNext() returns true.
String courseMessage = "Courses: ";
Iterator<String> c = studentEnrollments.get(userName).iterator();
while (c.hasNext()) {
courseMessage += c.next();
if (c.hasNext()) {
courseMessage += ",";
}
}
Note that in Java 8 you can use StringJoiner:
String commaSeparatedCourses = courses.stream().collect(Collectors.joining(", "));
You can use StringUtils.join method from apache
Example :
StringUtils.join(studentEnrollments, ", ");
you could use a StringJoiner if you are using java 8
StringJoiner joiner = new StringJoiner(", ");
for (String singleCourse : courses) {
joiner.add(singleCourse);
}
System.out.println(joiner.toString());
Otherwise you could just add the , previous to the string instead of appending it.
String courseMessage = "Courses: " + courses.get(0);
for (int i = 1; i<courses.size();++i) {
courseMessage += ", " + courses.get(i);
}
Here is another way to do it :
Define an empty string as a separator
Print the separator and the array element (in this order, the separator first)
Change the separator to a comma (or whatever you want)
This method reverse the problem : instead of adding a comma after each element except the last one, you add a comma before each element except the first one.
Here is an implementation
String separator = "";
for (String singleCourse : courses) {
courseMessage += separator + singleCourse;
System.out.println(courseMessage);
separator = ",";
}
With a StringBuilder:
for (String userName : studentEnrollments.keySet()) {
System.out.println("Student: " + userName);
ArrayList<String> courses = studentEnrollments.get(userName);
StringBuilder sb = new StringBuilder();
for (String singleCourse : courses) {
if(sb.length()>0){
sb.append(", ");
}
sb.append(singleCourse);
}
System.out.println(sb.insert(0, "Courses: ").toString());
}
For a solution prior Java 8 you also might have a look at this snippet as starting point
String[] courses ={ "AC130", "AC140", "AC150" };
for (int i = 0; i < courses.length - 1; i++) {
System.out.append(courses[i]).append(", ");
}
System.out.println(courses[courses.length-1]);
Small explanation: for all elements but the last one it print "element" + ", " for the last element it print "element" only. You need to ensure yourself, that an empty array would not be processed.
Use StringBuilder instead
for (String userName : studentEnrollments.keySet()) {
System.out.println("Student: " + userName);
ArrayList<String> courses = studentEnrollments.get(userName);
StringBuilder courseMessage = "Courses: ";
for (String singleCourse : courses) {
sb.append(singleCourse).append(", ");
}
if (sb.length() > 2)
sb.setLength(sd.length() -2);
String courseMessage = sb.toString();
System.out.println(courseMessage);
}
Or even better with StringUtils (from apache-common)
for (String userName : studentEnrollments.keySet()) {
System.out.println("Student: " + userName);
ArrayList<String> courses = studentEnrollments.get(userName);
String courseMessage = sb.toString();
System.out.println(StringUtils.join(courses, ", ");
}
Use string.replaceAll(", $", ""), as follows:
for (String userName : studentEnrollments.keySet()) {
System.out.println("Student: " + userName);
ArrayList<String> courses = studentEnrollments.get(userName);
String courseMessage = "Courses: ";
for (String singleCourse : courses) {
courseMessage += singleCourse + ", ";
}
System.out.println(courseMessage.replaceAll(", $", ""));
}

How do I find a specific string on a bigger string?

I am trying to get rid of multiple specific strings. For instance, I have a string that prints:
1.jedi
2.sith
3.sith
4.sith
5.bounty hunter
6.jedi
7.sith
8.robot
My goal is to remove duplicates so that it prints:
jedi
sith
bounty hunter
robot
If I change one of the jedi to "something jedi.", it will not print "something jedi."
Output should be:
1.jedi
2.sith
3.bounty hunter
4.robot
5.something jedi
Right now I am using this code to achieve the task of removing duplicates.
if (department.contains(departmentList.get(empName))){
}
else{
department += j + ": " + departmentList.get(empName) + "\n";
j++;
}
I understand where the mistake is. Since I am using .contains(VARIABLE), when it checks "something jedi" it will find that the word JEDI is already there. therefore it returns true and it won't add it to the department.
Create a set to contain the full names of the departments already output. Each time you want to output a department, check if the set contains it already. If not, then output the department name and add it to the set.
For example:
Set<String> usedDepartments = new HashSet<String>();
Then in your loop:
if(!usedDepartments.contains(departmentList.get(empName))) {
department += j + ": " + departmentList.get(empName) + "\n";
j++;
usedDepartments.add(departmentList.get(empName));
}
As your department's value:
department += j + ": " + departmentList.get(empName) + "\n";
You may change your IF statement:
if (department.contains(": " + departmentList.get(empName) + "\n"))
SUPPOSE:
department = "1: something jedi.\n";
departmentList.get(empName) = "jedi.";
department.contains(": " + departmentList.get(empName) + "\n"); // will return false
Firstly, split your String into Link.
Secondly, make a Set from it, so it will delete all the repetitions.
department should be a Set<String>, not a String:
Set<String> departments = new HashSet<String>();
then every loop:
departments.add(departmentList.get(empName));
and after the loop:
int i = 0;
String output = "";
for (String s : departments)
output += i + ": " + s + "\n";

How to only add something to a string if it doesn't contain it?

I am making a Lipogram program where any words with the banned letter are printed, however, the words are sometimes printed twice. How do I get it to not repeat the words?
Here is my code:
public String allWordsWith(char letter) {
String str = "";
String word = "";
s = s.replace(".", " ");
s = s.replace(",", " ");
s = s.replace("?", " ");
s = s.replace("!", " ");
s = " " + s + " ";
for (int i = 0; i <= s.lastIndexOf(letter); i++) {
if (s.charAt(i) == letter) {
if (str.contains(s.substring(s.lastIndexOf(" ", i), s.lastIndexOf(" ", i) + 1) + '\n') == true) {
} else {
word += s.substring(s.lastIndexOf(" ", i), s.indexOf(" ", i)) + '\n';
str += word;
}
}
}
return str;
}
Important clarification: Is the function run with the letter chosen as "o" on the string "hello hi hello howdy" meant to return "hello hello howdy" or "hello howdy". I.e., if the word appears twice, do you want to print it twice, or do you only want to print it once regardless of repetition?
If only once regardless of repetition, then you should be using a Set to store your data.
However, I think there's a chance you're instead dealing with an issue that when running the function with the letter chosen as "l" on that same string, "hello hi hello howdy", you are getting an output of "hello hello hello hello". Correct?
The issue here is that you are checking every letter and not testing each word. To fix this, I would use:
String[] words = s.split(" ");
to create an array of your words. Test each value in that array to see if it contains the given letter using:
if(words[index].contains(letter)){
str += " " + words[index];
}

Swapping the position of elements within an array in java?

Ok, so it's the first time I am posting out here, so bear with me.
I have a name in the format of "Smith, Bob I" and I need to switch this string around to read "Bob I. Smith". Any ideas on how to go about doing this?
This is one way that I've tried, and while it does get the job done, It looks pretty sloppy.
public static void main(String[] args) {
String s = "Smith, Bob I.", r = "";
String[] names;
for(int i =0; i < s.length(); i++){
if(s.indexOf(',') != -1){
if(s.charAt(i) != ',')
r += s.charAt(i);
}
}
names = r.split(" ");
for(int i = 0; i < names.length; i++){
}
System.out.println(names[1] +" " + names[2] + " " + names[0]);
}
If the name is always <last name>, <firstname>, try this:
String name = "Smith, Bob I.".replaceAll( "(.*),\\s+(.*)", "$2 $1" );
This will collect Smith into group 1 and Bob I. into group 2, which then are accessed as $1 and $2 in the replacement string. Due to the (.*) groups in the expression the entire string matches and will be replaced completely by the replacement, which is just the 2 groups swapped and separated by a space character.
String[] names = "Smith, Bob I.".split("[, ]+");
System.out.println(names[1] + " " + names[2] + " " + names[0]);
final String[] s = "Smith, Bob I.".split(",");
System.out.println(String.format("%s %s", s[1].trim(), s[0]));
String s = "Smith, Bob I.";
String result = s.substring(s.indexOf(" ")).trim() + " "
+ s.substring(0, s.indexOf(","));

Categories