Check exact word in scrabble words list - java

I have a Scrabble Clock with a verification tool inside.
The verification word space looks in green or red if the word that I check is in the list.
The thing is, if I use sbuffer.toString().contains, and write a word like ABA, the word space looks in green though ABA is not in the list, but ABAC, ABACA are in the list.
I would like to know how I can implement a condition in my code to check the exact complete word.
I've researched regex, boundary and matches, but I couldn't find a line code that words in my code.
Here is my code until now.
public class MainActivity extends AppCompatActivity {
TextView textView;
TextView textInV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.texto_1);
textView.setMovementMethod(new ScrollingMovementMethod());
textInV = findViewById(R.id.textIn);
String data = "";
StringBuffer sbuffer = new StringBuffer();
InputStream is = this.getResources().openRawResource(R.raw.fruits);
BufferedReader reader = new BufferedReader((new InputStreamReader(is)));
if (is != null)
{
try
{
while((data =reader.readLine())!=null)
{
sbuffer.append((data + "\n"));
}
is.close();
}
catch (Exception e){ e.printStackTrace();}
}
textView.setText(sbuffer);
}
}

The contains method on a string tests whether the target is contained as a substring; if ABAC is contained as a substring then so is ABA, since ABA is a substring of ABAC and hence it is also a substring of any string which ABAC is a substring of. Therefore, it is not logically possible for the String.contains method to return true for ABAC and false for ABA.
You want to test if the target is one of the elements of a collection of strings, so you should use contains on a collection of strings, not on a string. The best choice is a HashSet, since this performs membership tests in O(1) time on average.
> import java.util.*;
> Set<String> allowed = new HashSet<>();
> allowed.add("ABAC");
> allowed.add("ABACA");
> allowed.contains("ABA")
false
> allowed.contains("ABAC")
true

As #Ashutosh KS has already mentioned, String.contains is not really what you are looking for in this case: You want to check if two strings are identical, not if one contains the other.
The Java String class contains a few methods that you can use to compare the content of two strings, of which you can choose accordingly to match your exact use case:
contentEquals(CharSequence cs) and contentEquals(StringBuffer sb) both check if the passed string representation's content matches the current one.
equals(Object str) is similar to contentEquals in that it makes an exact comparison between both strings, however it also checks to make sure that the passed object is in fact a string.
equalsIgnoreCase(String anotherString), as the name implies, will do a check while ignoring the string case.
These are the 'proper' ways to compare two strings exposed by the native API, so while it is absolutely possible to use other methods, it is a good idea to stick to these.

StringBuffer's contains() check if the given string is a substring of the text in the sbuffer. That means, it will output true for searching "ABC" in "ABC", "ABCBC", "ZABC", "ZABCBC"...
If you want to search for a complete word in the sbuffer, then you can look for "\n" + "ABC" + "\n" since you're adding "\n" when adding words to sbuffer: sbuffer.append((data + "\n"));. But, you must also initialize sbuffer with "\n": StringBuffer sbuffer = new StringBuffer("\n");.
sbuffer.toString().contains("\n" + "ABC" + "\n"); // this will do the trick
Test code:
class Main {
public static void main(String[] args) {
StringBuffer sbuffer = new StringBuffer("\n");
StringBuffer sbuffer2 = new StringBuffer("\n");
sbuffer.append("ABC" + "\n");
sbuffer.append("ABCBC" + "\n");
sbuffer.append("ZABC" + "\n");
sbuffer.append("ZABCBC" + "\n");
System.out.println("Is ABC in sbuffer = " + sbuffer.toString().contains("\n" + "ABC" + "\n"));
sbuffer2.append("ABCBC" + "\n");
sbuffer2.append("ZABC" + "\n");
sbuffer2.append("ZABCBC" + "\n");
System.out.println("Is ABC in sbuffer2 = " + sbuffer2.toString().contains("\n" + "ABC" + "\n"));
}
}
Test output:
Is ABC in sbuffer = true
Is ABC in sbuffer2 = false

