How to Search a string array for specific strings - java

I am trying to search an array for a couple of specific strings that I get from words in a sentence. Eventually this sentence will be in-putted by the user but I have hard coded it in at the moment to make testing easier.If the program finds the strings it should return with "Yes" and "No" if it doesn't. The problem is that I am getting yes all the Time.
public class main {
public static void main(String[]args)
{
String Sentence = "This is a sentence";
String[] CensorList =
{"big","head"};
String[] words = Sentence.split(" ");
System.out.println(words.length);
boolean match = false;
for(int i = 0; i < words.length; i++)
{
for (int j = 0; j < CensorList.length; j++)
{
if(words[i].equals(CensorList[j]))
{
match = true;
}else{
match = false;
}
}
}
if (match = true){
System.out.println("Yes");}
else{
System.out.println("No");
}
}
}
I would really appreciate any help with this one, Thanks in advance.

the if in your second for() has wrong braces.
try this one:
for (int j = 0; j < CensorList.length; j++)
{
if(words[i].equals (CensorList[j])) {
match = true;
System.out.println("Yes");
} else {
System.out.println("No");
}
match = false;
}
for your second try:
the
if (match = true)
does not compare match with true, it sets the match flag to true, which results always in true.
compare the flag in your if:
if (match == true) // or simply if (match)
{ ....

Try it:
for(int i = 0; i < words.length; i++)
{
for (int j = 0; j < CensorList.length; j++)
{
if(words[i].equals (CensorList[j]))
match = true;
}
if (match) {
System.out.println("Yes"); }
else {
System.out.println("No"); }
match = false;
}

I think you have some typos in here.
for (int j = 0; j < CensorList.length; j++)
{
if(words[i].equals (CensorList[j]));
}
This will do essentially nothing, as the if has nothing to do if the expression is evaluated to true. Then after the loop you set match to true, so it will be true always, and it will always print "Yes"

You can use a simple RegEx based solution for this
private static boolean test(String value) {
String[] CensorList = { "This", "No" };
for (String string : CensorList) {
Pattern pattern = Pattern.compile("\\b" + string + "\\b", Pattern.CASE_INSENSITIVE);
if (pattern.matcher(value).find()) {
return true;
}
}
return false;
}
Then
String string = "This is a sentence";
if(test(string)){
System.out.println("Censored");
}

Any reason you are not using String.indexOf(String) ?
Another issue is if you are doing this repeatedly for the same (very large) stirng in which case, you might want to look into more sophisticated algorithms like suffix trees or even use specialized software like Apache Lucene

Try to use
public class main {
public static void main(String[]args)
{
String Sentence = "This is a sentence";
String[] CensorList =
{"This","No"};
String[] words = Sentence.split(" ");
System.out.println(words.length);
boolean match = false;
for(int i = 0; i < words.length; i++)
{
for (int j = 0; j < CensorList.length; j++)
{
if(words[i].compareTo(CensorList[j])==0)
{
System.out.println("Yes");
}
else{System.out.println("No");}
}
}
}

Related

How do you solve this problem with a nested for loop

My goal is to print out names with 2 letters that are the same with only one of the same letter in the name. For example brook would be printed out as brok and michelle would be printed out as michel. Whats wrong with my code?
for(int a = 0; a < word_1.length(); a++)
{
mychar = word_1.charAt(a);
for(int c = 1; c <word_1.length(); c++)
{
mychar_2 = word_1.charAt(c);
if(mychar == mychar_2)
{
word_3 = word_3 + "";
}
else
{
word_3 = word_3 + mychar;
}
}
}
System.out.println(word_3);
Better question is "what is right with the code". Basically the idea looks like going through all letters and then going through all matches. This is not too bad and we can slightly change your code to make it work (see comments):
for(int a = 0; a < word_1.length(); a++)
{
char mychar = word_1.charAt(a);
// flag for matching letters
Boolean found = false;
// you go through only previous characters!
for(int c = 0; !found && c < a; c++)
{
char mychar_2 = word_1.charAt(c);
if(mychar == mychar_2)
{
found = true;
}
}
// here you add character if no match found
if(!found) {
word_3 = word_3 + mychar;
}
}
This is a good way in academic coding, but in actual project if you deal with large numbers of words, you have to consider Map based solution to keep all existing letters and iterate only once through each word. Or you can search for some methods in numerous java libraries to do the job
This would solve the problem:
String testWord = "brook";
List<String> testSet = new ArrayList<String>();
for (int i = 0; i < testWord.length(); i++) {
if (!testSet.contains(String.valueOf(testWord.charAt(i)))) {
testSet.add(String.valueOf(testWord.charAt(i)));
}
}
StringBuilder builder = new StringBuilder();
for (Object s : testSet.toArray()) {
builder.append((String) s);
}
String str = builder.toString();
System.out.println(str);

find subsequence in a string: Java

I have a string hackkkerrank and i have to find if any subsequence gives a result as hackerrank, if it is present then it gives result as YES otherwise NO.
Sample:
hereiamstackerrank: YES
hackerworld: NO
I don't know which String method should be applied, can anyone help me how to do it?
Here is my code:
static String hackerrankInString(String s) {
char str[] = {
'h','a','c','k','e','r','a','n','k'
};
while (s.length() >= 10) {
for (int i = 0; i < s.length(); i++) {
for (char c: str) {
if (s.indexOf(c)) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
}
}
Here is a built-in way, using regex:
String regex = "[^h]*+h[^a]*+a[^c]*+c[^k]*+k[^e]*+e[^r]*+r[^r]*+r[^a]*+a[^n]*+n[^k]*+k.*";
System.out.println("hereiamstackerrank".matches(regex) ? "YES" : "NO");
System.out.println("hackerworld".matches(regex) ? "YES" : "NO");
Output
YES
NO
You can make a generic method to check for subsequence like this:
public static boolean containsSubsequence(String subsequence, String text) {
StringBuilder buf = new StringBuilder();
for (int i = 0, j; i < subsequence.length(); i = j) {
j = subsequence.offsetByCodePoints(i, 1);
String ch = Pattern.quote(subsequence.substring(i, j));
buf.append("[^").append(ch).append("]*+").append(ch);
}
String regex = buf.append(".*").toString();
return text.matches(regex);
}
Test
System.out.println(containsSubsequence("hackerrank", "hereiamstackerrank") ? "YES" : "NO");
System.out.println(containsSubsequence("hackerrank", "hackerworld") ? "YES" : "NO");
Output
YES
NO
Of course, it is not very efficient, but it is one way to do it.
For a simpler and more efficient solution, that doesn't handle characters in the Supplement­ary Planes, you'd do this:
public static boolean containsSubsequence(String subsequence, String text) {
int j = 0;
for (int i = 0; i < text.length() && j < subsequence.length(); i++)
if (text.charAt(i) == subsequence.charAt(j))
j++;
return (j == subsequence.length());
}
Here is an old fashioned looping way, which increments the starting position of the second string based upon where the last char was found
String str1 = "hackerrank";
String str2 = "hereiamstackerrank";
int index = 0;
for (int i = 0; i < str1.length(); i++)
{
boolean notfound = true;
int x = index;
for (; x < str2.length(); x++) {
if (str1.charAt(i) == str2.charAt(x)) {
notfound = false;
break;
}
}
if (notfound) {
System.out.println("NO");
return;
}
index = x + 1;
}
System.out.println("YES");
An in-efficient alternative is
for (int i = 0; str1.length() > 0 && i < str2.length(); i++)
{
if (str1.charAt(0) == str2.charAt(i)) {
str1 = str1.substring(1);
}
}
System.out.println(str1.length() == 0 ? "YES" : "NO");
static String re="";
static String hackerrankInString(String s) {
String pattern="[^h]*+h[^a]*+a[^c]*+c[^k]*+k[^e]*+e[^r]*+r[^r]*+r[^a]*+a[^n]*+n[^k]*+k.*";
if(s.matches(pattern)){
re="YES";
}else{
re="NO";
}
return re;
}
There's no built in function in core libraries to check subsequence. There's one for substring but none for subsequence you're looking for.
You'll have to code it yourself.
Below is the pseudo code for this:
1. Traverse both original string and string under test.
2. Increment both's counter if characters are equal
3. Else increment originalString's counter only.
4. Repeat 2-3 `while` both strings are `not` empty.
5. Given string under test is subsequence if its counter is exhausted.

How to fill the null array with a specific number in Java ?

I'm trying to solve a palindrome problem that the input consists of Strings , if the concatenation of two strings represent a palindrome word(A palindrome is a word which can be read the same way in either direction. For example, the following
words are palindromes: civic, radar, rotor, and madam)
then save it into array to print it latter otherwise print "0"
but I'm having a problem in filling the null index with zeros , here I get Exception
for (int re = 0; re < result.length; re++) {
if (result[re].equals(null)) {
result[re] = "0";
}
}
"Exception in thread "main" java.lang.NullPointerException"
here is my full code
import java.util.Scanner;
public class Palindrome {
public static String reverse(String R2) {
String Reverse = "";
String word_two = R2;
int ln = word_two.length();
for (int i = ln - 1; i >= 0; i--) {
Reverse = Reverse + word_two.charAt(i);
}
return Reverse;
}
public static void main(String[] args) {
Scanner inpoot = new Scanner(System.in);
int stop = 0;
String pal1;
int Case = inpoot.nextInt();
String result[] = new String[Case];
String Final;
int NumberofWords;
for (int i = 0; i < Case; i++) {
NumberofWords = inpoot.nextInt();
String words[] = new String[NumberofWords];
for (int array = 0; array < words.length; array++) {
words[array] = inpoot.next();
}
for (int word1 = 0; word1 < NumberofWords; word1++) {
if (stop > Case) {
break;
}
for (int word2 = 0; word2 < NumberofWords; word2++) {
if (word1 == word2) {
continue;
}
Final = "" + words[word1].charAt(0);
if (words[word2].endsWith(Final)) {
pal1 = words[word1].concat(words[word2]);
} else {
continue;
}
if (pal1.equals(reverse(pal1))) {
result[i] = pal1;
stop++;
break;
} else {
pal1 = "";
}
}
}
}
// HERE IS THE PROBLEM
for (int re = 0; re < result.length; re++) {
if (result[re].equals(null)) {
result[re] = "0";
}
}
for (int x = 0; x < result.length; x++) {
System.out.println("" + result[x]);
}
}
}
A test such as anObject.equals(null) makes no sense. Indeed, if anObject is null, it will throw a NullPointerException (NPE), and if it is not, it will always return false.
To test if a reference is null, just use anObject == null.
If you want to check whether result[re] is null, you cannot use equals. Use the identity comparison:
if (result[re] == null) {
result[re] = "0";
}

How to search via character matching with a skip distance?

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.

Get the meaning of a word/ String array

So this is the continuation of my question from this thread: here
String[] words = {"cowboy", "animal", "monster"};
String[] meanings = {"meaning1", "meaning2", "meaning3"};
boolean check = false;
for (int i = 0; i < words.length; i++) {
if (s.toLowerCase().contains(words[i].toLowerCase())) {
check = true;
} else {
}
}
if (check) {
System.out.println("Yes");
} else {
System.out.println("No");
}
But I can't seem to figure out how and where to put the specific meaning of each word that has been typed by the user in the edittext. Any help would be gladly appreciated. Thanks.
static String[] words = { "Cowboy", "animal", "monster" };
static String s = "My animal is a Cowboy";
static boolean check = false;
static String[] meanings = {"meaning1", "meaning2", "meaning3"};
static ArrayList<String> typed_words = new ArrayList<String>();
static ArrayList<String> typed_meanings = new ArrayList<String>();
for (int i = 0; i < words.length; i++) {
if (s.toLowerCase().contains(words[i].toLowerCase())) {
typed_words.add(words[i]);
typed_meanings.add(meanings[i]);
check = true;
} else {
}
}
if (check) {
System.out.println("Yes");
for(int i=0;i<typed_words.size();i++){
System.out.println("Word: "+typed_words.get(i)+" Meaning: "+typed_meanings.get(i));
}
} else {
System.out.println("No");
}
what about something like that?
int index;
...
if (s.toLowerCase().contains(words[i].toLowerCase())) {
check = true;
index = i;
} else {
....
if (check) {
System.out.println(meanings[index]);
} else {
...
If the words and their meanings have the same relative positions in the two arrays then re-use the index i to print the corresponding meaning as well. But, the i would now have to be defined outside the loop so that it has a bigger scope now and is available inside the if check.
int i = 0
for (; i < words.length; i++) {
if (s.toLowerCase().contains(words[i].toLowerCase())) {
check = true;
break;
}
}
if (check) {
System.out.println("Meaning found: " + meanings[i]);
}
Since words and meanings arrays have the relative indexing, you can-
boolean check = false;
for (int i = 0; i < words.length; i++) {
if (s.equalsIgnoreCase(words[i])) { // We don't need "toLowerCase"
System.out.println("Word: " + words[i] + "\tMeaning: " + meanings[i]);
check = true;
break; // Match found; so get out of the loop
}
}
if(check){
System.out.println("Found!");
} else {
System.out.println("Not Found!");
}
Why not use a java.util.HashMapin which every word maps to a meaning?
String s = "";
HashMap<String,String> meaningMap = new HashMap<String,String>();
//just for the example
meaningMap.put("cowboy", "meaning1");
...
if (s.toLowerCase().contains(words[i].toLowerCase())) {
ouput = meaningMap.get(s);
}
...
System.out.println(s);
Another idea would be to use HashMap to store your data.
HashMap hm = new HashMap();
hm.put("cowboy", "meaning1");
hm.put("animal", "meaning2");
And then use
String s = yourEdittext.getText();
String[] words = s.split("\s+");
for (int i = 0; i < words.length(); i++) {
words[i] = words[i].replaceAll("[^\w]", "");
}
for (int i=0; i < words.length(); i++) {
if (hm.containsKey(words[i])) {
System.out.println("Meaning found: " + hm.get(words[i]));
}
}
This basically gets the sentece form the edittext, splits it into words then checks if each word is in the HashMap. This is good if your list of words is going to be quite big in comparison to the length of the sentence.
i would suggest that you make a Hashmap<String ,ArrayList<String>>
as you have more than one meaning for oneword.
so now just passing the word you need to find the meaning for.
you can.also use treemap if you need to store them in a sorted fashion.
so here's how you can find the meaning for a word .
ArrayList<String> meaning =map.get("cowboy");
for(String string : meaning ) {
Log.v("meaning",string);
}

Categories

Resources