I am trying to return a word in a sentence that has the most common characters with a given string.
For instance:
Given sentence:
Old man sneezed at Starbucks.
Given word:
nee
I want to return sneezed word in that sentence.
I am pretty new to Java and I am actually JS and Python developer so I got really confused with Char array, ArrayList, StringBuilder etc.
In my opinion,
I need to pass given sentence into a String array
Convert each element to char array
Convert given word to char array in the same loop
Count most occuring word and return that index
But I really don't know what array types I need to use.
Can somebody help me out with a little snippet or algorithm that can lead me the path to solution.
This is how I started but I don't feel like this is going to help me out to accomplish what I am looking for:
ArrayList<String> wordArrayList = new ArrayList<String>();
int count = 0;
for(String eachWord : sentence.split(" ")) {
wordArrayList.add(eachWord);
char[] charArray = eachWord.toCharArray();
char[] givenWord = word.toCharArray();
}
Thank you all for your time and attention.
Edit:
I wanted add another case for it to clarify what I am trying to accomplish:
Given sentence:
Up to dubs
Given word:
bus
return:
dubs
Assuming you only want to return the first occurrence, you could modify your for loop to iterate over the whole words in the sentence rather than individual chars by using str.split(), and making use of str.contains():.
class Main {
static String findWordThatMatchesSubString(String sentence, String subString) {
for (String word : sentence.split(" ")) {
if (word.contains(subString)) {
return word;
}
}
return null;
}
public static void main(String[] args) {
String sentence = "Old man sneezed at Starbucks.";
String subString = "nee";
String foundWord = findWordThatMatchesSubString(sentence, subString);
if (foundWord != null) {
System.out.println(foundWord);
} else {
System.out.println(subString + " was not found in any word.");
}
}
}
Output:
sneezed
If you do need to deal with more than one match then using an ArrayList like what you are currently doing would be appropriate:
import java.util.ArrayList;
import java.util.List;
class Main {
static List<String> findWordsThatMatchesSubString(String sentence, String subString) {
List<String> wordMatches = new ArrayList<>();
for (String word : sentence.split(" ")) {
if (word.contains(subString)) {
wordMatches.add(word);
}
}
return wordMatches.size() > 0 ? wordMatches : null;
}
public static void main(String[] args) {
String sentence = "Old man sneezed at Starbucks and dropped his knitting needle on the floor.";
String subString = "nee";
List<String> foundWords = findWordsThatMatchesSubString(sentence, subString);
if (foundWords != null) {
System.out.println(foundWords);
} else {
System.out.println(subString + " was not found in any word.");
}
}
}
Output:
[sneezed, needle]
Regarding your followup question about finding the words in the sentence that have all the characters in the subString you can maintain a Map of Characters and their counts to achieve your desired your result:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
class Main {
static List<String> findWordsThatContainAllCharsInSubString(String sentence, String subString) {
List<String> wordMatches = new ArrayList<>();
for (String word : sentence.split(" ")) {
if (containsAllChars(word, subString)) {
wordMatches.add(word);
}
}
return wordMatches.size() > 0 ? wordMatches : null;
}
static boolean containsAllChars(String word, String subString) {
if (word.length() < subString.length()) {
return false;
}
Map<Character, Integer> subStringCharsMap = new HashMap<>();
for (char c : subString.toCharArray()) {
subStringCharsMap.put(c, subStringCharsMap.getOrDefault(c, 0) + 1);
}
for (char c : word.toCharArray()) {
if (subStringCharsMap.containsKey(c)) {
if (subStringCharsMap.get(c) == 1) {
subStringCharsMap.remove(c);
} else {
subStringCharsMap.put(c, subStringCharsMap.get(c) - 1);
}
}
if (subStringCharsMap.size() == 0) {
return true;
}
}
return false;
}
public static void main(String[] args) {
String sentence = "I got a new pair of shoes";
String subString = "hes";
List<String> foundWords = findWordsThatContainAllCharsInSubString(sentence, subString);
if (foundWords != null) {
System.out.println(foundWords);
} else {
System.out.println(subString + " was not found in any word.");
}
}
}
Output:
[shoes]
What you have is a good start - it should be possible to iterate over each word after splitting the sentence and then collect either the first / all words that contain the given word.
List<String> wordArrayList = new ArrayList<String>();
String givenWord = // from user
for(String eachWord : sentence.split(" ")) {
if (eachWord.contains(givenWord)) {
wordArrayList.add(eachWord)
}
}
This would then return a list of all words containing the given word. Depending on the requirements this could be changed to startsWith / endsWith etc.
Since you're new to Java I assume you haven't come across the Stream API Another interesting way of doing this:
String givenWord = // from user
List<String> wordArrayList = sentence.split(" ").stream.filter(str -> str.contains(givenWord)).collect(Collectors.toList())
You could just use the contains() method of string class. It takes one argument that is to be searched in the string object. Below code might help.
import java.util.*;
public class Sample{
public static void main(String []args){
ArrayList<String> occurences = new ArrayList<>();
String input = "Old man sneezed at Starbucks.";
String find = "nee";
for(String eachString: input.split(" ")){
if(eachString.contains(find)){
occurences.add(eachString);
}
}
System.out.println(occurences);
}
}
Related
I want to find how many words there are in a string but ignore the similar words in it.
For example the main method should return 8 insetad of 9.
I want it to be a method which takes one parameter s of type String and returns an int value. And im only allowed to use the bacics,so no HashMaps, ArrayLists, only charAt, length, or substring and using loops and if statemens are allowed.
public static void main(String[] args) {
countUniqueWords("A long long time ago, I can still remember");
public static int countUniqueWords(String str) {
char[] sentence = str.toCharArray();
boolean inWord = false;
int wordCt = 0;
for (char c : sentence) {
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
if (!inWord) {
wordCt++;
inWord = true;
}
} else {
inWord = false;
}
}
return wordCt;
}
```
Don't force yourself to limited options, and learn the Streaming API. Your question is as simple as:
public static long countUniqueWords(String str) {
var str2 = str.replaceAll("[^a-zA-Z0-9 ]", "").replaceAll(" +", " ");
return Arrays.stream(str2.split(" "))
.distinct()
.count();
}
[Optional step] Get get rid of all non alphanumeric chars
Split the string per empty slot
Remove duplicates
Add them together
To ignore same words in a string, you can use a combination of the split and distinct methods from the Java Stream API.
// Define the input string
String input = "This is a test string with some repeating words";
// Split the string into an array of words
String[] words = input.split("\\s+");
// Use the distinct method to remove duplicate words from the array
String[] distinctWords = Arrays.stream(words).distinct().toArray(String[]::new);
// Print the distinct words
System.out.println(Arrays.toString(distinctWords));
Try this:
public static int countUniqueWords(String words) {
// Add all the words to a list
List<String> array = new ArrayList<>();
Scanner in = new Scanner(words);
while (in.hasNext()) {
String s = in.next();
array.add(s);
}
// Save per word the amount of duplicates
HashMap<String, Integer> listOfWords = new HashMap<>();
Iterator<String> itr = array.iterator();
while (itr.hasNext()) {
String next = itr.next();
String prev = listOfWords.getOrDefault(next, 0);
listOfWords.put(next, prev + 1);
}
// Grab the size of all known words
return listOfWords.size();
}
public static void main(String args[]) {
int count = countUniqueWords("A long long time ago, I can still remember");
System.out.println("The number of unique words: " + count);
}
The code here only shows how many words they are, how do i ignore the words that are the same?
For example, "A long long time ago, I
can still remember", would return 8 instead of 9.
I want it to be a method which takes one parameter s of
type String and returns an int value. And im only allowed to use the bacics, so no hash keys or hash set and advance stuff.
public static int mostCommonLetter(String s){
int wordCount = 0;
boolean word = false;
int endOfLine = s.length() - 1;
for (int i = 0; i < s.length(); i++) {
if (Character.isLetter(s.charAt(i)) && i != endOfLine) {
word = true;
} else if (!Character.isLetter(s.charAt(i)) && word) {
wordCount++;
word = false;
} else if (Character.isLetter(s.charAt(i)) && i == endOfLine) {
wordCount++;
}
}
return wordCount;
}
}
How do i ignore the words that are the same?
import java.util.*;
public class MyClass {
public static void main(String args[]) {
String input = "A long long time ago, I can still remember";
String[] words = input.split(" ");
List<String> uniqueWords = new ArrayList<>();
for (String word : words) {
if (!uniqueWords.contains(word)) {
uniqueWords.add(word);
}
}
System.out.println("Number of unique words: " + uniqueWords.size());
}
}
Output: Number of unique words: 8
Basically, what you can do if you're allowed to use data structures like lists and so on, is create a list and put the words of the input sentence in the list if and only if they aren't already there.
General idea:
public int getUniqueWords(String input) {
// Split the string into words using the split() method
String[] words = input.split(" ");
// Create a Set to store the unique words
Set<String> uniqueWords = new HashSet<String>();
// Loop through the words and add them to the Set
for (String word : words) {
uniqueWords.add(word);
}
// Return unique words amount
return uniqueWords.size();
}
Same solution using StreamAPI:
public int getUniqueWords2(String input) {
// here we can safely cast to int, because String can contain at most "max int" chars
return (int) Arrays.stream(input.split(" ")).distinct().count();
}
If it is needed to handle multiple spaces between words, add some cleanup for input:
// remove leading and trailing spaces
cleanInput = input.trim();
// replace multiple spaces with a single space
cleanInput = cleanInput.replaceAll("\\s+", " ");
Considering the requirement "allowed to use the bacics":
hashtable (HashSet) is a basic data structure in algorithms
problem of counting unique items cannot be logically solved without a container holding "aready seen" items, so algorithm could check whether the next item is counted or not
in the role of container in the simplest case could be a list, but that would cause O(n^2) time complexity.
You can use a Set<T> collection type, that can only contains unique values:
public static int getTotalUniqueWords(String input) {
String[] words = input.split(" ");
Set<String> uniqueWords = new HashSet<>();
Collections.addAll(uniqueWords, words);
return uniqueWords.size();
}
or with Streams:
public static long getTotalUniqueWordsStream(String input) {
String[] words = input.split(" ");
return Arrays.stream(words).distinct().count();
}
I'd like to reverse a string word by word except the last letter of each word.
For example: "Hello how are you" -> lleHo ohw rae oyu
but I am getting output as: olleH woh era uoy
I'm not able to fix the last letter of each word.
This is my Java code for the above output:
public class Main
{
public static void main(String[] args) {
String s = "Hello how are you ";
char [] ch = s.toCharArray();
System.out.println(ch.length);
int pos=0;
for(int i=0;i<ch.length;i++)
{
if(ch[i]==' ')
{
for(int j=i;j>=pos;j--)
{
System.out.print(ch[j]);
}
pos=i+1;
}
}
}
}
Below is the solution to solve the problem:
public class Main {
public static void main(String[] args) {
//call the reverseSentence Method
reverseSentence("Hello how are you");
}
public static void reverseSentence(String sentence) {
//Replacing multiple space with a single space
sentence = sentence.replaceAll("[ ]{2,}", " ");
//Split the array and store in an array
String [] arr = sentence.split(" ");
StringBuilder finalString = new StringBuilder();
//Iterate through the array using forEach loop
for(String str : arr) {
//Creating substring of the word, leaving the last letter
String s = str.substring(0, str.length() - 1);
//Creating StringBuilder object and reversing the String
StringBuilder sb = new StringBuilder(s);
//Reversing the string and adding the last letter of the work again.
s = sb.reverse().toString() + str.charAt(str.length() - 1);
//Merging it with the final result
finalString.append(s).append(" ");
}
//Printing the final result
System.out.println(finalString.toString().trim());
}
}
What I have done is, firstly split all the words on spaces and store it inside an array. Now iterate through the array and get the substring from each word leaving the last letter of each word. And then I am using StringBuilder to reverse the String. Once that is done I am adding the last letter of the word to the reversed string and merging it with the finalString which is created.
I'd use regex replaceAll with a lambda to handle the reversal. \S+ matches any sequence of non-space characters. This has the advantage of elegantly handling arbitrary whitespace. You could use \w+ if you want to avoid reversing punctuation characters, although matching words like "isn't" and so forth suggests the problem devolves into natural language processing. I assume your specification is not so complex, though.
import java.util.regex.Pattern;
class Main {
public static void main(String[] args) {
String res = Pattern
.compile("\\S+")
.matcher("Hello how are you")
.replaceAll(m -> {
String s = m.group();
return new StringBuilder(s.substring(0, s.length() - 1))
.reverse().toString() + s.charAt(s.length() - 1);
});
System.out.println(res); // => lleHo ohw rae oyu
}
}
How do you think of this solution?
public class Main
{
public static void main(String[] args) {
String s = "Hello how are you ";
char [] ch = s.toCharArray();
System.out.println(ch.length);
int pos=0;
for(int i=0;i<ch.length;i++)
{
if(ch[i]==' ')
{
System.out.print(ch[i]);
for(int j=i-2;j>=pos;j--)
{
System.out.print(ch[j]);
}
System.out.print(ch[i-1]);
pos=i+1;
}
}
}
}
public class Main {
public static void main(String[] args) {
String s = "Hello how are you ";
final List<String> list = Arrays.asList(s.split(" "));
StringBuilder builder = new StringBuilder();
list.forEach(item ->{
StringBuilder itemBuilder = new StringBuilder(item);
final String rStr = itemBuilder.reverse().toString();
builder.append(rStr.substring(1,rStr.length())).append(rStr.substring(0,1)).append(" ");
});
System.out.println(builder.toString());
}
}
FP style:
String str = "Hello how are you";
String res = Arrays.stream(str.split(" "))
.map(s ->
new StringBuilder(s.substring(0, s.length() - 1)).reverse().toString() + s.substring(s.length() - 1)
)
.reduce((s, s1) -> s + " " + s1)
.orElse("");
System.out.println(res); // lleHo ohw rae oyu
A simpler solution would be to just use the Java Stack data structure for each word (after a string.split) and just add each letter (except token.length-1).
public static void main(String[] args) {
String string = "Hello how are you ";
final String[] tokens = string.split(" ");
for (String token : tokens) {
final Stack<Character> stack = new Stack<Character>();
for (int i = 0; i < token.length()-1; i++) {
stack.push(token.charAt(i));
}
while (!stack.empty()) {
System.out.print(stack.pop());
}
System.out.print(token.charAt(token.length()-1) + " ");
}
}
I have these two methods, one "findFour" finds the index of all the "bad words" in a given string. It puts the index of the located bad words into an arrayList and returns it. The next method "replaceFour" will find those same bad words in the same given string, and then replace those words with some symbol like "$$$$" and return the String. For example, if my input String was "Oh dang that's crap", then the findFour method would return an arrayList with [3, 13] (which is the index of the two "bad" words), then the replaceFour method would return "Oh $$$$ that's $$$$" I am trying to figure out how to basically make the replaceFour method.
public ArrayList<Integer> findFour(String text){
for(int i=0; i<text.length()-4;i++){
String fourLetter = text.substring(i, i+4);
FourWords.add(fourLetter);
if(fourLetter.equals(BadWords.get(0)) || fourLetter.equals(BadWords.get(1)) || fourLetter.equals(BadWords.get(2))){
IndexofBad.add(i);
}
}
return IndexofBad; //this arrayList contains index of all the bad words in the given string
}
//have to replace the bad words with a different text
public void replaceFour(String text){//Have not figured out
newString.equals(text);
for(int i=0; i<IndexofBad.size(); i++){
}
}
use String.replace (Oracle doc)
You can do it using basic String manipulation, like using indexOf() and substring() methods.
String s = "Oh crap that sucks";
List<Integer> badWordIndices = List.of(3, 13);
for (Integer i : badWordIndices) {
int indexOfNextSpace = s.indexOf(" ", i);
s = s.substring(0, i) + "$$$$" + (indexOfNextSpace != -1 ? s.substring(indexOfNextSpace) : "");
}
System.out.println(s);
Output
Oh $$$$ that $$$$
Try this solution with List..
static List<String> badWords = null;
public static String replaceBadWords(String s) {
List<String> lsStr = Arrays.asList(s.split(" "));
List<String> result = new ArrayList<String>();
for(String sr: lsStr) {
if(badWords.contains(sr)) {
sr = "$$$";
}
result.add(sr);
}
return String.join(" ", result);
}
public static void main(String[] args) {
badWords = new ArrayList<>();
badWords.add("crap");
badWords.add("dang");
System.out.println(replaceBadWords("Oh dang that's crap"));
}
How Would we write a program using Java to read a paragraph from the user and replace specific words mentioned in a vector to the following format, i.e.,
For example word Happy is reduced to H****.
Any Help will be Appriciated.
import java.io.*;
import java.util.*;
class replaceString {
public static String putStars(String str) {
char first_char = str.charAt(0);
String ans = new String();
ans = String.valueOf(first_char);
for(int i = 1;i < str.length(); ++i ) {
ans = ans + "*";
}
return ans;
}
public static String replaceWords(String str, Vector<String> v1) {
String[] words = str.split("\\W+"); //split across all types of punctuation
String ansString = new String();
for(String to_be_replaced : words) {
boolean found = false;
for(String to_replace_with : v1) {
if(to_be_replaced.equals(to_replace_with)) {
//System.out.println("in");
ansString = ansString +putStars(to_be_replaced) + " ";
found = true;
}
}
if(found == false) {
ansString = ansString + to_be_replaced + " ";
}
}
return ansString;
}
public static String replaceWords1(String str, Vector<String> v1) {
for(String currStr : v1) {
str.replace(str, );
}
return ansString;
}
public static void main(String args[])throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the paragraph that you would like to edit ");
String s = br.readLine();
// Let us assume some strings in our very own vector
Vector<String> v1 = new Vector<String>();
v1.addElement("Hello");
v1.addElement("Hi");
v1.addElement("Heya");
v1.addElement("Howdy");
v1.addElement("Howu");
String ans = replaceWords(s, v1);
System.out.println("Paragraph after replacement becomes\n\n"+ ans);
}
}
this is my current code but its not working fine
There could be other possibilities, but here's an example I did based on this answer:
We need all the words we need / want to match, and store them in an array:
String [] words = {"appy", "eya", "dy"};
(Optional) If you really need a Vector, I suggest to create a List (ArrayList) instead, and we can do it this way:
List <String> wordsToReplace = Arrays.asList(words);
Otherwise just modify the method in the next step to receive an array...
We create a function that receives this List and the phrase we want to check for and that returns the new String with the replaced text in it
So, our whole code ends up like this:
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WordReplacer {
public static void main(String[] args) {
String [] words = {"appy", "eya", "dy"};
List <String> wordsToReplace = Arrays.asList(words);
System.out.println(replaceWords("Happy", wordsToReplace));
System.out.println(replaceWords("Heya", wordsToReplace));
System.out.println(replaceWords("Howdy?", wordsToReplace));
System.out.println(replaceWords("Howdy? My friend lives in Pompeya and every time I see her I say \"Heya\" to her, she is very happy", wordsToReplace));
}
private static String replaceWords(String word, List <String> wordsToReplace) {
for (String s : wordsToReplace) {
Pattern p = Pattern.compile(s, Pattern.CASE_INSENSITIVE); //We create a pattern that matches each word in our list. (1)
Matcher m = p.matcher(word); //We actually check for each match against our phrase
StringBuilder sb = new StringBuilder();
if (m.find()) { //If there was a match, we're going to replace each character for an '*' (2)
for (int i = 0; i < s.length(); i++) {
sb.append("*");
}
}
word = m.replaceAll(sb.toString()); //We replace each match with '*' (3)
}
return word; //We return the modified word
}
}
I'm going to explain what each comment (1), (2), (3) do in a better and simpler way:
(1) As shown in the linked answer, they use \b regex command to match whole words, but in this case we're using it to match parts of words, not whole words, so we don't need it here...
(2) Only if we found a match we fill the StringBuilder with * characters... If we didn't do it this way, we would be getting: H* instead of H**** for the case of Happy word, this way we ensure we get the correct amount of * for every word in the List.
(3) We replace the matches for the total number of * in the StringBuilder so we get the correct output.
The program above produces the following output:
H****
H***
How**?
How**? My friend lives in Pomp*** and every time I see her I say "H***" to her, she is very h****
Try something like that with a map that contains yours replacing rules :
String input; //input string
Map<String,String> mapReplace = new HashMap<String,String>();
mapReplace.put("Hello","H****");
Iterator<String> keys = mapReplace.keySet().iterator();
while(keys.hasNext()){
String key = keys.next();
input = input.replace(input, mapReplace.get(key));
}