I am writing a program which is the opposite of Auto Correct. The logic is that the user enters a sentence, when a button is pressed, the grammatical opposite of the sentence entered by the user should be displayed. I am roughly able to get the code. I used the matcher logic.But i am not able to get the desired output. I am linking the code with this question. Can anyone help me please?
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String input = editText.getText().toString();
String store = input;
String store1 [] = store.split(" ");
String correct[] = {"is","shall","this","can","will"};
String wrong [] = {"was","should","that","could","would"};
String output = "";
for (int i=0;i<store1.length;i++) {
for(int j=0;j<correct.length;j++){
if(store1[i].matches(correct[j])) {
output = input.replace(store1[i], wrong[j]);
//store1[i] = wrong[j];
}
else
{
input.replace(store1[i], store1[i]);
//store1[i] = store1[i];
}
}
mTextView.setText(output);
}
}});
By looking at your code, I've found some redundancy and unused variable. Shown as below.
String store = input;
String store1 [] = store.split(" ");
As shown below, I did some cleanup for you and implement your logic using Map interface. The wrong value must be the Key of the map so that we can easily determine is the word a wrong value using Map.containKeys(word). If key is found then we concatenate the output variable with the correct word.
String input = editText.getText().toString().split(" ");
Map<String, String> pairs = new HashMap<>();
pairs.put("is", "was");
pairs.put("shall", "should");
pairs.put("this", "that");
pairs.put("can", "could");
pairs.put("will", "would");
String output = "";
for (String word : input) {
if (pairs.containsKey(word)) {
output = output + pairs.get(word) + " ";
} else {
output = output + word + " ";
}
}
mTextView.setText(output.trim());
Related
I need help to parse a string in Java... I'm very new to Java and am not sure how to go about it.
Suppose the string I want to parse is...
String str = "NC43-EB2;49.21716;-122.667252;49.216757;-122.666235;"
What I would want to do is:
String name = C43
String direction = EB2;
Then what I'd like to do is store 2 coordinates as a pair...
Coordinate c1 = 49.21716;-122.667252;
Coordinate c2 = 49.216757;-122.666235;
And then make a List to store c1 and c2.
So far I have this:
parseOnePattern(String str) {
String toParse = str;
name = toParse.substring(1, toParse.indexOf("-"));
direction = toParse.substring(toParse.indexOf("-", toParse.indexOf(";")));
I'm not sure how to move forward. Any help will be appreciated.
A simple substring function may solve your problem.
String str = "NC43-EB2;49.21716;-122.667252;49.216757;-122.666235;";
String[]s = str.split(";");
String[]n = s[0].split("-");
String name = n[0].substring(1);
String direction = n[1];
String c1 = s[1] +";"+s[2];
String c2 = s[3] +";"+s[4];
System.out.println(name + " " + direction);
System.out.println(c1 + " " + c2);
I hope this helps you.
Welcome to Java and the whole set of operations it allows to perform on Strings. You have a whole set of operations to perform, I will give you the code to perform some of them and get you started :-
public void breakString() {
String str = "NC43-EB2;49.21716;-122.667252;49.216757;-122.666235";
// Will break str to "NC43-EB2" and "49.21716" "-122.667252" "49.216757" "-122.666235"
String [] allValues = str.split(";", -1);
String [] nameValuePair = allValues[0].split("-");
// substring selects only the specified portion of string
String name = nameValuePair[0].substring(1, 4);
// Since "49.21716" is of type String, we may need it to parse it to data type double if we want to do operations like numeric operations
double c1 = 0d;
try {
c1 = Double.parseDouble(allValues[1]);
} catch (NumberFormatException e) {
// TODO: Take corrective measures or simply log the error
}
What I would suggest you is to go through the documentation of String class, learn more about operations like String splitting and converting one data type to another and use an IDE like Eclipse which has very helpful features. Also I haven't tested the code above, so use it as a reference and not as a template.
Ok i made this:
public static void main(String[] args) {
String str = "NC43-EB2;49.21716;-122.667252;49.216757;-122.666235;";
String[] strSplit = str.split(";");
String[] nameSplit=strSplit[0].split("-");
String name=nameSplit[0].replace("N", "");
String direction= nameSplit[1];
String cordanateOne = strSplit[1]+";"+strSplit[2]+";";
String cordanateTwo = strSplit[3]+";"+strSplit[4]+";";
System.out.println("Name: "+name);
System.out.println("Direction: "+direction);
System.out.println("Cordenate One: "+cordanateOne);
System.out.println("Cordenate Two: "+cordanateTwo);
}
Name: C43
Direction: EB2
Cordenate One: 49.21716;-122.667252;
Cordenate Two: 49.216757;-122.666235;
String str3 = "NC43-EB2;49.21716;-122.667252;49.216757;-122.666235;";
String sub = str3.substring(0,4); // sub = NC43
String sub4 = str3.substring(5,9); // sub = EB2;
HashMap<String, String> hm = new HashMap<>();
hm.put(str3.substring(9 ,30), str3.substring(30));
hm.forEach((lat, lot) -> {
System.out.println(lat + " - " + lot); // 49.21716;-122.667252; - 49.216757;-122.666235;
});
//edit if using an array non pairs (I assumed it was lat + lon)
List<String> coordList = new ArrayList<>();
coordList.add(str3.substring(9 ,30));
coordList.add(str3.substring(30));
coordList.forEach( coord -> {
System.out.println(coord);
});
//output : 49.21716;-122.667252;
49.216757;-122.666235;
The program that I am writing is in Java.
I am attempting to make my program read the file "name.txt" and store the values of the text file in an array.
So far I am using a text file that will be read in my main program, a service class called People.java which will be used as a template for my program, and my main program called Names.java which will read the text file and store its values into an array.
name.txt:
John!Doe
Jane!Doe
Mike!Smith
John!Smith
George!Smith
People.java:
public class People
{
String firstname = " ";
String lastname = " ";
public People()
{
firstname = "First Name";
lastname = "Last Name";
}
public People(String firnam, String lasnam)
{
firstname = firnam;
lastname = lasnam;
}
}
Names.java:
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Names
{
public static void main(String[]args)
{
String a = " ";
String b = "empty";
String c = "empty";
int counter = 0;
People[]peoplearray=new People[5];
try
{
File names = new File("name.txt");
Scanner read = new Scanner(names);
while(read.hasNext())
{
a = read.next();
StringTokenizer token = new StringTokenizer("!", a);
while(token.hasMoreTokens())
{
b = token.nextToken();
c = token.nextToken();
}
People p = new People(b,c);
peoplearray[counter]=p;
++counter;
}
}
catch(IOException ioe1)
{
System.out.println("There was a problem reading the file.");
}
System.out.println(peoplearray[0]);
}
}
As I show in my program, I tried to print the value of peoplearray[0], but when I do this, my output reads: "empty empty" which are the values I gave String b and String c when I instantiated them.
If the program were working corrrectly, the value of peoplearray[0] should be, "John Doe" as those are the appropriate values in "names.txt"
What can I do to fix this problem?
Thanks!
StringTokenizer(String str, String delim)
is the constructor of StringTokenizer.
You have written it wrong .
Just change your line
StringTokenizer token = new StringTokenizer("!", a); to
StringTokenizer token = new StringTokenizer(a, "!");
Just change it a little bit
StringTokenizer token = new StringTokenizer(a, "!");
while(token.hasMoreTokens())
{
b = token.nextToken();
c = token.nextToken();
}
//do something with them
I've a tricky condition which does not seem to work. For a given string, "Hi [HandleKey], you have [Action]", and a map which contains, map<"HandleKey","Peter"> I want to replace the square bracket and the word within if the key is found in the map. In this case, the map does not contain the key Action. The string should return "Hi Peter, you have [Action]".
Here is the code that I'm working on:
private String messageFormatter(String tMessage, Map<String, String> messageMap)
{
String formattedMsg = null;
Set<String> keyset = messageMap.keySet();
Iterator<String> keySetItr = keyset.iterator();
String msgkey = null;
boolean isFormatted = false;
while (keySetItr.hasNext())
{
msgkey = keySetItr.next();
if(t.contains(msgkey))
{
if(!isFormatted)
{
formattedMsg = tMessage.replaceAll("\\[", "").replaceAll("\\]", "");
formattedMsg = formattedMsg.replaceAll(msgkey, messageMap.get(msgkey));
isFormatted= true;
}else
{
formattedMsg = formattedMsg.replaceAll(msgkey, messageMap.get(msgkey));;
}
}else
{
formattedMsg=tMessage;
}
}
return formattedMsg;
}
The last else part is not right. Can anyone please help me with this. This code works fine for all the cases except when a matching key is not found in the map
is this idea ok for you?
instead of applying regex or extracting the stuff between [..], you could do some trick on your map side. e.g.
String s = "Hi [HandleKey], you have [Action]";
for(String k: yourMap.keySet()){
s=s.replaceAll("\\["+k+"\\]",yourMap.get(k));
}
You can do this with regex, here is a complete example code
public static void main(String[] args) {
String str = "Hi [HandleKey], you have [Action] ";
Hashtable<String, String> table = new Hashtable<String, String>();
table.put("HandleKey", "Peter");
Pattern pattern = Pattern.compile("\\[(\\w+)\\]");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
String key = matcher.group(1);
if (table.containsKey(key)) {
str = str.replaceFirst("\\[" + key + "\\]", table.get(key));
}
}
System.out.println(str);
}
Output:
Hi Peter, you have [Action]
Note that this is more efficient than looping over the Map if the map size is already large or growing.
To handle when key not in map with minimal changes to what you have above try
formattedMsg.replaceAll(msgkey,
(messageMap.containsKey(msgKey) ? messageMap.get(msgkey) : "[" + msgKey + "]"));
but looking again I can see that you're iterating the set of keys from the messageMap so the issue of a key not appearing in the map doesn't arise?
There's also a reference to if(t.contains(msgKey))... but not sure what t is
if you want the text to contain the formatted [msgKey] when its no found then replacing all "[" & "]" seems the wrong way to start if you want to put them back in in some cases.
I'd look at #iTech's suggestion and get regex doing more for you
I want to filter a string.
Basically when someone types a message, I want certain words to be filtered out, like this:
User types: hey guys lol omg -omg mkdj*Omg*ndid
I want the filter to run and:
Output: hey guys lol - mkdjndid
And I need the filtered words to be loaded from an ArrayList that contains several words to filter out. Now at the moment I am doing if(message.contains(omg)) but that doesn't work if someone types zomg or -omg or similar.
Use replaceAll with a regex built from the bad word:
message = message.replaceAll("(?i)\\b[^\\w -]*" + badWord + "[^\\w -]*\\b", "");
This passes your test case:
public static void main( String[] args ) {
List<String> badWords = Arrays.asList( "omg", "black", "white" );
String message = "hey guys lol omg -omg mkdj*Omg*ndid";
for ( String badWord : badWords ) {
message = message.replaceAll("(?i)\\b[^\\w -]*" + badWord + "[^\\w -]*\\b", "");
}
System.out.println( message );
}
try:
input.replaceAll("(\\*?)[oO][mM][gG](\\*?)", "").split(" ")
Dave gave you the answer already, but I will emphasize the statement here. You will face a problem if you implement your algorithm with a simple for-loop that just replaces the occurrence of the filtered word. As an example, if you filter the word ass in the word 'classic' and replace it with 'butt', the resultant word will be 'clbuttic' which doesn't make any sense. Thus, I would suggest using a word list,like the ones stored in Linux under /usr/share/dict/ directory, to check if the word is valid or it needs filtering.
I don't quite get what you are trying to do.
I ran into this same problem and solved it in the following way:
1) Have a google spreadsheet with all words that I want to filter out
2) Directly download the google spreadsheet into my code with the loadConfigs method (see below)
3) Replace all l33tsp33k characters with their respective alphabet letter
4) Replace all special characters but letters from the sentence
5) Run an algorithm that checks all the possible combinations of words within a string against the list efficiently, note that this part is key - you don't want to loop over your ENTIRE list every time to see if your word is in the list. In my case, I found every combination within the string input and checked it against a hashmap (O(1) runtime). This way the runtime grows relatively to the string input, not the list input.
6) Check if the word is not used in combination with a good word (e.g. bass contains *ss). This is also loaded through the spreadsheet
6) In our case we are also posting the filtered words to Slack, but you can remove that line obviously.
We are using this in our own games and it's working like a charm. Hope you guys enjoy.
https://pimdewitte.me/2016/05/28/filtering-combinations-of-bad-words-out-of-string-inputs/
public static HashMap<String, String[]> words = new HashMap<String, String[]>();
public static void loadConfigs() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(new URL("https://docs.google.com/spreadsheets/d/1hIEi2YG3ydav1E06Bzf2mQbGZ12kh2fe4ISgLg_UBuM/export?format=csv").openConnection().getInputStream()));
String line = "";
int counter = 0;
while((line = reader.readLine()) != null) {
counter++;
String[] content = null;
try {
content = line.split(",");
if(content.length == 0) {
continue;
}
String word = content[0];
String[] ignore_in_combination_with_words = new String[]{};
if(content.length > 1) {
ignore_in_combination_with_words = content[1].split("_");
}
words.put(word.replaceAll(" ", ""), ignore_in_combination_with_words);
} catch(Exception e) {
e.printStackTrace();
}
}
System.out.println("Loaded " + counter + " words to filter out");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Iterates over a String input and checks whether a cuss word was found in a list, then checks if the word should be ignored (e.g. bass contains the word *ss).
* #param input
* #return
*/
public static ArrayList<String> badWordsFound(String input) {
if(input == null) {
return new ArrayList<>();
}
// remove leetspeak
input = input.replaceAll("1","i");
input = input.replaceAll("!","i");
input = input.replaceAll("3","e");
input = input.replaceAll("4","a");
input = input.replaceAll("#","a");
input = input.replaceAll("5","s");
input = input.replaceAll("7","t");
input = input.replaceAll("0","o");
ArrayList<String> badWords = new ArrayList<>();
input = input.toLowerCase().replaceAll("[^a-zA-Z]", "");
for(int i = 0; i < input.length(); i++) {
for(int fromIOffset = 1; fromIOffset < (input.length()+1 - i); fromIOffset++) {
String wordToCheck = input.substring(i, i + fromIOffset);
if(words.containsKey(wordToCheck)) {
// for example, if you want to say the word bass, that should be possible.
String[] ignoreCheck = words.get(wordToCheck);
boolean ignore = false;
for(int s = 0; s < ignoreCheck.length; s++ ) {
if(input.contains(ignoreCheck[s])) {
ignore = true;
break;
}
}
if(!ignore) {
badWords.add(wordToCheck);
}
}
}
}
for(String s: badWords) {
Server.getSlackManager().queue(s + " qualified as a bad word in a username");
}
return badWords;
}
I was wondering if someone could provide me some code or point me towards a tutrial which explain how I can convert my string so that each word begins with a capital.
I would also like to convert a different string in italics.
Basically, what my app is doing is getting data from several EditText boxes and then on a button click is being pushed onto the next page via intent and being concatenated into 1 paragraph. Therefore, I assume I need to edit my string on the intial page and make sure it is passed through in the same format.
Thanks in advance
You can use Apache StringUtils. The capitalize method will do the work.
For eg:
WordUtils.capitalize("i am FINE") = "I Am FINE"
or
WordUtils.capitalizeFully("i am FINE") = "I Am Fine"
Here is a simple function
public static String capEachWord(String source){
String result = "";
String[] splitString = source.split(" ");
for(String target : splitString){
result
+= Character.toUpperCase(target.charAt(0))
+ target.substring(1) + " ";
}
return result.trim();
}
The easiest way to do this is using simple Java built-in functions.
Try something like the following (method names may not be exactly right, doing it off the top of my head):
String label = Capitalize("this is my test string");
public String Capitalize(String testString)
{
String[] brokenString = testString.split(" ");
String newString = "";
for(String s : brokenString)
{
s.charAt(0) = s.charAt(0).toUpper();
newString += s + " ";
}
return newString;
}
Give this a try, let me know if it works for you.
Just add android:inputType="textCapWords" to your EditText in layout xml. This wll make all the words start with the Caps letter.
Strings are immutable in Java, and String.charAt returns a value, not a reference that you can set (like in C++). Pheonixblade9's will not compile. This does what Pheonixblade9 suggests, except it compiles.
public String capitalize(String testString) {
String[] brokenString = testString.split(" ");
String newString = "";
for (String s : brokenString) {
char[] chars = s.toCharArray();
chars[0] = Character.toUpperCase(chars[0]);
newString = newString + new String(chars) + " ";
}
//the trim removes trailing whitespace
return newString.trim();
}
String source = "hello good old world";
StringBuilder res = new StringBuilder();
String[] strArr = source.split(" ");
for (String str : strArr) {
char[] stringArray = str.trim().toCharArray();
stringArray[0] = Character.toUpperCase(stringArray[0]);
str = new String(stringArray);
res.append(str).append(" ");
}
System.out.print("Result: " + res.toString().trim());