Input Validation Loop - java

So my program allows a user to input a string then remove all occurrences of a character. If the character doesn't exist in the string then it should print an error message. Right now, I've created a loop to check each character in the string to create the new string without the character. I'm not sure how to create an input validation loop without printing an error message for each character that doesn't match the character the user wants to remove. I hope this makes sense!
Here is a portion of my code:
//REMOVE LOOP
System.out.println("Enter the character to remove");
String oldChar = keyboard.nextLine();
while ( indexEnd <= string.length() ) {
String substring = string.substring(indexStart, indexEnd);
indexStart++;
indexEnd++;
}
while ( substring.equals(oldChar) ) {
substring = string.substring(0, indexStart-1);
string = substring + string.substring(indexEnd - 1);
indexStart=0;
indexend=1;
}
}

Add a guard clause (a check) at the beginning.
It's best to avoid while loops and write something more readable.
public String removeCharacter(String text, String character) {
if(!text.contains(character)) {
throw new IllegalArgumentException("Character " + character + " not found in text " + text);
} else {
return text.replace(character, "");
}
}

Although Swifter's answer is great and more readable, here's another alternative:
Since we're just removing characters, we know that the character wasn't found if the resulting length stays the same.
public String remove(String text, String character) {
// save the original length because we are going to use it later
var origLength = text.length();
text = text.replace(character, "");
// check new length against original length
// - if they are the same, then 'character' wasn't found
if(origLength == text.length()) {
throw new IllegalArgumentException("Character " + character + " not found.");
}
return text;
}
Technically this is more performant since there's just one pass through the string (although in reality this is negligible).

Related

How many times the word is used on the html page

I have a method that should return an integer which is the number of uses of the searchWord in the text of an HTML document:
public int searchForWord(String searchWord) {
int count = 0;
if(this.htmlDocument == null){
System.out.println("ERROR! Call crawl() before performing analysis on the document");
}
System.out.println("Searching for the word " + searchWord + "...");
String bodyText = this.htmlDocument.body().text();
if (bodyText.toLowerCase().contains(searchWord.toLowerCase())){
count++;
}
return count;
}
But my method always returns count=1, even if the word is used several times. I understand that the error should be obvious, but I’m stuck and I don’t see it.
You are currently only checking once that the text contains the search word, so the count will always be either 0 or 1. To find the total count, keep looping using String#indexOf(str, fromIndex) while the String can be found using the second argument that indicates the index to start searching from.
public int searchForWord(String searchWord) {
int count = 0;
if(this.htmlDocument == null){
System.out.println("ERROR! Call crawl() before performing analysis on the document");
}
System.out.println("Searching for the word " + searchWord + "...");
String bodyText = this.htmlDocument.body().text();
for(int idx = -1; (idx = bodyText.indexOf(searchWord, idx + 1)) != -1; count++);
return count;
}
According to the Java docs String#contains:
Returns true if and only if this string contains the specified sequence of char values.
You're asking if the word you're looking for is contained in the document, which it is.
You could:
Split the text on words (splitting it by spaces) and then count how many times it appears
Iterate the String using String#indexOf starting on index 0 and then from last index you found until the end of the String.
Iterate the String using contains but starting from a certain index (doing this logic yourself).
I'd go for the 2nd approach as it seems like the easiest one.
These are only conditional statements, you aren't looping through the HTML text, therefor, if it finds the instance of searchWord in bodyText, it'll increment it, and then exit the method with a value of 1. I suggest looping through every word in the html, adding it to an array, and counting it that way using something like this:
char[] bodyTextA = bodyText.toCharArray();
Or keep it in a string array and split it by a space, or new line, or whatever criteria you have. Example of space:
//puts hello, i'm, your, and string into their own array slots in the array
/split
str = "Hello I'm your String";
String[] split = str.split("\\s+");
Your issue here is that the if statement is checking if the text contains the word and the increments your count variable. So even if it contains the word multiple time, your logic goes basically, if it contains it at all, increase count by one. You will have to rewrite your code to check for multiple occurrences of the word. There are many ways you can go about this, you could loop through the entire body text, you could split the body text into an array of words and check that, or you could remove the search word from the text each time you find it and keep checking until it no longer contains the search word.
You can use indexOf(,) with an index for the last found word
public int searchForWord(String searchWord) {
int count = 0;
if(this.htmlDocument == null){
System.out.println("ERROR! Call crawl() before performing analysis on the document");
}
System.out.println("Searching for the word " + searchWord + "...");
String bodyText = this.htmlDocument.body().text();
int index = 0;
while ((index = bodyText.indexOf(searchWord, index + 1)) != -1) {
count++;
}
return count;
}

