Here is is my problem, I have to explain a lot, because it's a quite complicated.
I have created an arrayList<Word>, that contains strings as objects. In my case, I have three classes, all working together, that is supposed to represent a dictionary.
The first class is called "Word", it has a constructor, and has simple methodes like .length, adds 1 to the counter, and keeps track of the words that are repeated.
The second class is called "Wordlist", and uses more advanced methodes like reading a file, a summary of 30,000 words. Some methodes is for instance, to add words to the arraylist, as objects. Methods like search if they can find a perticular word. Now, these tasks contains parametres, with variables that I can use.
But I came upon a task in which I had to find the longest word(string) in the arrayList, without any parameters. The method is called: public Word findLongest().
In the thrid class, I have the test case, where I use the methodes. The most central part here is to read the file, and add it to the arrayList object. In what way can I use the method to find the longest word(string) in the arrayList without any parameters?
It is very confusing with arrayList as objects.
I am aware of the for (each : array) use in this sense, but have no idea how use it properly.
If your Word class provides a length() method which simply returns the length of the word represented by that object, then you can run through your ArrayList<Word> and find the longest like this:
private Word getLongestWordFromList(List<Word> listOfWords) {
Word longestWord = null;
for (Word word : listOfWords) {
if (longestWord == null || word.length() > longestWord.length()) {
longestWord = word;
}
}
return longestWord;
}
The for (Word word : listOfWords) pattern simply says: iterate through the List called "listOfWords" and store the current Word object in a variable called "word". Then you just check the length of each word to see whether it is longer than the longest already found. (If the longestWord variable is null then it means you haven't processed any words so far, so whatever is the first Word found will go into that variable, ready to be compared with the next.)
Note: if there is more than one word with the longest length then this method will simply return the first word which is found with that length. If you need to return a list of all words having the longest length then you'll need to modify this pattern to generate a List<Word> which contains all words of the longest length.
Assuming your Word class has a method called length(), maybe something like this:
Word longest = arrayList.get(0);
for (int i=1; i<arrayList.size(); ++i) {
if (arrayList.get(i).length() > longest.length()) {
longest = arrayList.get(i);
}
}
For Java Stream enthusiasts one very declarative solution is:
private Word getLongestWordFromList(List<Word> listOfWords) {
return listOfWords.stream()
.filter(word -> word != null)
.max(Comparator.comparing(Word::length))
.orElse(null);
}
filter makes sure the stream skips over null values.
max compares the word lengths and returns an Optional<Word> with the largest length value. Note that instead of Word::length we could have also written word -> word.length().
orElse "unpacks" the optional value. If it didn't find anything (eg. because every value is null or listOfWords is empty), it returns null.
Related
I have an arraylist of type String with many words, and in some cases they are just single letters. Such as the letter "K".
I am essentially trying to remove all single instance characters, EXCEPT "A" and "I".
Here is the code/regex I was trying, to no avail:
//removing all single letters
ArrayList<String> newList2 = new ArrayList<String>();
for(String word : words) {
newList2.add(word.replace("[BCDEFGHJKLMOPQRSTUVWXYZ]", ""));
}
words = newList2;
Should I not use regex? Is there a better method, or is there a way I am not using regex correctly? From my understanding my implementation, if it even worked, would only replace it with an empty spot, not completely remove the element.. my goal is to remove the element entirely if it exists, perhaps by the .remove method... Not sure how to go about this. (JAVA)
(P.S, ideally I would also remove the "=" and other symbols if they are apparent, but characters is my gripe at the moment)
No need to use stream api for it. List#removeIf will suffice here:
list.removeIf(s -> s.length() == 1 && ! List.of("A", "I").contains(s))
Note: It is a mutative operation.
A solution with loop:
for(int i=0; i < newList2.size(); i++){
if(newList2.get(i).length() == 1){
if(!newList2.get(i).equals("A") || !newList2.get(i).equals("I")){
newList2.remove(i)
}
}
}
I'm trying to create a program that can abbreviate certain words in a string given by the user.
This is how I've laid it out so far:
Create a hashmap from a .txt file such as the following:
thanks,thx
your,yr
probably,prob
people,ppl
Take a string from the user
Split the string into words
Check the hashmap to see if that word exists as a key
Use hashmap.get() to return the key value
Replace the word with the key value returned
Return an updated string
It all works perfectly fine until I try to update the string:
public String shortenMessage( String inMessage ) {
String updatedstring = "";
String rawstring = inMessage;
String[] words = rawstring.replaceAll("[^a-zA-Z ]", "").toLowerCase().split("\\s+");
for (String word : words) {
System.out.println(word);
if (map.containsKey(word) == true) {
String x = map.get(word);
updatedstring = rawstring.replace(word, x);
}
}
System.out.println(updatedstring);
return updatedstring;
}
Input:
thanks, your, probably, people
Output:
thanks, your, probably, ppl
Does anyone know how I can update all the words in the string?
Thanks in advance
updatedstring = rawstring.replace(word, x);
This keeps replacing your updatedstring with the rawstring with a the single replacement.
You need to do something like
updatedstring = rawstring;
...
updatedString = updatedString.replace(word, x);
Edit:
That is the solution to the problem you are seeing but there are a few other problems with your code:
Your replacement won't work for things that you needed to lowercased or remove characters from. You create the words array that you iterate from altered version of your rawstring. Then you go back and try to replace the altered versions from your original rawstring where they don't exist. This will not find the words you think you are replacing.
If you are doing global replacements, you could just create a set of words instead of an array since once the word is replaced, it shouldn't come up again.
You might want to be replacing the words one at a time, because your global replacement could cause weird bugs where a word in the replacement map is a sub word of another replacement word. Instead of using String.replace, make an array/list of words, iterate the words and replace the element in the list if needed and join them. In java 8:
String.join(" ", elements);
I'm really really really not sure what is the best way to approach this. I've gotten as far as I can, but I basically want to scan a user response with an array of words and search for matches so that my AI can tell what mood someone is in based off the words they used. However, I've yet to find a clear or helpful answer. My code is pretty cluttered too because of how many different methods I've tried to use. I either need a way to compare sections of arrays to each other or portions of strings. I've found things for finding a part of an array. Like finding eggs in green eggs and ham, but I've found nothing that finds a section of an array in a section of another array.
public class MoodCompare extends Mood1 {
public static void MoodCompare(String inputMood){
int inputMoodLength = inputMood.length();
int HappyLength = Arrays.toString(Happy).length();
boolean itWorks = false;
String[] inputMoodArray = inputMood.split(" ");
if(Arrays.toString(Happy).contains(Arrays.toString(inputMoodArray)) == true)
System.out.println("Success!");
InputMood is the data the user has input that should have keywords lurking in them to their mood. Happy is an array of the class Mood1 that is being extended. This is only a small piece of the class, much less the program, but it should be all I need to make a valid comparison to complete the class.
If anyone can help me with this, you will save me hours of work. So THANK YOU!!!
Manipulating strings will be nicer when you do not use the relative primitive arrays, where you have to walk through yourself etcetera. A Dutch proverb says: not seeing the wood through the trees.
In this case it seems you check words of the input against a set of words for some mood.
Lets use java collections:
Turning an input string into a list of words:
String input = "...";
List<String> sentence = Arrays.asList(input.split("\\W+"));
sentence.remove("");
\\W+ is a sequence of one or more non-word characters. Mind "word" mean A-Za-z0-9_.
Now a mood would be a set of unique words:
Set<String> moodWords = new HashSet<>();
Collections.addAll(moodWords, "happy", "wow", "hurray", "great");
Evaluation could be:
int matches = 0;
for (String word : sentence) {
if (moodWords.contains(word)) {
++matches;
}
}
int percent = sentence.isEmpty() ? 0 : matches * 100 / sentence.size();
System.out.printf("Happiness: %d %%%n", percent);
In java 8 even compacter.
int matches = sentence.stream().filter(moodWords::contains).count();
Explanation:
The foreach-word-in-sentence takes every word. For every word it checks whether it is contained in moodWords, the set of all mood words.
The percentage is taken over the number of words in the sentence being moody. The boundary condition of an empty sentence is handled by the if-then-else expression ... ? ... : ... - an empty sentence given the arbitrary percentage 0%.
The printf format used %d for the integer, %% for the percent sign % (self-escaped) and %n for the line break character(s).
If I'm understanding your question correctly, you mean something like this?
String words[] = {"green", "eggs", "and", "ham"};
String response = "eggs or ham";
Mood mood = new Mood();
for(String foo : words)
{
if(response.contains(foo))
{
//Check if happy etc...
if(response.equals("green")
mood.sad++;
...
}
}
System.out.println("Success");
...
//CheckMood() etc... other methods.
Try to use tokens.
Every time that the program needs to compare the contents of a row from one array to the other array, just tokenize the contents in parallel and compare them.
Visit the following Java Doc page for farther reference: http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html
or even view the following web pages:
http://introcs.cs.princeton.edu/java/72regular/Tokenizer.java.html
I have a java string containing n number of characters.
How do I extract the LAST few characters from that string?
I found this piece of code online that extracts the first few, but I dont understand it so I cant modify it.
Can anyone help me with this?
String upToNCharacters = s.substring(0, Math.min(s.length(), n));
Try,
String upToNCharacters = s.substring(s.length()-lastCharNumber);
That piece of code does exactly the opposite of what you want. Now let's see why and how we can modify it.
Quick solution
You can modify the code as follows to do what you want:
String lastNchars = s.substring( Math.max(0, s.length()-n));
Explanation
According to the official documentation, Java String class has a special method called substring().
The signature of the method is the following (with overload):
public String substring(int beginIndex, int endIndex))
public String substring(int beginIndex)
The first method accepts 2 parameters as input:
beginIndex: the begin index of the substring, inclusive.
endIndex: the end index of the substring, exclusive.
The second overload will automatically consider as endIndex the length of the string, thus returning "the last part"
Both methods return a new String Object instance according to the input parameters just described.
How do you pick up the right sub-string from a string? The hint is to think at the strings as they are: an array of chars. So, if you have the string Hello world you can logically think of it as:
[H][e][l][l][o][ ][w][o][r][l][d]
[0]...............[6]......[9][10]
If you choose to extract only the string world you can thus call the substring method giving the right "array" indexes (remember the endIndex is exclusive!):
String s = "Hello world";
s.substring(6,11);
In the code snippet you provided, you give a special endIndex:
Math.min(s.length(), n);
That is exactly up to the n th char index taking into account the length of the string (to avoid out of bound conditions).
What we did at the very beginning of this answer was just calling the method and providing it with the beginning index of the substring, taking into account the possible overflow condition if you choose a wrong index.
Please note that any String Object instance can take advantage of this method, take a look at this example, for instance:
System.out.println("abc");
String cde = "cde";
System.out.println("abc" + cde);
String c = "abc".substring(2,3);
String d = cde.substring(1, 2);
As you see even "abc", of course, has the substring method!
Have a look at the substring documentation, Basically what it does is, it returns a substring of the string on which it is called, where substring from the index specified by the first parameter and the ends at the second parameter.
So, to get the last few characters, modify the begin index and the end index to the values you need. There is also another version of this method which takes only one parameter, just the begin index, which might be useful for you.
String lastNchars = s.substring(s.length()-n);
One of the String.substring() overloads takes one parameter - the index of the starting index. From that, you can easily implement your function :
String lastFew(String s, int number) {
if (number > s.length()) {
throw new IllegalArgumentException("The string is too short!");
} else return s.substring(s.length()-number);
}
Problem Description
I have list of strings, which contains 8000 items. Items which contains list are described below.
List<String> stringList = new List<String>(8000);
stringList.add("this is first string.");
stringList.add("text which I want to search.");
stringList.add("separated string items.");
....
So you can see that every item in my list is a sentence which have more then three words.
Question.
User from outside can search through the list in the following way. For example user want to search word "first" the search algorithm must work in this way.
Search algorithm must run over the list and compare word "first" with all words in the sentence and if any word in the sentence starts with "first" it must return that sentence ". So in order to realize this algorithm I write following code, you can see code below.
Algorithm which I implement works very slow, So I want to know if there is faster algorithm or how I can made my algorithm faster ?
Code Example
Iterator<ContactInformation> stringListIter = stringList .iterator();
while (stringListIter.hasNext()) {
String currItem = stringListIter.next();
String[] separatedStr = currItem.split(" ");
for(int i=0; i<separatedStr.lenght; ++i)
if(separatedStr[i].startsWith(textToFind))
retList.add(currItem);
}
You could use the String#contains method along with String#startsWithinstead of splitting your String and searching each token.
String currItem = stringListIter.next();
if(currItem.startsWith(textToFind.concat(space))){
retList.add(currItem);
} else if(currItem.endsWith(space.concat(textToFind))){
retList.add(currItem);
} else if(currItem.contains(space.concat(textToFind).concat(space))){
retList.add(currItem);
} else if(currItem.equals(textToFind)){
retList.add(currItem);
}
First if - Checks if its the first word.
Second if - Checks if its the last word.
Third if - Checks if its somewhere in the middle.
Last if - Checks if its the only word.
I would hold a Map<String, Set<Integer>> where every word is a key and the value are the indexes of the sentence that contains this word.
A task perfectly suited for Lucene.
for(String s : yourList){
if(s.contains(textToFind)){
retList.add(s);
}
}