I want to write a static method that is passed a string and that checks to see if the string is made up of just letters and spaces. I can use String's methods length() and charAt(i) as needed..
I was thinking something like the following: (Sorry about the pseudocode)
public static boolean onlyLettersSpaces(String s){
for(i=0;i<s.length();i++){
if (s.charAt(i) != a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) {
return false;
break;
}else {
return true;
}
}
I know there is probably an error in my coding, and there is probably a much easier way to do it, but please let me know your suggestions!
use a regex. This one only matches if it starts with, contains, and ends with only letters and spaces.
^[ A-Za-z]+$
In Java, initialize this as a pattern and check if it matches your strings.
Pattern p = Pattern.compile("^[ A-Za-z]+$");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
That isn't how you test character equality, one easy fix would be
public static boolean onlyLettersSpaces(String s){
for(i=0;i<s.length();i++){
char ch = s.charAt(i);
if (Character.isLetter(ch) || ch == ' ') {
continue;
}
return false;
}
return true;
}
For the constraints your mentioned (use of only length() and charAt()), you got it almost right.
You do loop over each character and check if its one of the acceptable characters - thats the right way. If you find a non-acceptable character, you immediately return "false", thats also good. Whats wrong is that if you determined to accept the character, you do return true. But the definition says only to return true if all characters are accepted. You need to move the "return true" to after the loop (thats the point at which you will know that all characters were accepted)
So you change your pseudocode to:
for (all characters in string) {
if (character is bad) {
// one bad character means reject the string, we're done.
return false;
}
}
// we now know all chars are good
return true;
Related
public static boolean Xish
This method should take in two parameters, in the following order: A String of the word to check and a String made up of the letters to check for. For example, a word is considered elf-ish, if it contains the letters e, l, and f, in any order (“waffle”, “rainleaf”) and a true return of the method would be Xish(“waffle”, ”elf”). If there are multiple occurrences of a letter to check for, it must occur multiple times in the search word. Return true if the word contains all the needed characters and false if it does not contain all the characters.
This is what I have so far, but I am lost how I would recall the method and check to see if there are multiple occurrences (2nd part).
public static boolean Xish(String check, String letters) {
String word = check;
String contains= letters;
if(word.indexOf(contains) >= 0)
return true;
else
return false;
}
Actually, doing this recursively will also take care of the multiple occurrences issue.
First, your own method is not really correct - it looks for the whole letters in the word. That is, if letters is elf, then true will be returned for self, but not for heartfelt, and that's wrong. You are supposed to look for the individual letters, because the order is not important.
For recursion:
If the letters is an empty string - return true. You can say that any word is fine if there are no restrictions.
If the check is an empty string - return false. An empty string does not contain the letters in letters (and we already know that letters is not empty).
Take the first letter in letters. Look for it in check. If it's not there, return false.
If it was there, then call the same method, but pass only what remains of check and letters. For example, if check was selfish and letters was elf, you found that e exists. Return the result of Xish("slfish","lf"). This will take care of the multiple occurrences. You do that by using substring and concatenating the applicable parts.
If multiple occurrences weren't an issue, you could pass the check as-is to the next level of the recursion. But since they matter, we need to remove one letter for each letter requested, to make sure that we don't match the same position again for the next occurrenc.
The title mentions a recursive function so I will propose a recursive solution.
For each character in your check string, compare it against the first character in your letters string.
If the compared characters are equivalent, remove the first character from your letters string and pass both strings back into your function.
If the check string is fully iterated without finding a character in the letters string, return false
If letters is empty at any point, return true
This is a brute force approach, and there are several other ways to accomplish what you are looking for. Maybe think about how you could check every character in your in you check string a single time?
public static boolean Xish(String check, String letters) {
boolean ish = true;
String word = check;
char[] contains= letters.toCharArray();
for(int i = 0; i < contains.length; i++){
if(word.indexOf(contains[i]) < 0){
ish = false;
}else {
StringBuilder sb = new StringBuilder(word);
sb.deleteCharAt(word.indexOf(contains[i]));
word = sb.toString();
// System.out.println(word);
}
}
return ish;
}
This could be one way, but it is not recursive.
Xish("Waffle", "elff") returns true, but
Xish("Waffle", "elfff") returns false.
Not sure whether it solves your question 100 %. But i tried a recursive method. See if this helps.
package com.company;
public class Selfish {
public static void main(String args[]) {
String check = "waffle";
String letters = "elf"; // "eof"
int xishCount = xish(check, letters, 0);
if(letters.length()== xishCount) {
System.out.println("TRUE");
}else{
System.out.println("FALSE");
}
}
static int xish(String check, String letters, int xishCount) {
if(letters.length() < 1) {
return 0;
}
if(check.contains(letters.substring(0, 1))) {
xishCount = 1;
}
return xishCount + xish(check, letters.substring(1, letters.length()), 0);
}
}
What im trying to do is reject any string that contains characters outside a-z, 0-9 or _
I tried using the match function below as id seen elsewhere but i cant get it to work correctly. It will either tell me the string is fine when its not, or it will tell me its not fine when it is.
public static Boolean checkc(String word) {
String w = word;
for (int i = 0; i < w.length(); i++) {
if (w.substring(i, i).matches("[A-Za-z0-9_]")) {
return true;
}
}
return false;
}
The logic might be wrong now because I've fiddled with it trying to get it working but to be fair, it wasnt working in the first place. Im checking a few things in the function thats calling this, so i just need to know if it string is fine given the rules.
The end index argument to substring is exclusive, so substring(i, i) always returns a 0 length string. You could fix this by using substring(i, i+1), but there's no reason to use a loop here. You can just use word.matches("[A-Za-z0-9_]+") and check the entire string at once. The regex quantifier + means "one or more". You could also use the quantifier * which means "zero or more", if the method should return true if the string is empty.
Edit: There's also another problem with your loop logic that I just noticed. Your conditional in the loop returns true the first time the condition is met:
for (...) {
if ( /* condition is met */ )
return true;
}
return false;
That logic only requires that the condition be met at least once, and then it returns true, but you probably meant the following:
for (...) {
if (! /* condition is met */ )
return false;
}
return true;
That requires that the condition be met for every character.
Try this:
public static boolean check(String word) {
return word.matches("[^a-zA-Z0-9_]+");
}
this method returns true when word string contains no single character described in the square bracket, ^ regex symbol means same as logical ! (in example !true == false). Plus symbol + after square bracket means that one symbol [] could repeat one or more time.
javadoc link to Pattern class (regex explanations and examples)
Regex101 convenient online regex debug tool
stringToCheck.String.matches("[^0-9a-zA-Z_]")
This will check whether string that needs to be matched contains any digits or alphabets and return a boolean value
I have the following characters that I would like to be considered "illegal":
~, #, #, *, +, %, {, }, <, >, [, ], |, “, ”, \, _, ^
I'd like to write a method that inspects a string and determines (true/false) if that string contains these illegals:
public boolean containsIllegals(String toExamine) {
return toExamine.matches("^.*[~##*+%{}<>[]|\"\\_^].*$");
}
However, a simple matches(...) check isn't feasible for this. I need the method to scan every character in the string and make sure it's not one of these characters. Of course, I could do something horrible like:
public boolean containsIllegals(String toExamine) {
for(int i = 0; i < toExamine.length(); i++) {
char c = toExamine.charAt(i);
if(c == '~')
return true;
else if(c == '#')
return true;
// etc...
}
}
Is there a more elegant/efficient way of accomplishing this?
You can make use of Pattern and Matcher class here. You can put all the filtered character in a character class, and use Matcher#find() method to check whether your pattern is available in string or not.
You can do it like this: -
public boolean containsIllegals(String toExamine) {
Pattern pattern = Pattern.compile("[~##*+%{}<>\\[\\]|\"\\_^]");
Matcher matcher = pattern.matcher(toExamine);
return matcher.find();
}
find() method will return true, if the given pattern is found in the string, even once.
Another way that has not yet been pointed out is using String#split(regex). We can split the string on the given pattern, and check the length of the array. If length is 1, then the pattern was not in the string.
public boolean containsIllegals(String toExamine) {
String[] arr = toExamine.split("[~##*+%{}<>\\[\\]|\"\\_^]", 2);
return arr.length > 1;
}
If arr.length > 1, that means the string contained one of the character in the pattern, that is why it was splitted. I have passed limit = 2 as second parameter to split, because we are ok with just single split.
I need the method to scan every character in the string
If you must do it character-by-character, regexp is probably not a good way to go. However, since all characters on your "blacklist" have codes less than 128, you can do it with a small boolean array:
static final boolean blacklist[] = new boolean[128];
static {
// Unassigned elements of the array are set to false
blacklist[(int)'~'] = true;
blacklist[(int)'#'] = true;
blacklist[(int)'#'] = true;
blacklist[(int)'*'] = true;
blacklist[(int)'+'] = true;
...
}
static isBad(char ch) {
return (ch < 128) && blacklist[(int)ch];
}
Use a constant for avoids recompile the regex in every validation.
private static final Pattern INVALID_CHARS_PATTERN =
Pattern.compile("^.*[~##*+%{}<>\\[\\]|\"\\_].*$");
And change your code to:
public boolean containsIllegals(String toExamine) {
return INVALID_CHARS_PATTERN.matcher(toExamine).matches();
}
This is the most efficient way with Regex.
If you can't use a matcher, then you can do something like this, which is cleaner than a bunch of different if statements or a byte array.
for(int i = 0; i < toExamine.length(); i++) {
char c = toExamine.charAt(i);
if("~##*+%{}<>[]|\"_^".contains(c)){
return true;
}
}
Try the negation of a character class containing all the blacklisted characters:
public boolean containsIllegals(String toExamine) {
return toExamine.matches("[^~##*+%{}<>\\[\\]|\"\\_^]*");
}
This will return true if the string contains illegals (your original function seemed to return false in that case).
The caret ^ just to the right of the opening bracket [ negates the character class. Note that in String.matches() you don't need the anchors ^ and $ because it automatically matches the whole string.
A pretty compact way of doing this would be to rely on the String.replaceAll method:
public boolean containsIllegal(final String toExamine) {
return toExamine.length() != toExamine.replaceAll(
"[~##*+%{}<>\\[\\]|\"\\_^]", "").length();
}
I just want to know where am i wrong here:
import java.io.*;
class Tokens{
public static void main(String[] args)
{
//String[] result = "this is a test".split("");
String[] result = "4543 6546 6556".split("");
boolean flag= true;
String num[] = {"0","1","2","3","4","5","6","7","8","9"};
String specialChars[] = {"-","#","#","*"," "};
for (int x=1; x<result.length; x++)
{
for (int y=0; y<num.length; y++)
{
if ((result[x].equals(num[y])))
{
flag = false;
continue;
}
else
{
flag = true;
}
if (flag == true)
break;
}
if (flag == false)
break;
}
System.out.println(flag);
}
}
If this is not homework, is there a reason you're avoiding regular expressions?
Here are some useful ones: http://regexlib.com/DisplayPatterns.aspx?cattabindex=6&categoryId=7
More generally, your code doesn't seem to validate that you have a phone number, it seems to merely validate that your strings consists only of digits. You're also not allowing any special characters right now.
Asides from the regex suggestion (which is a good one), it would seem to make more sense to deal with arrays of characters rather than single-char Strings.
In particular, the split("") call (shudder) could/should be replaced by toCharArray(). This lets you iterate over each individual character, which more clearly indicates your intent, is less prone to bugs as you know you're treating each character at once, and is more efficient*. Likewise your valid character sets should also be characters.
Your logic is pretty strangely expressed; you're not even referencing the specialChars set at all, and the looping logic once you've found a match seems odd. I think this is your bug; the matching seems to be the wrong way round in that if the character matches the first valid char, you set flag to false and continue round the current loop; so it will definitely not match the next valid char and hence you break out of the loop with a true flag. Always.
I would have thought something like this would be more intuitive:
private static final Set<Character> VALID_CHARS = ...;
public boolean isValidPhoneNumber(String number)
{
for (char c : number,toCharArray())
{
if (!VALID_CHARS.contains(c))
{
return false;
}
}
// All characters were valid
return true;
}
This doesn't take sequences into account (e.g. the strings "--------** " and "1" would be valid because all individual characters are valid) but then neither does your original code. A regex is better because it lets you specify the pattern, I supply the above snippet as an example of a clearer way of iterating through the characters.
*Yes, premature optimization is the root of all evil, but when better, cleaner code also happens to be faster that's an extra win for free.
Maybe this is overkill, but with a grammar similar to:
<phone_numer> := <area_code><space>*<local_code><space>*<number> |
<area_code><space>*"-"<space>*<local_code><space>*"-"<space>*<number>
<area_code> := <digit><digit><digit> |
"("<digit><digit><digit>")"
<local_code> := <digit><digit><digit>
<number> := <digit><digit><digit><digit>
you can write a recursive descent parser. See this page for an example.
You can checkout the Pattern class in Java, really easy to work with regular expression using this class:
https://docs.oracle.com/javase/1.5.0/docs/api/java/util/regex/Pattern.html.
In Java is there a way to find out if first character of a string is a number?
One way is
string.startsWith("1")
and do the above all the way till 9, but that seems very inefficient.
Character.isDigit(string.charAt(0))
Note that this will allow any Unicode digit, not just 0-9. You might prefer:
char c = string.charAt(0);
isDigit = (c >= '0' && c <= '9');
Or the slower regex solutions:
s.substring(0, 1).matches("\\d")
// or the equivalent
s.substring(0, 1).matches("[0-9]")
However, with any of these methods, you must first be sure that the string isn't empty. If it is, charAt(0) and substring(0, 1) will throw a StringIndexOutOfBoundsException. startsWith does not have this problem.
To make the entire condition one line and avoid length checks, you can alter the regexes to the following:
s.matches("\\d.*")
// or the equivalent
s.matches("[0-9].*")
If the condition does not appear in a tight loop in your program, the small performance hit for using regular expressions is not likely to be noticeable.
Regular expressions are very strong but expensive tool. It is valid to use them for checking if the first character is a digit but it is not so elegant :) I prefer this way:
public boolean isLeadingDigit(final String value){
final char c = value.charAt(0);
return (c >= '0' && c <= '9');
}
IN KOTLIN :
Suppose that you have a String like this :
private val phoneNumber="9121111111"
At first you should get the first one :
val firstChar=phoneNumber.slice(0..0)
At second you can check the first char that return a Boolean :
firstChar.isInt() // or isFloat()
regular expression starts with number->'^[0-9]'
Pattern pattern = Pattern.compile('^[0-9]');
Matcher matcher = pattern.matcher(String);
if(matcher.find()){
System.out.println("true");
}
I just came across this question and thought on contributing with a solution that does not use regex.
In my case I use a helper method:
public boolean notNumber(String input){
boolean notNumber = false;
try {
// must not start with a number
#SuppressWarnings("unused")
double checker = Double.valueOf(input.substring(0,1));
}
catch (Exception e) {
notNumber = true;
}
return notNumber;
}
Probably an overkill, but I try to avoid regex whenever I can.
To verify only first letter is number or character --
For number
Character.isDigit(str.charAt(0)) --return true
For character
Character.isLetter(str.charAt(0)) --return true