match exact the same words between 2 strings

I would like to compare and match exactly one word (characters and length) between two strings.
This is what I have:
String wordCompare = "eagle:1,3:7;6\nBasils,45673:ewwsk\nlola:flower:1:2:b";
String lolo = scanner.nextLine();
if ( motCompare.toLowerCase().indexOf(lolo.toLowerCase()) != -1 ) {
System.out.println("Bingo !!!");
} else {
System.out.println("not found !!!");
}
If I type eagle:1,3:7;6 it should display Bingo !!!
If I type eagle:1,3 it still displays Bingo !!! which is wrong, it should display Not found.
If I type eagle:1,3:7;6 Basils,45673:ewwsk or eagle:1,3:7;6\nBasils,45673:ewwsk it should also display Not Found. Length of the typed word should be acknowledged between \n.
If I type Basils,45673:ewwsk, it displays bingo !!!
It looks like what you're wanting is an exact match, with the words being split by the newline character. With that assumption in mind, I would recommend splitting the string out into an array and then loading that into a HashSet like so:
boolean search(String wordDictionary, String search){
String[] options = wordDictionary.split("\n");
HashSet<String> searchSet = new HashSet<String>(Arrays.asList(options));
return searchSet.contains(search);
}
If the search function returns true, it has found whatever word you're searching for, if not, it hasn't.
Installing it in your code will look something like this:
String wordCompare = "eagle:1,3:7;6\nBasils,45673:ewwsk\nlola:flower:1:2:b";
String lolo = scanner.nextLine();
if(search(wordCompare, lolo))
System.out.println("Bingo!!!");
else
System.out.println("Not found.");
(For the record, you'd probably be better off with more clear variable names)
As #Grey has already mentioned within his answer, since you have a newline tag (\n) between your phrases you can Split the String using the String.split() method into a String Array and then compare the elements of that Array for equality with what the User supplies.
The code below is just another example of how this can be done. It also allows for the option to Ignore Letter case:
boolean ignoreCase = false;
String userString = "Basils,45673:ewwsk";
String isInString = "'" + userString + "' Was Not Found !!!";
String wordCompare = "eagle:1,3:7;6\nBasils,45673:ewwsk\nlola:flower:1:2:b";
String[] tmp = wordCompare.split("\n");
for (int i = 0; i < tmp.length; i++) {
// Ternary used for whether or not to ignore letter case.
if (!ignoreCase ? tmp[i].trim().equals(userString) :
tmp[i].trim().equalsIgnoreCase(userString)) {
isInString = "Bingo !!!";
break;
}
}
System.out.println(isInString);
Thank you,
The thing is I am not allowed to use regular expression nor tables.
so basing on your suggestions I made this code :
motCompare.toLowerCase().indexOf(lolo.toLowerCase(), ' ' ) != -1 ||
motCompare.toLowerCase().lastIndexOf(lolo.toLowerCase(),' ' ) != -1)
as a condition for a do while loop.
Could you please confirm if it is correct ?
Thank you.

Java: Removing duplicate words & substrings of words in java

Recently i have come up against a question which i am not able to tackle in school.
I need to remove duplicate words in an input string which consists of words. The main issue here is that the requirement states that i cannot use arrays or regular expressions.
E.g.
userInput = "this is a test testing is fun really fun"
the first "is" is a duplicate of "this" as it is a substring
the second "is" is a duplicate of the first "is"
"testing" is not a duplicate of "test" as it is not an exact match
therefore the output comes out as - "this a test testing fun really"
How would one actually achieve this without using Arrays or Regular Expressions as it is impossible to split the words up by the white spaces and dynamically create a String in java.
I didn't compile this code, but I think it should works.
Let me know if it can help you to solved your problem.
public String solve(String input) {
String ret = "";
int pos = 0;
while(pos<input.length()) {
// find next position of space
int next = input.indexOf(' ',pos);
// space not exists, skip next to end of string
if(next==-1) next = input.length();
// take 1 word from input
String word = input.substring(pos,next);
// check if word exists in previous result
if(ret.indexOf(word)==-1) {
if(ret.length() > 0) ret += " ";
// append word to ret
ret += word;
}
pos = next + 1;
}
return ret;
}

