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;
Related
Code logic
In order to find all subsequences of String s that are equal to String t, I made a recursive method getSub() to get all the subsequences of input string s and added it to the list. Now I loop through the list (in numDistinct method) and try to see all those subsequences in the list that matches the string t. In case there is a match count should be incremented and later returned.
BUT
Question
In the following code count never increases, which means the if condition (in numDistinct method) does not work as it was intended. Why t which is a string and list.get(i) which should also return a string doesn't seem to work with equals method?
public static int numDistinct(String s, String t) {
int count = 0;
ArrayList<String> list = new ArrayList<>();
getSub(s, list);
StdOut.println(list);
for (int i = 0; i < list.size(); i++) {
if (t.equals(list.get(i))) {
count++;
}
}
return count;
}
private static int getSub(String s, ArrayList<String> list) {
if (s.length() == 0) {
list.add(" ");
return 1;
}
int smallOutput = getSub(s.substring(1), list);
char[] cha = s.toCharArray();
for (int i = 0; i < smallOutput; i++) {
list.add(cha[0] + list.get(i));
}
return 2 * smallOutput;
}
public static void main(String[] args) {
String s = "rabbbit";
String t = "rabbit";
StdOut.println(numDistinct(s, t));
}
The way you are creating the strings in the list ensures there is a space character at the end of each string. As such, none of them are equal to t.
if (s.length() == 0) {
list.add(""); // remove the space from this line
return 1;
}
I have a .txt file which has data for states as given below:
AL,Alab,4860
AK,Alas,7415
AZ,Ariz,6908
AR,Arka,2988
I have made a function which counts how many states there are that start with the initial passed as such:
public int CInitial(char initial) {
int total = 0;
for(int i = 0; i < states.length; i++) { //states is an array which includes all states present in the .txt file
String testString = states[i].getName(); // getName gets the name of the states present in the .txt file
char[] stringToCharArray = testString.toCharArray();
for (char output : stringToCharArray) {
if(initial == output) {
total++;
}
}
}
return total;
}
This would return the number 4 if "A" is passed and 0 if any other initial is passed as there are 4 states that begin with the letter "A".
Now how can I create a new function that passes a character and returns the name of all the states that begin with that character? For Instance this is the initial return type needed for this, however I'm having troubles starting this. Is the process identical to the countStatesCountByInitial function I created?
public State[] CByInitial(char initial) {
return new State[] {}; //to be completed
}
Yes, it will be very similar to the countStatesCountByInitial. The main difference is each time you find a match, you want to add the state into the array. Since we don't know the size of the array beforehand, we may want to use a List instead.
public State[] getStatesCountByInitial(char initial) {
ArrayList<State> found = new ArrayList<>();
// this is the same as before
for(int i = 0; i < states.length; i++) {
String testString = states[i].getName();
char[] stringToCharArray = testString.toCharArray();
for (char output : stringToCharArray) {
if(initial == output) {
// except here when you find a match, you add it into the list
found.add(states[i]);
}
}
}
// return as array
return found.toArray(new State[found.size()]);
}
As suggested by Patrick, we can avoid using List by using countStatesCountByInitial to initialize the size of the states.
public State[] getStatesCountByInitial(char initial) {
int matchSize = countStatesCountByInitial(initial);
States[] found = new States[matchSize];
int foundIndex = 0;
// this is the same as before
for(int i = 0; i < states.length; i++) {
String testString = states[i].getName();
char[] stringToCharArray = testString.toCharArray();
for (char output : stringToCharArray) {
if(initial == output) {
// except here when you find a match, you add it into the array
found[foundIndex] = states[i];
foundIndex++;
}
}
}
// return the array
return found;
}
You can done both operations simply by one method.
public static ArrayList<State> getStatesCountByInitial(char initial) {
ArrayList selectedStates = new ArrayList<State>();
for(int i = 0; i < states.length; i++) {
if(states.charAt(0) == initial){
selectedStates.add(states[i]);
}
}
return selectedStates;
}
This method will return a arraylist.
If you want to get the count, call this method and get the size of the array.
ArrayList<State> statesNew = getStatesCountByInitial('A');
int count = statesNew.size();
public static int getNthOccurrence(int n, char find, String str)
{
int counter=0;
for(int i=0;i<str.length();i++)
{
if(str.charAt(i)==find)
{
counter++;
if(counter==n)
return i;
}
}
return -1;
}
I have already seen this thread Java: method to get position of a match in a String?
The code runs that:
int n=getNthOccurrence(3,'n',"you arent gonna find me");
output: 13
You can make a char into a String by simply doing this
String theString = yourChar + "";
Your code could look something like this !spoiler below!
public static int getNthOccurrence(int n, char find, String str)
{
String f = find + "";
int counter = 0;
for (String c : str.split("")){
if (c.equals(f)) n--;
if (n < 1 ) return counter;
counter++;
}
return -1;
}
}
Once you've changed the parameter type to String:
public static int getNthOccurrence(int n, String find, String str)
Use String.indexOf(String, int):
i = -find.length();
for (int count = 0; count < n; ++count) {
i = str.indexOf(find, i + find.length());
if (i < 0) break;
}
return (i >= 0) ? i : -1;
(Note that String.indexOf(char, int) is a preferable way to do it with char, as in the case of the original code).
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);
}
As the title says, I'm working on a project in which I'm searching a given text, moby dick in this case, for a key word. However instead of the word being linear, we are trying to find it via a skip distance ( instead of cat, looking for c---a---t).
I've tried multiple ways, yet can't seem to get it to actually finish one skip distance, have it not work, and call the next allowed distance (incrementing by 1 until a preset limit is reached)
The following is the current method in which this search is done, perhaps this is just something silly that I'm missing?
private int[] search()
throws IOException
{
/*
tlength is the text file length,
plength is the length of the
pattern word (cat in the original post),
text[] is a character array of the text file.
*/
int i=0, j;
int match[] = new int[2];
int skipDist = 2;
while(skipDist <= 100)
{
while(i<=tlength-(plength * skipDist))
{
j=plength-1;
while(j>=0 && pattern[j]==text[i+(j * skipDist)])j--;
if (j<0)
{
match[0] = skipDist;
match[1] = i;
return match;
}
else
{
i++;
}
}
skipDist = skipDist + 1;
}
System.out.println("There was no match!");
System.exit(0);
return match;
}
I do not know about the method you posted, but you can use this instead. I've used string and char array for this:
public boolean checkString (String s)
{
char[] check = {'c','a','t'};
int skipDistance = 2;
for(int i = 0; i< (s.length() - (skipDistance*(check.length-1))); i++)
{
boolean checkValid = true;
for(int j = 0; j<check.length; j++)
{
if(!(s.charAt(i + (j*skipDistance))==check[j]))
{
checkValid = false;
}
}
if(checkValid)
return true;
}
return false;
}
Feed the pattern to match in the char array 'check'.
String "adecrayt" evaluates true. String "cat" evaluates false.
Hope this helps.
[This part was for fixed skip distance]
+++++++++++++++++++++++++++
Now for any skip distance between 2 and 100:
public boolean checkString (String s)
{
char[] check = {'c','a','t'};
int index = 0;
int[] arr = new int[check.length];
for(int i = 0; i< (s.length()); i++)
{
if(check[index]==s.charAt(i))
{
arr[index++] = i;
}
}
boolean flag = true;
if(index==(check.length))
{
for(int i = 0; i<arr.length-1; i++)
{
int skip = arr[i+1]-arr[i];
if(!((skip>2)&&(skip<100)))
{
flag = false;
}
else
{
System.out.println("Skip Distance : "+skip);
}
}
}
else
{
flag = false;
}
return flag;
}
If you pass in a String, you only need one line:
public static String search(String s, int skipDist) {
return s.replaceAll(".*(c.{2," + skipDist + "}a.{2," + skipDist + "}t)?.*", "$1");
}
If no match found, a blank will be returned.