Now i have this, and works, but i have a file with the words, and i would like to add the files in the diccionario.
But i don't know how to read the file. I have try bufferread, but i need try/catch, and not works....
Some other solutions....
Thanks
boton2.setOnClickListener(new View.OnClickListener()
{
String content;
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onClick(View view)
{
HashSet<String> diccionario = new HashSet<String>();
//Adding elements to HashSet
diccionario.add("CASA");
diccionario.add("ABAC");
if(diccionario.contains(textIn.getText().toString().toUpperCase()))
{
textIn.setBackgroundColor(Color.GREEN);
}
else
{
textIn.setBackgroundColor(Color.RED);
}
}

Related

How I can use InCombiningDiacriticalMarks ignoring one case

I'm writing code for remove all diacritics for one String.
For example: áÁéÉíÍóÓúÚäÄëËïÏöÖüÜñÑ
I'm using the property InCombiningDiacriticalMarks of Unicode. But I want to ignore the replace for ñ and Ñ.
Now I'm saving these two characters before replace with:
s = s.replace('ñ', '\001');
s = s.replace('Ñ', '\002');
It's possible to use InCombiningDiacriticalMarks ignoring the diacritic of ñ and Ñ.
This is my code:
public static String stripAccents(String s)
{
/*Save ñ*/
s = s.replace('ñ', '\001');
s = s.replace('Ñ', '\002');
s = Normalizer.normalize(s, Normalizer.Form.NFD);
s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", "");
/*Add ñ to s*/
s = s.replace('\001', 'ñ');
s = s.replace('\002', 'Ñ');
return s;
}
It works fine, but I want know if it's possible optimize this code.
It depends what you mean by "optimize". It's tough to reduce the number of lines of code from what you have written, but since you are processing the string six times there's scope to improve performance by processing the input string only once, character by character:
public class App {
// See SO answer https://stackoverflow.com/a/10831704/2985643 by virgo47
private static final String tab00c0
= "AAAAAAACEEEEIIII"
+ "DNOOOOO\u00d7\u00d8UUUUYI\u00df"
+ "aaaaaaaceeeeiiii"
+ "\u00f0nooooo\u00f7\u00f8uuuuy\u00fey"
+ "AaAaAaCcCcCcCcDd"
+ "DdEeEeEeEeEeGgGg"
+ "GgGgHhHhIiIiIiIi"
+ "IiJjJjKkkLlLlLlL"
+ "lLlNnNnNnnNnOoOo"
+ "OoOoRrRrRrSsSsSs"
+ "SsTtTtTtUuUuUuUu"
+ "UuUuWwYyYZzZzZzF";
public static void main(String[] args) {
var input = "AaBbCcáÁéÉíÍóÓúÚäÄëËïÏöÖüÜñÑçÇ";
var output = removeDiacritic(input);
System.out.println("input = " + input);
System.out.println("output = " + output);
}
public static String removeDiacritic(String input) {
var output = new StringBuilder(input.length());
for (var c : input.toCharArray()) {
if (isModifiable(c)) {
c = tab00c0.charAt(c - '\u00c0');
}
output.append(c);
}
return output.toString();
}
// Returns true if the supplied char is a candidate for diacritic removal.
static boolean isModifiable(char c) {
boolean modifiable;
if (c < '\u00c0' || c > '\u017f') {
modifiable = false;
} else {
modifiable = switch (c) {
case 'ñ', 'Ñ' ->
false;
default ->
true;
};
}
return modifiable;
}
}
This is the output from running the code:
input = AaBbCcáÁéÉíÍóÓúÚäÄëËïÏöÖüÜñÑçÇ
output = AaBbCcaAeEiIoOuUaAeEiIoOuUñÑcC
Characters without diacritics in the input string are not modified. Otherwise the diacritic is removed (e.g. Çto C), except in the cases of ñ and Ñ.
Notes:
The code does not use the Normalizer class or InCombiningDiacriticalMarks at all. Instead it processes each character in the input string only once, removing its accent if appropriate. The conventional approach for removing diacritics (as used in the OP) does not support selective removal as far as I know.
The code is based on an answer by user virgo47, but enhanced to support the selective removal of accents. See virgo47's answer for details of mapping an accented character to its unaccented counterpart.
This solution only works for Latin-1/Latin-2, but could be enhanced to support other mappings.
Your solution is very short and easy to understand, but it feels brittle, and for large input I suspect that it would be significantly slower than an approach that only processed each character once.
Ave Maria Purisima,
You can create a pattern excluding the tilde from the diacritical marks set:
private static final Pattern STRIP_ACCENTS_PATTERN = Pattern.compile("[\\p{InCombiningDiacriticalMarks}&&[^\u0303]]+");
public static String stripAccents(String input) {
if (input == null) {
return null;
}
final StringBuilder decomposed = new StringBuilder(Normalizer.normalize(input, Normalizer.Form.NFD));
return STRIP_ACCENTS_PATTERN.matcher(decomposed).replaceAll(EMPTY);
}
Hope it helps

Trying to convert a text to a java string array

I'm trying to have an EditText that will check every word written while ignoring all special characters, and and add it to a String array. My idea was to make every new word clickable and use it to connect to an API.
I've tried a few things a found on the internet but never really worked.
#Override
public void afterTextChanged(Editable s) {
String string = editText_Main.getText().toString();
String[] arr = string.split(" ");
for ( String ss : arr) {
System.out.println("Adding: " + ss + " to words array");
words.add(ss);
}
System.out.println("Words array -> "+words);
}
So the idea was just to use the words array for creating all of the links and somehow using it to also link them to the EditText, but maybe this is a completely wrong approach and someone can lead me on a better path.
Instead of using
String string = editText_Main.getText().toString();
you should use
String string = s.getText().toString();

Issue with Java string search pattern ( contains / matches)

I have one string which contains a couple of attribute values. While verifying whether the string contains specific attribute values or not by using some simple regex, the matches function is always returning false value.
Now I need the behavior like,
If String contains \"import\" : Then I need isExportSet to be
set as true.
If String contains \"path\" : true Then I need
isPathSet to be set to true.
I tried as shown below, but it did not work for me:
public class DriverClass {
public static void main(String[] args) {
String str = "\"import\" : \"static\",\"path\" : true";
boolean isExportSet = str.matches("\\*+export\\*+");
boolean isPathSet = str.matches("\\*+multipath\\s+:\\s+true");
System.out.println("Export " + isExportSet);
System.out.println("Path " + isPathSet);
}
}
Please let me know if the following code fulfill the problem deifinition.
static String str = "\"import\" : \"static\",\"path\" : true";
static void test(String str) {
Map<String, String> map = new HashMap<String, String>();
String[] parts = str.split("(:|,)");
for (int i = 0; i < parts.length - 1; i+=2) {
map.put(getUnquotedStr(parts[i]), getUnquotedStr(parts[i+1]));
}
System.out.println(map.size() + " entries: " + map); // 2 entries: {path=true, import=static}
boolean isExportSet = "".equals(map.get("import"));
boolean isPathSet = "true".equals(map.get("path"));
System.out.println(isExportSet + " - " + isPathSet);
}
private static String getUnquotedStr(String str) {
return str.replaceAll("\"", "").trim();
}
will print as follows on the console:
2 entries: {path=true, import=static}
false - true
You can simply use str.contains("valueToSerach")
You can use
\"import\"
\"(path|multipath)\"
And please never connect a * with another quantity indicator that leads to errors.
And since you want to check the " hard, you have to include them in your expression.
Testing the string for containing \"import\" is just checking if the string contains "import". In your regular expression you need to disregard the \ check because this is an escape character for Java to be able to handle the double quotes inside a string, without ending the string definition. You will, however, need to escape those characters in your regex as well.
For "import" the regex becomes str.matches(\"import\"). Analogous for the "path" string.
I found this a handy tool to check regex's: Free Formatter

How to make spaced text .equal() to unspaced text

I am working on code that takes two inputs like the following:
,Air Condition,
, Air Condition,
This text is received from a JSON object and the commas are something that must be considered.
As can be seen, one has white space at the beginning and the other doesn't. How can I compare them using the equals()?
So far, I have used the following code to compare the two strings:
if (oldSelected.get(i).equalsIgnoreCase(String.valueOf(fc.getText()))){
fc.setChecked(true);
}
However, it doesn't do what I expect it to do.
How i can trim this space and get the desired results?
You need to trim the white spaces first.
String oldSelected = ",Air Conditioner,";
String newSelected = ", Air Conditioner, ";
if(oldSelected.replaceAll("\\s", "").equalsIgnoreCase(newSelected.replaceAll("\\s", ""))){
// Do Something
}
else{ // Do Something Else
}
Hope that helps! :)
You can do something like this:
public static void main(String[] args) {
String s1 = ",Air Condition";
String s2 = ", Air Condition";
System.out.println(s1.equals(s2.replace(", ", ",")));
}
or, if you want to keep space between words, you may use like this:
public static void main(String[] args) {
String s1 = ",Air Condition";
String s2 = ", Air Condition";
System.out.println(s2.split(", ")[1]);
System.out.println(s1.split(",")[1]);
System.out.println(s1.split(",")[1].equals(s2.split(", ")[1]));
}
Try,
String.valueOf(fc.getText())).replaceAll("\\s+","")
This removes all whitespaces and non-visible characters (e.g. tab, \n)
you can use String methot called SPLIT for example you have
String STR1 = "Ahoj"
String STR2 = "Ahoj "
String x[] = STR1.split(" ");
String y[] = STR2.split(" ");
then use simple for loop to check all words :)
Well, worked solution as #Rahul suggest to use .trim() but this worked with english words only, so in order to equalize all language i trim the equalized text to as below :
String checkedVal = oldSelected.get(i);
checkedVal = checkedVal.trim();
if (checkedVal.equalsIgnoreCase(String.valueOf(fc.getText().toString().trim()))){
fc.setChecked(true);
}
Thanks for all answers.