Using regex to add a new line to a string every time each line reaches a certain length

I'm trying to ensure text does not appear outside of the window as the window size cannot be changed.
The image above shows what happens when the string of the order numbers exceeds the length of the window. I'm trying to ensure that when the length of the string of order numbers reaches a certain length, I use regex to make a new line for the next orders.
private String listOfOrders( Map<String, List<Integer> > map, String key )
{
String res = "";
if ( map.containsKey( key ))
{
List<Integer> orders = map.get(key);
for ( Integer i : orders )
{
res += " " + i + ",";
}
} else {
res = "-No key-";
}
return res;
}
}
This is the code to display the text, it works by forming the string res and filling it with the order numbers from the array list.
I found, through researching, a cool little piece of code which replaces a string every set amount of characters with itself plus a new line.
if(res.length() >= W-10)
{
res = res.replaceAll("(.{20})", "$1\n");
}
else
{
res += " " + i + ",";
}
But this has no effect at all. And I also realised that this code can not tell how long each line is because I'm using length to determine the length of each line and not how long each line is between each "\n".
My question is, how do I go about using regex to ensure each line in the string is a certain number of characters long? As my attempt does not work. The above just provides context as to why I want lines in a string a certain legnth.
Thanks!

java: code keeps looping

The below code is giving me a headache: It's supposed to jump out of the do--while loop after replacing all \n's, but it doesn't. Any ideas how to solve this?
public String invoerenTemplate(){
String templateGescheiden = null;
String teHerkennenTemplate = Input.readLine();
String uitvoer = teHerkennenTemplate;
do {
templateGescheiden = teHerkennenTemplate.substring(0, teHerkennenTemplate.indexOf(" "));
templateGescheiden += " ";
if (templateGescheiden.charAt(0) == '\\' && templateGescheiden.charAt(1) == 'n') {
teHerkennenTemplate = teHerkennenTemplate.replace(templateGescheiden, "\n");
uitvoer = uitvoer.replace(templateGescheiden, "\n");
}
teHerkennenTemplate = teHerkennenTemplate.substring(teHerkennenTemplate.indexOf(" "));
System.out.println(uitvoer);
} while (teHerkennenTemplate.length() > 0);
return uitvoer;
}
EDIT:
I now placed this line: teHerkennenTemplate.trim(); just beneath my if-statement, but now it gives me a StringIndexOutOfRange: 0 error at my first line of my if-statement
I have noticed a couple of problems with the above code, although it is difficult to tell why you are taking the approach that you are to the solution.
The main thing I noticed is that your replace statements do NOT remove the \n characters
teHerkennenTemplate = teHerkennenTemplate.replace(templateGescheiden, "\n");
uitvoer = uitvoer.replace(templateGescheiden, "\n");
From Java Documentation:
replace(char oldChar, char newChar):
Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.
So, you are replacing your string templateGescheiden with \n each time you loop.
Another issue would be the improper shortening of your teHerkennenTemplate string each loop, which is causing it not to terminate correctly. It will always shorten from the next space character to the end of the string (inclusive) - meaning it will never be an empty string, but will always have a " ".
My advice would be to debug and go step-by-step to see where the shortening and string manipulation is not doing what you want, then evaluate why and modify the code appropriately
There's a variety of things wrong with the code:
the index of a carriage return is found in the string with indexOf("\n").
the substring of teHerkennenTemplate isn't taking into account that it starts with a space, which cause the loop to continue forever.
The simplest way to do what you want is with a regular expression:
"test \n test \n".replaceAll("\n", "")
Will return:
"test test "
If you're set on using a loop then this will do the same:
public static String invoerenTemplate(String teHerkennenTemplate)
{
StringBuilder result = new StringBuilder();
while (teHerkennenTemplate.length() > 0)
{
int index = teHerkennenTemplate.indexOf("\n");
result.append(index > -1 ? teHerkennenTemplate.substring(0, index) : teHerkennenTemplate);
teHerkennenTemplate = teHerkennenTemplate.substring(index + 1, teHerkennenTemplate.length());
}
return result.toString();
}

Categories