I need to do some keywords search and print if true.
works fine if i am comparing in order. but i want to
compare the following cases and expect them to be true.
do some java programming = true
some java = true
do programming = true
and finally most importantly
programming java = true
programming java some do = true
I need to return true for all the cases mentioned above but so far it only works for case 1 and 2
public class Examples {
public static void main(String[] args) {
String[] given = new String[20];
given[0] = ("do some java programming");
given[1] = ("do some grocery shopping");
given[2] = ("play soccer at the west field");
String input = new String();
Scanner userInput = new Scanner(System.in);
System.out.println("Enter the string to compare");
input[0] = userInput.nextLine();
for (int i=0; i <20; i++){
if(given[i].contains(input))
{
System.out.println(given[i]);
}
else
{
//do nothing
}
}
}
}
Outline of one way to solve this:
Each string in given should be converted to a Set<String> that is a set of all the words in the string. Use split() on each string to get the words, then go through the list of words and add each word to the Set.
For each input string, use split() to split it into words, then create any kind of collection (a Set<String> will work, but creating a List<String> by using Arrays.asList works too.
You can then see if the collection of words from the input is a subset of the set of words in each given string by using a Set's containsAll method.
(Note that you'll have to make sure the input string isn't the empty set first. Also, if the input string has more than one occurrence of any word, this approach won't catch that, without some extra logic.)
For this Regex will be your friend.
Here's some working code to play with:
String[] matches = input[0].split(" ");
for (int i=0; i <3; i++){
for(String s: matches){
if(given[i].contains(s))
System.out.println(given[i]);
break;
}
}
}
Split the given lines and store it in a List.
Again split the input line and compare word by word.
Below is the code snippet
public class StringCompare
{
public static final String delimiter = " ";
public static void main( String[] args )
{
String[] given = new String[20];
given[ 0 ] = ( "do some java programming" );
given[ 1 ] = ( "do some grocery shopping" );
given[ 2 ] = ( "play soccer at the west field" );
List< List< String >> listLineAsWords = new ArrayList< List< String >>();
//split each line and store it as list.
for ( String line : given )
{
if ( line == null )
break;
listLineAsWords.add( Arrays.asList( line.split( delimiter ) ) );
}
//Write your own logic to get the input line
String inputLine = "programming java";
if ( compareLine( inputLine, listLineAsWords ) )
System.out.println( "The input line is part of given lines" );
}
private static boolean compareLine( String inputLine, List< List< String >> listLineAsWords )
{
if ( inputLine == null )
return false;
List< String > words = Arrays.asList( inputLine.split( delimiter ) );
for ( List< String > listOfWords : listLineAsWords )
{
boolean isPartOfLine = true;
for ( String word : words )
{
if ( !listOfWords.contains( word ) )
{
isPartOfLine = false;
break;
}
}
if(isPartOfLine)
return true;
}
return false;
}
}
Your code is almost right, yet it needs some changes
First, since in your sample code you have 3 case, it is best to define your given array length 3.
String[] given = new String[3];
Note: for more cases, you can define bigger array length; for example, if you will add other 2 cases, your array length is 5
For all reference types, the default value is null if you have array length more than you need.
read more about it here
Second, in your if statement, you want to check if input contains given element of array or not
if (input.contains(given[i])) {
code:
String[] given = new String[3];
given[0] = ("do some java programming");
given[1] = ("do some grocery shopping");
given[2] = ("play soccer at the west field");
Scanner userInput = new Scanner(System.in);
System.out.println("Enter the string to compare");
String input = userInput.nextLine();
for (int i = 0; i < given.length; i++) {
if (input.contains(given[i])) {
System.out.println(given[i]);
} else {
// System.out.println("do nothing");
}
}
output:
Modify as below assuming everything else is fine
//here initialize 'given' array
//get the user input in a string that is 'input[0]' in your case
int count = 0;
for (String s : given) {
if (s != null && s.matches(input[0])) {
//it matches and print it
} else {
//either it's not a match or the 'given' array has a null at this index
}
count++;
}
I must say, get the user input in a string. I don't understand why you have it in input array.
Related
I'm trying to get the unique words within a string then storing it within an array along with the amount of times it occurs.
My approach towards this was to assign a unique integer to each unique string within an if-else statement, then taking the unique counts of those integers, and pulling any one word from the string that's assigned a unique value, and finally taking the number of times the unique integer occurs.
However, whenever I get to assigning a unique value to the String I get null:
import java.util.Arrays;
public class StringLearning {
public static void main(String[] args) {
final String text = "Win Win Win Win Draw Draw Loss Loss";
int[] numbers = null;
if(text.equals("Win")) {
numbers= new int[1];
}else if(text.equals("Draw")){
numbers = new int [2];
}else if(text.equals("Loss")) {
numbers = new int [3];
}
System.out.println(Arrays.toString(numbers));
}
}
Expected output:
{1, 1, 1, 1, 2, 2, 3, 3}
EDIT:
How could this be implemented in a general sense? Such that, I did not know the String had "Win, Loss, Draw" in the string, but I'd want to assign a unique integer to any given unique word?
you have many problems with your code.
first, you have to get each word of the string individual, so you need to split it into array.
second, you need to create one array, and in it to put the integers. (what you did is to create new array for each number)
I tried to fix the problems. hope you understand my code.
(I only fixed your code, and not make it generial)
String[] arr = text.split(" ");
int[] numbers = new int[arr.length];
for (int i=0;i<arr.length;i++){
if(arr[i].equals("Win")) {
numbers[i] = 1;
}else if(arr[i].equals("Draw")){
numbers[i] = 2;
}else if(arr[i].equals("Loss")) {
numbers[i] = 3;
}
}
When creating an object of an array, the number in the brackets new int[1] you declare the length of the array. I'd recommend using a HashMap for that matter. An example of code would be:
public class StringLearning {
public static void main(String[] args) {
final String text = "Win Win Win Win Draw Draw Loss Loss";
HashMap<String, Integer> counts = new HashMap<String, Integer>();
for (String word : text.split(" ")) { // loops through each word of the string
// text.split(" ") returns an array, with all the parts of the string between your regexes
// if current word is not already in the map, add it to the map.
if (!counts.containsKey(word)) counts.put(word, 0);
counts.put(word, counts.get(word) + 1); // adds one to the count of the current word
}
// lambda expression
counts.forEach((string, integer) -> System.out.printf("amount of \"%s\": %d\n", string, integer));
}
}
Output:
amount of "Draw": 2
amount of "Loss": 2
amount of "Win": 4
Edit (response to tQuadrat):
I edited this post to keep everything clean and readable.
public class StringLearning {
public static void main(String[] args) {
final String text = "Win Win Win Win Draw Draw Loss Loss";
HashMap<String, Integer> counts = new HashMap<String, Integer>();
for (String word : text.split(" ")) { // loops through each word of the string
// text.split(" ") returns an array, with all the parts of the string between your regexes
// if current word is not already in the map, add it to the map.
if (!counts.containsKey(word))
counts.put(word, counts.size() + 1); // index of the word (+ 1 because your expected output was 1-indexed)
}
for (String word : text.split(" ")) {
System.out.print(counts.get(word) + " ");
}
}
}
Output:
1 1 1 1 2 2 3 3
Let's try this approach:
Get the number of words in the String: var words = text.split( " " ); This assumes that words are separated by blanks only.
Create registry for the words: Map<String,Integer> registry = new HashMap<>();
Create the result array: var result = new int [words.length];
Now loop over the words and check if you have seen the word already:
for( var i = 0; i < words.length; ++i )
{
result [i] = registry.computeIfAbsent( words [i], $ -> registry.size() + 1 );
}
Finally, print the result: System.out.println( Arrays.toString( result ) ); – although this would use […] instead of {…}.
registry.computeIfAbsent( words [i], $ -> registry.size() + 1 ); adds a new entry to the registry for each unseen word and assigns the size of the registry plus one as the unique number for that word. For already known words, it returns the previously assigned number.
This works for any set of words in text.
So the complete thing may look like this:
public final class StringLearning
{
public static final void main( final String... args )
{
final var text = "Win Win Win Win Draw Draw Loss Loss"; // … or any other text
final var words = text.split( " " );
final Map<String,Integer> registry = new HashMap<>();
final var result = new int [words.length];
for( var i = 0; i < words.length; ++i )
{
result [i] = registry.computeIfAbsent( words [i], $ -> registry.size() + 1 );
}
System.out.println( Arrays.toString( result ) );
}
}
Maintain the unique value for each word of string in map and then fetch the unique value while assigning your array.
String text = "Win Win Loss Draw Hello";
String[] split = text.split(" ");
// To maintain unique value for each word of input string
Map<String, Integer> = new HashMap<>();
int counter = 0;
for(String ele:split)
if(!map.containsKey(ele))
map.put(ele, ++counter)
// Getting unique value for each word and assigining in array
int[] array=new int[split.length];
for(int i=0; i<split.length;i++)
array[i] = map.get(split[i]);
I'm new to programming, and here I'm required to capitalise the user's input, which excludes certain words.
For example, if the input is
THIS IS A TEST I get This Is A Test
However, I want to get This is a Test format
String s = in.nextLine();
StringBuilder sb = new StringBuilder(s.length());
String wordSplit[] = s.trim().toLowerCase().split("\\s");
String[] t = {"is","but","a"};
for(int i=0;i<wordSplit.length;i++){
if(wordSplit[i].equals(t))
sb.append(wordSplit[i]).append(" ");
else
sb.append(Character.toUpperCase(wordSplit[i].charAt(0))).append(wordSplit[i].substring(1)).append(" ");
}
System.out.println(sb);
}
This is the closest I have gotten so far but I seem to be unable to exclude capitalising the specific words.
The problem is that you are comparing each word to the entire array. Java does not disallow this, but it does not really make a lot of sense. Instead, you could loop each word in the array and compare those, but that's a bit lengthy in code, and also not very fast if the array of words gets bigger.
Instead, I'd suggest creating a Set from the array and checking whether it contains the word:
String[] t = {"is","but","a"};
Set<String> t_set = new HashSet<>(Arrays.asList(t));
...
if (t_set.contains(wordSplit[i]) {
...
Your problem (as pointed out by #sleepToken) is that
if(wordSplit[i].equals(t))
is checking to see if the current word is equal to the array containing your keywords.
Instead what you want to do is to check whether the array contains a given input word, like so:
if (Arrays.asList(t).contains(wordSplit[i].toLowerCase()))
Note that there is no "case sensitive" contains() method, so it's important to convert the word in question into lower case before searching for it.
You're already doing the iteration once. Just do it again; iterate through every String in t for each String in wordSplit:
for (int i = 0; i < wordSplit.length; i++){
boolean found = false;
for (int j = 0; j < t.length; j++) {
if(wordSplit[i].equals(t[j])) {
found = true;
}
}
if (found) { /* do your stuff */ }
else { }
}
First of all right method which is checking if the word contains in array.
contains(word) {
for (int i = 0;i < arr.length;i++) {
if ( word.equals(arr[i])) {
return true;
}
}
return false;
}
And then change your condition wordSplit[i].equals(t) to contains(wordSplit[i]
You are not comparing with each word to ignore in your code in this line if(wordSplit[i].equals(t))
You can do something like this as below:
public class Sample {
public static void main(String[] args) {
String s = "THIS IS A TEST";
String[] ignore = {"is","but","a"};
List<String> toIgnoreList = Arrays.asList(ignore);
StringBuilder result = new StringBuilder();
for (String s1 : s.split(" ")) {
if(!toIgnoreList.contains(s1.toLowerCase())) {
result.append(s1.substring(0,1).toUpperCase())
.append(s1.substring(1).toLowerCase())
.append(" ");
} else {
result.append(s1.toLowerCase())
.append(" ");
}
}
System.out.println("Result: " + result);
}
}
Output is:
Result: This is a Test
To check the words to exclude java.util.ArrayList.contains() method would be a better choice.
The below expression checks if the exclude list contains the word and if not capitalises the first letter:
tlist.contains(x) ? x : (x = x.substring(0,1).toUpperCase() + x.substring(1)))
The expression is also corresponds to:
if(tlist.contains(x)) { // ?
x = x; // do nothing
} else { // :
x = x.substring(0,1).toUpperCase() + x.substring(1);
}
or:
if(!tlist.contains(x)) {
x = x.substring(0,1).toUpperCase() + x.substring(1);
}
If you're allowed to use java 8:
String s = in.nextLine();
String wordSplit[] = s.trim().toLowerCase().split("\\s");
List<String> tlist = Arrays.asList("is","but","a");
String result = Stream.of(wordSplit).map(x ->
tlist.contains(x) ? x : (x = x.substring(0,1).toUpperCase() + x.substring(1)))
.collect(Collectors.joining(" "));
System.out.println(result);
Output:
This is a Test
Question
Autocomptete
Doug was using Google and was amazed to see the autocomptete feature How autocomptete works it search the database for all the possible words that can be formed using the characters that are provided by user (as input)
For ex If a user type 'cis' in the search bar then suggestions would be
• cisco
• cist
• cissp
• cism
• cisa
He thought about applying the same feature in his search engine. In his prototype he took a string as domain which contained all the words he could search.
As his designer you have to tell him how many autocomptete options will be provided to him if something is entered in the input field.
This is my code for the following problem.
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
String input1 = "Hello world with warm welcome from Mr.kajezevu";
String input2 = "w";
//output should be any word starting with w i.e {world,warm,welcome}
List < String > l = new ArrayList < String > ();
String[] str = input1.split("\\s+");//splits a given string at spaces
for (int i = 0; i < str.length; i++) {
if (str[i].length() >= input2.length()) { // checks if the length of input2 is not greater than the str[i] selected
if (input2.equals(str[i].substring(0, input2.length()))) { //comparing the two string if they are equal
l.add(str[i]);
}
}
}
String[] result = l.toArray(new String[l.size()]);
for (int i = 0; i < result.length; i++) {
System.out.println(result[i]);
}
}
}
But my solution is passing only one test case and also its failing complexity case.
i can't figure out whats wrong with it.
It seems you missed boundary conditions.
Below is code.
public static String[] autoComplete(String input1, String input2){
List<String> listOfPredictions = new ArrayList<String>();
String[] emptyArr = new String[0];
if(isEmpty(input1) || isEmpty(input2)){
return emptyArr;
}
input1 = input1.trim();
input2 = input2.trim();
String tokenizer = " " + input2;
int fromIdx = 1;
if(input1.startsWith(input2)){
fromIdx = input1.indexOf(" ");
listOfPredictions.add(input1.substring(0, fromIdx));
}
while(fromIdx > 0){
fromIdx = input1.indexOf(tokenizer, fromIdx) + 1;
if(fromIdx > 0){
listOfPredictions.add(input1.substring(fromIdx, input1.indexOf(" ", fromIdx)));
}
}
return listOfPredictions.toArray(emptyArr);
}
private static boolean isEmpty(String str){
return str == null || str.trim().length() == 0;
}
We also need to remove all duplicate words from the resulting array.
So first we break the string into words using the string.split() function.
Then push all those words that start with input2 string.
Then from the resulting array, we remove all duplicates by creating a Set and then converting it back into an Array.
function autoComplete(input1, input2) {
let results = [];
if(!input1 || !input1.length || !input2 || !input2.length) return results;
input1 = input1.trim();
input2 = input2.trim();
let allWords = input1.split(/\s+/);
allWords.forEach(word => {
if(word.startsWith(input2)) {
results.push(word);
}
})
results = [...[...new Set(results)]];
return results;
}
I'm getting an ArrayIndexOutOfBoundsException with this program and I can't figure out what the problem is. It allows the user to type 3 inputs but then just gives the error!
If anyone can see where I'm going wrong (I believe it's with the 'parts' after the .split(), but I need the delimiter) ...
public class SplittingStrings
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
//Sample input(not sorted the validation yet) "Chelsea : Arsenal : 2 : 1"
Scanner sc = new Scanner(System.in);
String results = sc.nextLine();
int count = -1;
String str = null;
String[] parts = new String[100];
parts = results.split(":");
String home_team = parts[0];
String away_team = parts[1];
String home_score = parts[2];
String away_score = parts[3];
String[] refinedArray = new String[parts.length];
for (int i = 0;i < 100; i++){
results= sc.nextLine();
for(String s : parts) {
if(s != null) { // Skips over null values. Add "|| "".equals(s)" if you want to exclude empty strings
refinedArray[++count] = s; // Increments count and sets a value in the refined array
}
}
if(sc.equals("stop")) {
Arrays.stream(parts, 0, i).forEach(System.out::println);
}
parts[i] = str;
}
}
It is because of this statement: parts[i] = str. You change value of variable parts in this statement: parts = results.split(":"); so you change size of this array (possibly lesser than 100) and in the for loop you access to an element of this array which is not existed.
Creating an array of 100 elements was pointless
String[] parts = new String[100];
You overwrote it with an array of only 4 (?)
parts = results.split(":");
Your loop goes up to 100, but parts[4] throws the exception
It's not really clear what results is supposed to be, either
Please excuse me for my formatting mistakes as I am very new here.
I have a Java assignment, in which I have to find the lexicographic lowest word that is larger then the given word from a scanner without putting the string in lexicographic order. In this example the given word is "am". I have written the code below but I have the problems that I will explain at the end of this question.
public static void main (String[] args){
Scanner s = new Scanner("I am very happy with life");
String high = "";
String o = "am";
String curr = "";
while (s.hasNext()){
curr = s.next();
if (curr.compareTo(high) > 0)
high = curr;
}
Scanner ss = new Scanner("I am very happy with life");
while (ss.hasNext()){
curr = ss.next();
if (curr.compareTo(high) < 0 && curr.compareTo(o) > 0)
high = curr;
}
System.out.println(high);
}}
My problems are:
I have to write a method that does the computation rather than having the procedure in main. Also I have to use the Scanner once and I can not initialize another scanner with the same value.
This code works ok, but I have the hardest times converting it into a single functional loop method.
PS. Sorry for stupid var names.
Something like this (using a TreeSet):
import java.util.Scanner;
import java.util.TreeSet;
public class LexicographicScanner {
private final TreeSet<String> words = new TreeSet<String>();
public LexicographicScanner( final Scanner scanner )
{
while ( scanner.hasNext() )
{
words.add( scanner.next() );
}
scanner.close();
}
public String nextWord( final String word )
{
return words.higher( word );
}
public static void main(String[] args) {
final LexicographicScanner ls
= new LexicographicScanner ( new Scanner("I am very happy with life") );
System.out.println( ls.nextWord( "am" ) );
System.out.println( ls.nextWord( "I" ) );
System.out.println( ls.nextWord( "with" ) );
}
}
Output
happy
am
null
Edit
Without a TreeSet:
public class LexicographicScanner {
public static String nextWord( final Scanner scanner, final String word )
{
String higher = null, curr;
while ( scanner.hasNext() )
{
curr = scanner.next();
if ( curr.compareTo( word ) > 0 )
{
if ( higher == null || curr.compareTo( higher ) < 0 )
higher = curr;
}
}
return higher;
}
public static void main(String[] args) {
final Scanner s1 = new Scanner("I am very happy with life");
final Scanner s2 = new Scanner("I am very happy with life");
final Scanner s3 = new Scanner("I am very happy with life");
System.out.println( nextWord( s1, "am" ) );
System.out.println( nextWord( s2, "I" ) );
System.out.println( nextWord( s3, "with" ) );
s1.close();
s2.close();
s3.close();
}
}
First make some requirements:
The word i am looking for is lexicographic higher than my input word
The word i am looking for is the lexicographic lowest possible
So basically you have to walk over your input sentence word for word and check those two requirements. Here is some pseudo code, i hope this helps to understand your problem/this solution.
inputWord <= input
currentlyHighest <= null
for (word <= sentence) {
is word higher than inputWord?
no: discard word and analyze the next one
yes: go on
do i have a currently highest word?
no: save the word in currentlyHighest and analyze the next word
yes: go on
is word lower than currentlyHighest?
no: discard word and analyze the next one
yes: we have found a better match: save word in currentlyHighest and analyze the next one
}
Hint:
String res = null;
Scanner s = new Scanner(str);
for each curr in s scanner {
if (curr greater than given
and (dont have res or curr is less than res)) {
res = curr;
}
}