Java Array matching input with array - java

I'm attempting to write a method in a class that will prompt the user to enter the name of a student. Then search the list of already existing names for a match. But I cant seem to figure out how to proceed in coding it on how to search for a valid match.
public void modifyExam(String [] names)
{
String name;
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter the name of the student whose grade you would like to modify: ");
name = scanner.nextLine();
boolean nameMatch = true;
for (int i=0; i<names.length; i++)
{
// ....
}

You should use .equals() to compare strings in Java. Example:
public void modifyExam(String [] names) {
String name;
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter the name of the student whose grade you would like to modify: ");
name = scanner.nextLine();
boolean nameMatch = false;
for (int i=0; i<names.length; i++) {
if( names[i].equals(name) ) {
// do your logic here ...
}
}
}

I would recommend that you store your students in a Map with the name as the key. Then you wouldn't have to iterate (assuming your names are unique).
Map<String, Student> students = new HashMap<String, Student>();
Student s = new Student("Joe Smoe");
students.put(s.getName(), s);
Then you can lookup the student to update like this:
Student studentToUpdate = students.get(name);
if (studentToUpdate != null) {
// logic here...
}
Note Returns null if this map contains no mapping for the key. So you would want to add a null check before using the return value of the get call and deal with it accordingly.

Equalities.
if(name.equals(name[i]))
System.out.println("match at " i);

boolean nameMatch = false;
for (int i=0; i<names.length; i++) {
if(names[i].equals(name)) {
namesMatch = true;
break;
}
}
The break means you don't carry on searching the array as a match has been found.

I would break this function into two functions. One called findName() or even more generic findString() and the other called modifyExam. Let findString() return an index, use the index in modify exam.
Here is what findString() should do
int findString(String [] names, String name) {
for ( int i = 0; i < names.length; i++ ) {
if names[i].equals(name) return // either a boolean or an index or something.
}
return -1 // or null
}
You could also use binary search if the search array is large and already sorted. Using binarySearch() the findString method will be something like :-
int findString(String[] names, String name, int startIndex, int stopIndex) {
if ( startIndex > stopIndex) return;
int mid = (stopIndex - startIndex)/2
if ( name < names[mid] ) return findString(names, name, startIndex, mid-1);
else if ( names[mid].equals(name) ) return mid;
else return findString(names, name, mid+1, stopIndex);
}

Related

Creating an else condition in a loop if string does not exist in an array

The output i need
enter name: john
name not found in array
Here is my pseudocode
//ask for name
System.out.print("enter name")
name = sc.nextLine()
//loop to check if name exists in my array
for (int count = 0; count < arrayofnames.length; count++)
{
if (name.equals(arrayofnames[count]))
{ code to be executed if name is found in arrayofnames }
}
I tried putting an else/else if condition after the if but it executes the code arrayofnames.length times. How do I only make it print something like "name not found in array" only once then break?
You can have a flag, which you can test after the loop
System.out.print("enter name")
name = sc.nextLine()
boolean found = false;
for (int count = 0; count < arrayofnames.length; count++)
{
if (name.equals(arrayofnames[count]))
{
found = true;
break;
}
}
if (!found) System.out.println ("Not found");
public static void main(String[] args) {
String name = "jhn";
String[] arrayofnames = {"john", "tomer", "roy", "natalie"};
IsName(name, arrayofnames);
}
public static void IsName(String _name, String[] _arrayofnames){
boolean a = false;
for (String name : _arrayofnames) {
if(name == _name){
System.out.println("name is in the array");
a = true;
}
}
if(!a){
System.out.println("name is not in the array");
}
}
You can solve this problem by putting your String[] arrayOfNames into an ArrayList<> and simply checking if the ArrayList<> contains the name given by the user.
String[] arrayOfNames = {"Angelo", "David", "John"};
String name = "Angelo"; //the name given by the user
ArrayList<String> newArray = new ArrayList<>(Arrays.asList(arrayOfNames));
//check too see if the ArrayList contains the name
if (newArray.contains(name))
System.out.println("Name found in array");
else
System.out.println("Name not found in array");
If you want your code more compact, you can also use Streams to check if any element of the array equals the given String like this:
boolean found = Arrays.stream(arrayofnames).anyMatch(n -> n.equals(name));
if(found) {
//code to be executed if name is found in arrayofnames
}

How to return to index number

I am trying to write a program where the user can write their grocery item list, and then they can search whether they have wrote that item on the list or not. When they find if they have wrote down the item name it's suppose to return the index number and if they haven't wrote down the item name it's suppose to return -1. So far my code is able to find out if they have wrote down the item or not in Boolean expression.
import java.util.Scanner;
import java.util.Arrays;
public class GroceryStoreTest {
// for the search item we need to create a method.
I wrote down a boolean method for the search item.
public static boolean contains(String [] arr, String targetItem){
for(String find : arr){
if(targetItem.equals(find))
return true;
} return false ;
}
public static void main(String[] args) {
//lets create an array of string and add items list
int list;
Scanner input = new Scanner(System.in);
System.out.print("How many items would you like to add to the list: ");
list = input.nextInt();
String[] items = new String[list];
System.out.print("Write down the name of item without any space.\n(i.e.; Green Paper = GreenPaper)\n\nItems list: \n");
int i;
for (i = 0; i < list; i++) {
System.out.printf((i+1 ) + ".");
items[i] = input.next();// asks for next item name
}
// search in the items list
String search = " ";
System.out.print("Enter the name of the item to check if you have listed: " + search);
search = input.next();
//System.out.print(contains(items, String.valueOf(input)));
System.out.print(contains(items, search));
input.close();// it will stop taking the input
}
}
The other answers are correct, but there is another perspective: you should understand the difference between the for-each and the "counting-for" loops.
You got:
public static boolean contains(String [] arr, String targetItem){
for(String find : arr){
if(targetItem.equals(find))
return true;
}
return false ;
}
Which is already pretty good. ( Maybe expect for the subtle thing that I would advise you to always put blocks in { braces }; as it is far too easy to get things wrong in order to save that little bit of typing. )
But in general, that code is OK. One should actually prefer this style of looping. Because that construct really improves readability by making you "read less".
But in your case: you need that index. So the for-each loop doesn't give you what you need. Thus - this is a case where an old school counter loop is better:
for (int i=0; i<arr.length;i++) {
... and now i is the index you are looking for; thus the value to return
or -1 in the end if nothing matched
Why not just change your contains method to return an int instead?
public static int indexOf(String [] arr, String targetItem){
for(int i = 0 ; i < arr.length ; i++) {
if(targetItem.equals(arr[i]))
return i;
}
return -1 ;
}
Alternatively, you don't need to create your own indexOf method, you can just call Arrays.asList(items).indexOf("valueSearch") to get the index.
Another way to do this is to use an array list instead of an array. An ArrayList is basically an array without a fixed length. Your code will look like this:
Scanner input = new Scanner(System.in);
ArrayList<String> items = new ArrayList<>();
System.out.print("Write down the name of item without any space.\n(i.e.; Green Paper = GreenPaper)\n\nWrite "END" to finish entering items\n\nItems list: \n");
while(true) {
String item = input.next();
if (item.equals("END")) {
break;
}
items.add(item);
}
// search in the items list
String search = " ";
System.out.print("Enter the name of the item to check if you have listed: " + search);
search = input.next();
System.out.print(items.indexOf(search));
input.close();// it will stop taking the input
Here is an example of how to remove all occurences of something from an array list:
ArrayList<String> a = new ArrayList<>();
a.add("Hello");
a.add("Hello");
while (a.contains("Hello")) {
a.remove("Hello");
}
through a cycle, comparing the values with the value adding looking toLoweCase method to avoid problems with case sensitive
for(int i = 0 ; i < items.length ; i++) {
if(targetItem.toLowerCase().equals(items[i].toLowerCase()))
System.out.println("Index " + i);
}
or using the ArrayList class can be done as follows
System.out.println(Arrays.asList(items).indexOf("valueSearch"));

How to count the number of times a string appears in an array without using maps?

I am trying to count the number of times a string appears in an array, but I cannot use any type of Map. From my research, I tried the following expecting it to work:
int count = Collections.frequency(strings, search);
However, when I got an error when running the program. The error was a Null Pointer Exception error and I'm not sure how to fix that or why it happened. Any ideas on whats wrong with my code?
EDIT: Here's my full code. I can't find where the issue lies. Maybe someone else can find it
import java.util.*;
public class Lab9 {
public static void main(String[] args){
Scanner kb = new Scanner (System.in);
String name = null;
List<String> strings =null;
System.out.println("How many strings do you want to enter?:");
int size = kb.nextInt();
List<String> String = getStrings(size,name);
System.out.println(String);
System.out.println("What string would you like to search for?:");
String search = kb.next();
int numofTimes = countValues (search,strings);
System.out.print("That word appears "+numofTimes+" times in the array.");
}
public static List<String> getStrings(int size,String name) {
Scanner kb = new Scanner (System.in);
int count = 0;
List<String> strings = new ArrayList<String>();
while (count != size) {
System.out.println("Enter a string:");
name = kb.nextLine();
strings.add(name);
count = count + 1;
}
return strings;
}
public static int countValues (String search, List<String> strings){
int count = Collections.frequency(strings , search);
return count;
}
}
You can do a linear search through the array
String strings[] = {"A","B",null,"C","A",null}; // the array contains nulls
String search = "A";
int count = 0;
for (int i = 0;i< strings.length ;i++ )
{
if(strings[i] != null)
{
if(strings[i].equals(search))
{
count++;
}
}
}
System.out.println(count);
Check out http://www.tutorialspoint.com/java/util/collections_frequency.htm
There's a good example of the use of frequency(Collection c, Object o);
The nullpointerexception can occur if one of the values in your collection is null. Are you sure that the excpetion is at the line of your frequency?
Do a null and size check on strings before using it:
if (strings != null && strings.size() > 0) {
int count = Collections.frequency(strings, search);
}
If size() returns a number larger than 0 that means your strings has something in it and you can perform frequency() on it.
This is the code for Collections.frequency():
public static int frequency(Collection<?> c, Object o) {
int result = 0;
if (o == null) {
for (Object e : c)
if (e == null)
result++;
} else {
for (Object e : c)
if (o.equals(e))
result++;
}
return result;
}
As you can see, it is able to deal with o == null and with c containing null elements. The only case it will throw a NullPointerException is when c == null.
Also, from the documentation:
frequency
public static int frequency(Collection c, Object o)
Throws:
NullPointerException - if c is null

Program does nothing when run?

I wrote this program and have all the code that it should need. At first I was having some run-time errors, but I easily fixed those. Now it shows no visible errors, and when I run it, it does nothing.
In essence, what it should be doing is printing out a list of classes with students and id numbers, which have been merged from two files. It matches the ids of students to the ids of classes and forms them into a list. This all seems to be happening, it just isn't printing it out.
My code is below. Please let me know what you think. I have included a description at the top and markers of where I think the issue starts and ends. Also after the code there is an example of the contents of the two files.
/* This program reads in two files, one which contains a list of student names and id numbers, and another which lists class id numbers.
* Then, the data is taken into arrays which are then used in different sorts. One sorts the id numbers numerically, one sorts the students
* alphabetically, and one sorts the class names alphabetically.The id numbers of students are matched to class and both are compiled into
* a list which then prints out first the class name, then the list of students within it. All done alphabetically.
*
*/
import java.io.*;
import java.util.Scanner;
public class MergingFiles {
public static void main(String[] args) throws IOException {
String[][] studentArray = new String [1000][2];
String[][] classArray = new String[4000][2];
int count = 0;
Scanner sc = new Scanner(new File("students.txt"));
while(sc.hasNextLine()){
String studentInput = sc.nextLine();
String name = studentInput.substring(0, 30).trim();
String id = studentInput.substring(30).trim();
studentArray[count][0] = name;
studentArray[count][1] = id;
count++;
}
for(int i = 0; i < count-1; i++){ //sorts id number numerically
for(int j = 0; j < count-1-i; j++){
if(studentArray[j][1].compareTo(studentArray[j+1][1]) > 0){
String holder = studentArray[j][1];
studentArray[j][1] = studentArray[j+1][1];
studentArray[j+1][1] = holder;
}
}
}
int counter3 = 0;
Scanner sc2 = new Scanner(new File("classes.txt"));
while(sc2.hasNextLine()){
int counter2 = 0;
String classInput = sc2.nextLine();
while(classInput.charAt(counter2)!= ' '){
counter2++;
}
String className = classInput.substring(0, counter2);
while(classInput.charAt(counter2) == ' '){
counter2++;
}
String idNum = classInput.substring(counter2);
int low = 0;
int high = count - 1;
int mid = (high - low)/2 + low;
while(!idNum.equals(studentArray[mid][1])){ //binary search
if(idNum.compareTo(studentArray[mid][1]) < 0){
high = mid - 1;
}else
low = mid + 1;
mid = (high - low)/2 + low;
}
String studentName2 = studentArray[mid][1];
classArray[counter3][0] = className;
classArray[counter2][1] = studentName2;
}
//I THINK THE ISSUE STARTS HERE
for(int a = 0; a < (counter3 - 1); a++){ //sort class names alphabetically
for(int b = 0; b < counter3-1-a; b++){
if(classArray[b][0].compareTo(classArray[b+1][0]) > 0){
String holder2 = classArray[b][0];
classArray[b][0] = classArray[b+1][0];
classArray[b+1][0] = holder2;
}
}
}
for(int c = 0; c < (counter3 - 1); c++){ //sort class names alphabetically
for(int d = 0; d < counter3-1-c; d++){
if((classArray[d][0].compareTo(classArray[d+1][0])) == 0){
if(classArray[d][1].compareTo(classArray[d+1][1]) > 0){
String holder3 = classArray[d][1];
classArray[d][1] = classArray[d+1][1];
classArray[d+1][1] = holder3;
}
}
}
}
String currentClass = "";
for(int s = 0; s < counter3; s++){
if(!classArray[s][0].equals(currentClass)){
currentClass = classArray[s][0];
System.out.print(currentClass);
}
System.out.print(classArray[s][1]);
}
//THIS IS WHERE THE ISSUE ENDS
}
}
studentArray contents example (without //'s):
//Lambert, Desmond 451825335
//Johnston, Michaela 143547061
//Wells, Shirley 942366473
// Blevins, Dawson 407183976
// Roy, Benjamin 575069268
// Mitchell, Jaquan 285633099
// Freeman, Nayeli 312234364
// Benson, Myles 755491358
// Wilkinson, Stephany 384506082
// Bradshaw, Nikki 159900631
// Davila, Sarah 788743448
// Wyatt, Eddie 253830483
// Ortega, Josh 891761169
// Pruitt, Deven 533987743
// Harrison, Aliyah 710258372
// Perez, Emerson 611325979
// Stanton, Sonny 430095944
// Rice, Bruce 301915859
// Callahan, Brandon 327995163
// Torres, Jovan 629852538
// Mathis, Timothy 936191071
// Calhoun, Nathanael 107519769
// Mullen, Malik 711847273
// Sims, Marvin 519717164
// Pham, Siena 530779316
// Vincent, Demetrius 618276821
etc.
classArray contents example (without //'s):
//ECON101 938597595
//BUS100 951008337
//ECON408 620903271
//PHY101 695451867
//COSC150 392023624
//MATH215 557048539
//COSC325 495522117
//BUS215 185642398
//ECON408 807662685
//MATH215 920062540
//MATH325 517786537
//PHY150 915173832
//BUS100 518392974
//BUS408 410797598
//BUS215 152414047
//PHY150 561839967
etc.
Thanks.
I think you should add tokens in the txt file and using StringTokenizer have the columns captured per row in the arrays. Once you have all the data in the array, then you should be process the data to merge.
When you are saying "The id numbers of students are matched to class and both are compiled into a list which then prints out first the class name, then the list of students within it. All done alphabetically."
Are you intend to match the id in the student file with class file? if so, the above example values does not show it though.
Also if you have the student and classtxt files, share those and I can try running with them.
Basic problem is,counter3 is never set to anything besides 0, so the body of your print loop never executes. You probably want to increment counter3 here, and also use it as the index into classArray for both of these assignment statements (I think you're mistakenly using counter2 to set the student name):
classArray[counter3][0] = className;
classArray[counter2][1] = studentName2;
counter3++;
By the way, your sorting is broken because you're sorting the student ids without also sorting their names - make sure to shuffle the whole Student[] (studentArray[i]) forward instead of only studentArray[i][1]. Here's a working example using Arrays.sort(T[] a, Comparator<? super T> c):
// sort students by id number and sort null elements to end of array
Arrays.sort(studentArray, new Comparator<String[]>() {
public int compare(String[] student1, String[] student2)
{
if (student1[1] == null) return 1;
if (student2[1] == null) return -1;
return student1[1].compareTo(student2[1]);
}
});

variable type question java

So here is my problem im trying to search an array for a value and then return the index as well as the string name.
But my problem is that when i return the index it sets it as a string because thats what the method called for so when i try to type cast the index to be changed to a string my compiler throws errors. Here are the trouble some methods, i can post my whole code if you guys would like to see it.
public static String studentGrade(Scanner stdIn)
{
System.out.print("What student do you want to enter a grade for?");
String searchName=stdIn.next();
String index = findStudent(students, searchName);
int studentId =(int) currentStudentId(students, searchName);
if (index == searchName)
{
System.out.println("Student was found, " + index + studentId);
System.out.println("What is the grade that you want to input for this student?");
String input = stdIn.next();
String studentGrade = input;
return studentGrade;
}
else
{
System.out.println("not found");
}
}
public static String findStudent(String[] students, String searchName)
{
for (int i = 0; i < students.length; i++)
{
if (students[i].equals(searchName))
{
String currentStudentId = i;
return currentStudentId;
return searchName;
}
} // end for
String fail = "fail";
return fail;
} // end findStudent
I don't believe returning both String and index as int is a good idea. Why don't you just return index and get the student by looking up in array that contains all students.
If the student wasn't found you can return for example -1.
This is what I mean:
String[] students = new String[] { ... };
//...
int indexFound = findStudent(students, "John Doe");
if (indexFound >= 0) {
String studentFound = students[indexFound];
}
PS. Your code contains errors (like doubled return command)
Why would you want to return searchName from findStudent() to a method that passes it through an argument.
Of course the caller method already has the value. Just return the index:
Example:
public static int findStudent(String[] students, String searchName)
{
for (int i = 0; i < students.length; i++)
{
if (students[i].equals(searchName))
{
return i;
}
} // end for
int fail = -1;
return fail;
} // end findStudent
An index is naturally an int, not a String. You should return an int.
Assuming this is homework, and you have to return a String, you can convert a number into a String using the following.
return ""+currentStudentId;
However, the problem you have is that you are trying to return two values.
I suspect you have mis-understood the requirements, I suggest you read them again.
A shorter example, using varargs
public static int findString(String string, String... strings) {
for (int i = 0; i < strings.length; i++)
if (strings[i].equals(string))
return i;
return -1; // for not found.
}
Or even the following works for any type.
public static <T> int indexOf(T t, T... ts) {
for (int i = 0; i < ts.length; i++)
if (ts[i].equals(t))
return i;
return -1; // for not found.
}
e.g.
int found = indexOf(5, 1,3,5,7); // found = 2;

Categories

Resources