string tokenizing from textview

I have TextView with text that changed dynamically.
i want tokenizing this text with delimiter space " " and send to another textview
this is my code
public void onClick(View v) {
// TODO Auto-generated method stub
if (v.getId()==R.id.button5){
Intent i = new Intent(this, Tokenizing.class);
String test = ((TextView)findViewById(R.id.textView6)).getText().toString();
String result = null;
StringTokenizer st2 = new StringTokenizer(test," ");
while (st2.hasMoreTokens()) {
String st3 = st2.nextToken();
System.out.println(st3);
result = st3;
}
i.putExtra("result", result);
startActivity(i);
Log.i("Test Klik Next", result);
but i have just last word in the textview.
text before tokenizing:
Examples of paradoxes can be humorous and confusing
text after tokenizing:
confusing
where is the part of my coding is wrong?
You are overwriting the result every time you read a new token
result = st3;
So it's always equal to the last value. Change the type of result from String to StringBuilder and just build it as you go
result.append(st3 + " "); //re-adding the space as the StringTokenizer will remove it
Then after the StringTokenizer loop just get the built String using result.toString()
Why not result += st3?
Some other answers suggest you do this. The reason not to do this is that in Java, String is immutable. This means they can't be changed so any time you append two String objects, a new String object is created.
So every step through the loop you are creating a new String object which is inefficient and unnecessary. StringBuilder is not immutable and Strings can be appended to it without the overhead of creating new objects every time.
StringTokenizer
Worth noting -as #RGraham said in the comments- that this class is deprecated. This means it's no longer in common use, use of it is discouraged and it could be removed at some point.
More information here.
Tokens - in or out
As other answers assumed the opposite of me and after discussion on one of said answers and on meta, I feel I need to clarify this. I
'm not sure if your intention was to get rid of the tokens (in this case spaces " ") and end up with
Examplesofparadoxescanbehumorousandconfusing
or to replace them when outputting the final String and get out what you put in. So I assumed you wanted to preserve the original meaning and replace them. Otherwise a quicker way to get the result above would be to simply skip all the tokenizing and do
test.replaceAll(" ","");
while (st2.hasMoreTokens()) {
String st3 = st2.nextToken();
System.out.println(st3);
result = st3; // Everytime you are reassigning result to some other String
}
Replace
result = st3; by (initialize String result=" ";)
result+=st3+" "
and then replace
i.putExtra("result", result); with i.putExtra("result", result.trim());
Try this , it will show perfect result.
You can also do this result.append(st3+" "); and then i.putExtra("result", result.trim());

Categories