I am writing a Java program that can convert an inputted Roman Numeral into a Short, and I want it to be able to recognize and ask for input again when any letter has been inputted besides a Roman Numeral (I, V, X, L, C, D, and M).
Is there a method similar to .contains(), but with the opposite function?
Or do I have to check each individual letter with some kind of loop?
Well of course, you need some type of filter to test against the input.
One solution could be to use a string that contains all the possible valid characters in the input and then return false if a character wasn't found in the filter.
public class HelloWorld
{
public static boolean filter(String test, String filter) {
for(int i = 0; i < test.length(); i++) {
if (filter.indexOf(test.charAt(i)) == -1) {
return false;
}
}
return true;
}
// arguments are passed using the text field below this editor
public static void main(String[] args)
{
System.out.println(filter("XDQX", "XDQ"));
}
}
I suggest you use a regular expression to check whether the input is a Roman numeral. You can find a regular expression for this problem here. Use String#matches() to determine whether your input matches the regex.
if(!input.matches("^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$")) { // input is the String the user entered
// handle invalid input here
}
Just testing for valid characters, not for a valid sequence, can be done with contains:
boolean roman (String s)
{
for (char c: s.toCharArray())
if (! "IVXCLDM".contains(""+c))
return false;
return true;
}
However, I would prefer a regular expression
boolean roman (String s)
{
return s.matches ("[IVXCLDM]+");
}
which means any number(+) of characters from that Set, at least one.
Related
I need to create a recursive method that takes a String parameter.
I need to verify that the first letter in the string is a lowercase character, and then verify that everything that comes after the first letter is a number.
So it should be like this a1234.
I've tried creating a base case, smaller base case, and a general case, but can't seem to figure out the right way to style it:
public void digitCheck(String s) {
if () //To Check that first character is a letter
else if ()To check that everything after the first letter is a number
else //Invalid
}
I need the code to report whether it's a valid string if the first character is a lower case letter and everything after that is a number.
Example:
a123 -> valid.
ab123 -> invalid.
Use the String.matches() method:
boolean valid = s.matches(".\\d+");
For solving this problem with recursion for your pattern you can do:
start from the end and
check the last element
remove the last element
call all remaining part
It should be checking until one element will be passed to the method -> make final validation if it is a lower letter.
Also, StringUtils class is used from commons lang library.
Here is code snippet:
public class StringValidationDemo {
public boolean validateStringRecursive(String str) {
if (str.length() == 1) {
return StringUtils.isAlpha(str) && StringUtils.isAllLowerCase(str);
}
String lastIndex = str.substring(str.length() - 1);
return StringUtils.isNumeric(lastIndex)
&& validateStringRecursive(str.substring(0, str.length() - 1));
}
public static void main(String[] args) {
List<String> words = Arrays.asList("a123", "ab123", "123ab", "A123", "aaa", "123");
StringValidationDemo demo = new StringValidationDemo();
for (String word : words) {
System.out.printf("validation for: %s = %s\n",
word, demo.validateStringRecursive(word));
}
}
}
Output:
validation for: a123 = true
validation for: ab123 = false
validation for: 123ab = false
validation for: A123 = false
validation for: aaa = false
validation for: 123 = false
I think you could ommit the first character in the string, and then just check with Integer.parseInt(String). so it would look something like:
public static boolean isNumeric(String strNum) {
try {
double d = Integer.parseInt(String);
} catch (NumberFormatException | NullPointerException nfe) {
return false;
}
return true;
}
public void DoStuff(String string){
if (isNumeratic(string.substring(1)) //ommits first
{
///yourstuff
}
}
I am creating an Android application where I have a string. I want to check whether this string contains at least one character that belongs to Hindi language or not.
It does not matter in which language the String is, but if it has atleast one character that is in Hindi language, my function needs to be called.
One of the ways of doing so is comparing each character of the string with all the unicodes of Hindi language. But wont that be too time consuming? For example 50 character of string and 50 unicode will end up with 2500 comparisons already.
What can be the most optimum solution to this?
I think of these two methods
Method 1
boolean isHindi = false;
for (char c: myString.toCharArray()) {
if (Character.UnicodeBlock.of(c) == Character.UnicodeBlock.DEVANAGARI) {
isHindi = true;
break;
}
}
Method 2
boolean isHindi = false;
for (int k = 0; k < Character.codePointCount(myString, 0, myString.length()); k++) {
int c = myString.codePointAt(k);
if (c >= 0x0900 && c <= 0x097F) { //Hindi uni-codes are within this range
isHindi = true;
break;
}
}
If you are using java-8, you could do:
boolean isHindi =
myString.chars().anyMatch(c -> Character.UnicodeBlock.of(c) == Character.UnicodeBlock.DEVANAGARI);
You can also do regex matching. Here is a sample code
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HindiDetctionDemo {
public static void main(String args[]) {
Pattern hindiFirstCharMatchPattern = Pattern.compile("[\\u0900-\\u097F].*");
Matcher hindiFirstCharMatcher = hindiFirstCharMatchPattern.matcher("ok ");
if(hindiFirstCharMatcher.matches()) {
System.out.println("found");
} else {
System.out.println("could not find.");
}
}
}
Note about regex
[\u0900-\u097F] is matcher for hindi characters.
.* is appended so that matching stops after first match.
I want to create a boolean method that allows me to check if the characters in one string randomly generated in a method before contains characters from a string that the user inputs.
Example:
Random base word: Cellphone
User word: Cell --> Yes this is okay.
User word: Cells --> No, it contains letters not found in original word given.
I'm thinking we can maybe do something that looks like this:
public static class boolean usesSymbolsFromWord(String candidate, String base) {
//pseudocode
characters in String candidate are found in String base
return true;
}
return false;
}
Just try it with a build in method of Java.lang.String:
base.contains(candidate);
That's all.
For further informations see the Java Docs:
contains(CharSequence s)
Returns true if and only if this string
contains the specified sequence of char values.
try this func
boolean allS1CharsAreInS2(String s1, String s2) {
for(int i = 0; i < s1.length(); i++) {
char c = s1.charAt(i);
if (s2.indexOf(c) == -1) {
return false;
}
}
return true;
}
I normally use : word1.toUpperCase().contains(word2.toUpperCase()) as I prefer case insensitive check. But its based on your requirement. If it has to be case sensitive checking, you can use word1.contains(word2)
I am attempting to create a method that checks every character in userInput to see if they are present in operatorsAndOperands. The issue is that tempbool is always false for all values.
import java.util.*;
public class stringCalculator
{
private String userInput = null;
String[] operatorsAndOperands = {"1","2","3","4","5","6","7","8","9","0","+","-","*","/"};
public stringCalculator(String newInput)
{
userInput = newInput;
}
public boolean checkInput()
{
boolean ifExists = true;
for(int i=0; i<userInput.length(); i++)
{
char currentChar = userInput.charAt(i);
boolean tempbool = Arrays.asList(operatorsAndOperands).contains(currentChar);
if (tempbool == false)
{
ifExists = false;
}
}
return ifExists;
}
}
This is because you have an array of string objects (which you later convert to a list of string objects), but you are checking a char for presence in that array.
Efficiency is also pretty poor here - converting a fixed array to a list on each iteration takes a lot of unnecessary CPU cycles.
A simple solution to this problem is to put all characters in a string, and then check each incoming character against that string:
if ("0123456789+-*/".indexOf(currentChar) >= 0) {
... // Good character
}
Another solution would be making a regex that allows only your characters to be specified, like this:
if (expr.replaceAll("[0-9+/*-]*", "").length() == 0) {
... // Expr contains only valid characters
}
Why don't you declare
String[] operatorsAndOperands = {"1","2","3","4","5","6","7","8","9","0","+","-","*","/"};
as a String, instead of an array of String. Then you can just use the contains method to check the characters against the valid operators.
Declare: char[] operatorsAndOperands; instead of: String[] operatorsAndOperands.
Or add this: String.valueOf(charToCompare) as the "contains" argument.
As has been pointed out, the issue is that you're checking for a char in a list of String objects, so you'll never find it.
You can make this check easier, though, by using a regular expression:
Pattern operatorsAndOperands = Pattern.compile("[0-9+\\-*/]");
Let's say I have this string: "abcd123fx".
Now, I want to make a method which checks (in order) if "a","b","c","d" etc is a number and if not, returns false. I don't know how to handle the n-th position of char and for each char, in order.
You can check if a character is a letter of number with teh Character class.
String text = ...
char ch = texct.charAt(nth);
if (Character.isLetter(ch)) {
// is a letter
} else if (Character.isDigit(ch)) {
// is a digit
}
Note: these method support characters in different blocks of the unicode. e.g. it will accept characters in Arabic or Korean.
Check the documentation. You can use charAt function.
if (Character.isLetter(yourString.charAt(index)))
// ... Letter
if (Character.isDigit(yourString.charAt(index)))
// ... Number
Check this page
Well there are a few ways you could do this. The simplest would probably be something along the lines of:
Character.isDigit(someString.charAt(x))
or a regex way would be someString.substring(x,x).matches("[0-9]")
To get the nth character of a string you should use charAt, the you should use the Charachter's isLetterOrDigit.
Usually, when you face these problems, you should search the javadoc looking for suitable methods.
Check out the Java tutorials on oracle.com for more information.
Specifically for this subject:
Characters, specifically the Character.isLetter(char ch) and Character.isDigit(char ch) methods
Strings and Manipulating Characters in a String, the simplest method is String.charAt(int index)
- As you have said that you are a newbie, i won't make this complicated using Regex, but will use inbuilt Java functionalities to answer this.
- First use subString() method to get the "abcd" part of the String, then use toCharArray() method to break the String into char elements, then use Character class's isDigit() method to know whether its a digit or not.
Eg:
public class T1 {
public static void main(String[] args){
String s = "abcd123fx";
String str = s.substring(0,4);
System.out.println(str);
char[] cArr = str.toCharArray();
for(char a :cArr){
if(Character.isDigit(a)){
System.out.println(a+" is a digit");
}else{
System.out.println(a+" is not a digit");
}
}
}
}
This might help you
public static boolean isNumeric(String str) {
return str.matches("-?\\d+(.\\d+)?");
}
public static void main(String[] args){
System.out.println(isNumeric("abcd123fx"));
}
If you have a numeric string it will return true else false
public static void main(String[] args){
System.out.println(checkNumber("123a44"));
}
public static boolean checkNumber(String s){
for(int i = 0; i < s.length(); i++){
if(Character.isDigit(s.charAt(i))){
continue;
}
else{
return false;
}
}
return true;
}
You can also have a look into the ASCII table
Depending on this you can write a method:
private boolean isNumber(char a) {
int i = a;
if(i >= 48 && i <=57)
return true;
else
return false;
}
// now you can look by a String
private void checkString() {
String x = "abcd123fx ";
for(char counter : x.toCharArray())
System.out.println(isNumber(counter));
}