This is the question:
Problem I.
We define the Pestaina strings as follows:
ab is a Pestaina string.
cbac is a Pestaina string.
If S is a Pestaina string, so is SaS.
If U and V are Pestaina strings, so is UbV.
Here a, b, c are constants and S,U,V are variables. In these rules,
the same letter represents the same string. So, if S = ab, rule 3
tells us that abaab is a Pestaina string. In rule 4, U and V represent
Grandpa strings, but they may be different.
Write the method
public static boolean isPestaina(String in)
That returns true if in is a Pestaina string and false otherwise.
And this is what i have so far which only works for the first rule, but the are some cases in which doesnt work for example "abaaab":
public class Main {
private static boolean bool = true;
public static void main(String[] args){
String pestaina = "abaaab";
System.out.println(pestaina+" "+pestainaString(pestaina));
}
public static boolean pestainaString(String p){
if(p == null || p.length() == 0 || p.length() == 3) {
return false;
}
if(p.equals("ab")) {
return true;
}
if(p.startsWith("ab")){
bool = pestainaString(p, 1);
}else{
bool = false;
}
return bool;
}
public static boolean pestainaString(String p, int sign){
String letter;
char concat;
if("".equals(p)){
return false;
}
if(p.length() < 3){
letter = p;
concat = ' ';
p = "";
pestainaString(p);
}else if(p.length() == 3 && (!"ab".equals(p.substring(0, 2)) || p.charAt(2) != 'a')){
letter = p.substring(0, 2);
concat = p.charAt(2);
p = "";
pestainaString(p);
}else{
letter = p.substring(0, 2);
concat = p.charAt(2);
pestainaString(p.substring(3));
}
if(letter.length() == 2 && concat == ' '){
if(!"ab".equals(letter.trim())){
bool = false;
//concat = 'a';
}
}else if((!"ab".equals(letter)) || (concat != 'a')){
bool = false;
}
System.out.println(letter +" " + concat);
return bool;
}
}
Please tell me what i have done wrong.
I found the problem i was calling the wrong method.
You are describing a Context Free Language, which can be described as a Context Free Grammer and parsed with it. The field of parsing these is widely researched and there is a lot of resources for it out there.
The wikipedia page also discusses some algorithms to parse these, specifically - I think you are interested in the Early Parsers
I also believe this "language" can be parsed using a push down automaton (though not 100% sure about it).
public static void main(String[] args) {
// TODO code application logic here
String text = "cbacacbac";
System.out.println("Is \""+ text +"\" a Pestaina string? " + isPestaina(text));
}
public static boolean isPestaina(String in) {
if (in.equals("ab")) {
return true;
}
if (in.equals("cbac")) {
return true;
}
if (in.length() > 3) {
if ((in.startsWith("ab") || in.startsWith("cbac"))
&& (in.endsWith("ab") || in.endsWith("cbac"))) {
return true;
}
}
return false;
}
That was fun.
public boolean isPestaina(String p) {
Set<String> existingPestainas = new HashSet<String>(Arrays.asList(new String[]{"ab", "cbac"}));
boolean isP = false;
int lengthParsed = 0;
do {
if (lengthParsed > 0) {
//just realized there's a touch more to do here for the a/b
//connecting rules...I'll leave it as an excersize for the readers.
if (p.substring(lengthParsed).startsWith("a") ||
p.substring(lengthParsed).startsWith("b")) {
//good connector.
lengthParsed++;
} else {
//bad connector;
return false;
}
}
for (String existingP : existingPestainas) {
if (p.substring(lengthParsed).startsWith(existingP)) {
isP = true;
lengthParsed += existingP.length();
}
}
if (isP) {
System.err.println("Adding pestaina: " + p.substring(0, lengthParsed));
existingPestainas.add(p.substring(0, lengthParsed));
}
} while (isP && p.length() >= lengthParsed + 1);
return isP;
}
Related
I want to write a code to check the existence of given two values in a List.
List<Tag> tags = new ArrayList<>();
The requirement is to return true only if the List tag contains both "start" and "end" values.
My code is like this, but it doesn't cater to the requirement.
public static boolean checkStartAndEndTimeTag(List<Tag> tags) {
boolean isSuccess = false;
int count = 0;
for (Tag tag : tags) {
if (tag.getKey().equals("start") || tag.getKey().equals("end")) {
count++;
if (count == 2)
break;
isSuccess = true;
}
}
return isSuccess;
Can someone help me with to resolve this issue?
This...
if (count == 2)
break;
isSuccess = true;
doesn't make sense. This will set isSuccess even if there is only one match
The long winded approach
Okay, let's assuming for a second that you only care if there is at least one start and one end (discounting duplicates). One approach would be to use to state flags, one for start and one for end. To keep it simple, they would start of as 0 but would only ever be a maximum of 1 (because we don't want duplicates), then you might be able to do something like...
public static boolean checkStartAndEndTimeTag(List<Tag> tags) {
boolean isSuccess = false;
int starts = 0;
int ends = 0;
for (Tag tag : tags) {
if (tag.getKey().equals("start")) {
starts = 1;
} else if (tag.getKey().equals("end")) {
ends = 1;
}
}
isSuccess = (starts + ends) == 2;
return isSuccess;
}
Ok, you don't need isSuccess = (starts + ends) == 2; and could simply return the result of the comparison. You could also break out of the loop if (starts + ends) == 2 and save yourself from unnecessary computation
for (Tag tag : tags) {
if (tag.getKey().equals("start")) {
starts = 1;
} else if (tag.getKey().equals("end")) {
ends = 1;
}
if ((starts + ends) == 2) {
break;
}
}
Using streams...
One approach might be to make use the streams support and simply filter the List and count the results, for example...
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
List<Tag> tags = new ArrayList<Tag>(25);
tags.add(new Tag("begin"));
tags.add(new Tag("front"));
tags.add(new Tag("start"));
tags.add(new Tag("finish"));
tags.add(new Tag("tail"));
tags.add(new Tag("end"));
boolean isSuccessful = tags.stream().filter(tag -> tag.getKey().equals("start") || tag.getKey().equals("end")).count() >= 2;
System.out.println(isSuccessful);
}
public class Tag {
private String key;
public Tag(String key) {
this.key = key;
}
public String getKey() {
return key;
}
}
}
Updated...
Okay, this got complicated fast. Let's assume you don't want to match two start tags, so you MUST have both one end and one start tag
So, using the above, example, we can modify the Tag class to support equals (and by extension hashcode)
public class Tag {
private String key;
public Tag(String key) {
this.key = key;
}
public String getKey() {
return key;
}
#Override
public String toString() {
return getKey();
}
#Override
public int hashCode() {
int hash = 7;
hash = 73 * hash + Objects.hashCode(this.key);
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Tag other = (Tag) obj;
if (!Objects.equals(this.key, other.key)) {
return false;
}
return true;
}
}
Then we can simply use distinct to filter out any duplicates, for example...
boolean isSuccessful = tags
.stream()
.distinct()
.filter(tag -> tag.getKey().equals("start") || tag.getKey().equals("end"))
.count() >= 2;
Probably not the most efficient solution, but certainly one of the shortest
In this code
if (tag.getKey().equals("start") || tag.getKey().equals("end")) {
count++;
if (count == 2)
break;
isSuccess = true;
}
you are setting isSuccess to true whenever the tag is start or end.
Better way would be
if (tag.getKey().equals("start") || tag.getKey().equals("end")) {
count++;
if (count == 2)
return true;
}
You could also use
tags.stream()
.map(Tag::getKey)
.distinct()
.filter(t -> "start".equals(t) || "end".equals(t))
.count() == 2;
This would also fix the issue that your original code falsely returns true if the list contains statt or end twice.
What about
tags.containsAll(Arrays.asList(new Tag("start"), new Tag("stop")))
I'm trying to verify if a String s match/is a real number. For that I created this method:
public static boolean Real(String s, int i) {
boolean resp = false;
//
if ( i == s.length() ) {
resp = true;
} else if ( s.charAt(i) >= '0' && s.charAt(i) <= '9' ) {
resp = Real(s, i + 1);
} else {
resp = false;
}
return resp;
}
public static boolean isReal(String s) {
return Real(s, 0);
}
But obviously it works only for round numbers. Can anybody give me a tip on how to do this?
P.S: I can only use s.charAt(int) e length() Java functions.
You could try doing something like this. Added recursive solution as well.
public static void main(String[] args) {
System.out.println(isReal("123.12"));
}
public static boolean isReal(String string) {
boolean delimiterMatched = false;
char delimiter = '.';
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
if (!(c >= '0' && c <= '9' || c == delimiter)) {
// contains not number
return false;
}
if (c == delimiter) {
// delimiter matched twice
if (delimiterMatched) {
return false;
}
delimiterMatched = true;
}
}
// if matched delimiter once return true
return delimiterMatched;
}
Recursive solution
public static boolean isRealRecursive(String string) {
return isRealRecursive(string, 0, false);
}
private static boolean isRealRecursive(String string, int position, boolean delimiterMatched) {
char delimiter = '.';
if (position == string.length()) {
return delimiterMatched;
}
char c = string.charAt(position);
if (!(c >= '0' && c <= '9' || c == delimiter)) {
// contains not number
return false;
}
if (c == delimiter) {
// delimiter matched twice
if (delimiterMatched) {
return false;
}
delimiterMatched = true;
}
return isRealRecursive(string, position+1, delimiterMatched);
}
You need to use Regex. The regex to verify that whether a string holds a float number is:
^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$
Can anybody give me a tip on how to do this?
Starting with your existing recursive matcher for whole numbers, modify it and use it in another method to match the whole numbers in:
["+"|"-"]<whole-number>["."[<whole-number>]]
Hint: you will most likely need to change the existing method to return the index of that last character matched rather than just true / false. Think of the best way to encode "no match" in an integer result.
public static boolean isReal(String str) {
boolean real = true;
boolean sawDot = false;
char c;
for(int i = str.length() - 1; 0 <= i && real; i --) {
c = str.charAt(i);
if('-' == c || '+' == c) {
if(0 != i) {
real = false;
}
} else if('.' == c) {
if(!sawDot)
sawDot = true;
else
real = false;
} else {
if('0' > c || '9' < c)
real = false;
}
}
return real;
}
I'm trying to write a recursive method that checks if all string A unique chars are a subset of string B.
Examples:
String A = "a"
isTrans(A,"a") == true
isTrans(A,"aa") == true
isTrans(A,"aaa") == true
isTrans(A,"aab") == false
String A = "acd"
isTrans(A,"addbc") == false
isTrans(A,"aacdd") == true
isTrans(A,"acccd") == true
isTrans(A,"aaaccdd") == true
That's my code:
public static boolean isTrans(String s,String t)
{
boolean isT=false;
if(t.length()>1)
{
if(s.substring(0,1).equals(t.substring(0,1))&&(t.substring(0,1)!=t.substring(1,2)))
{
return isTrans(s.substring(1,s.length()),t.substring(1,t.length()));
}
if((s.substring(0,1)).equals(t.substring(0,1))&&((t.substring(0,1)).equals(t.substring(1,2))))
{
return isTrans(s,t.substring(1,t.length()));
}
}
else
{
isT =(s.substring(0,1).equals(t.substring(0,1)))?true:false;
}
return isT;
}
You need to correct
t.substring(0,1)!=t.substring(1,2)
The == and != operators don't work on strings the same way they do on primitive types.
You could replace it with something like
!t.substring(0,1).equals(t.substring(1,2))
But a better approach would be to check characters directly.
Try the below snippet i modified to replace substring with charAt.
public static boolean isTrans(String s, String t) {
System.out.println(s + " - " + t);
boolean isT = false;
if (t.length() > 1) {
if (s.charAt(0) == t.charAt(0) && (t.charAt(0) != t.charAt(1))) {
return isTrans(s.substring(1, s.length()), t.substring(1, t.length()));
}
if (s.charAt(0) == t.charAt(0) && t.charAt(0) == t.charAt(1)) {
return isTrans(s, t.substring(1, t.length()));
}
} else {
isT = (s.charAt(0) == t.charAt(0)) ? true : false;
}
return isT;
}
You can achieve this with the help of regular expressions.
Try this:
String s = "a";
String t1 = "aa";
String t2 = "aab";
System.out.println("t1->" + t1.replaceAll("(.+?)\\1+", "$1").equals(s));
System.out.println("t2->" + t2.replaceAll("(.+?)\\1+", "$1").equals(s));
s = "acd";
t1="addc";
t2 = "aaaccddd";
System.out.println("t1->" + t1.replaceAll("(.+?)\\1+", "$1").equals(s));
System.out.println("t2->" + t2.replaceAll("(.+?)\\1+", "$1").equals(s));
Hope it helps.
I'm trying to solve this CodingBat problem:
Return true if the given string contains an appearance of "xyz" where the xyz is not directly preceeded by a period (.). So "xxyz" counts but "x.xyz" does not.
xyzThere("abcxyz") → true
xyzThere("abc.xyz") → false
xyzThere("xyz.abc") → true
My attempt:
public boolean xyzThere(String str) {
boolean res = false;
if(str.contains(".xyz") == false && str.contains("xyz")){
res = true;
}
return res;
}
The problem is that is passes all the tests except the one below because it contains two instances of xyz:
xyzThere("abc.xyzxyz")
How can I make it pass all tests?
public static boolean xyzThere(String str) {
int i = -1;
while ((i = str.indexOf("xyz", i + 1 )) != -1) {
if (i == 0 || (str.charAt(i-1) != '.')) {
return true;
}
}
return false;
}
Alternatively, you could replace all occurrences of ".xyz" in the string with "", then use the .contains method to verify that the modified string still contains "xyz". Like so:
return str.replace(".xyz", "").contains("xyz");
public boolean xyzThere(String str) {
return(!str.contains(".xyz") && str.contains("xyz"));
}
Edit: Given that ".xyzxyz" should return true, the solution should be:
public boolean xyzThere(String str) {
int index = str.indexOf(".xyz");
if(index >= 0) {
return xyzThere(str.substring(0, index)) || xyzThere(str.substring(index + 4));
} else return (str.contains("xyz"));
}
The below code worked fine for me:
if '.xyz' in str:
return xyz_there(str.replace('.xyz',''))
elif 'xyz' in str:
return True
return False
Ok, I know everyone is eager to share their expertise but straight giving the kid the answer does little good.
#EnTHuSiAsTx94
I was able to pass all of the tests with three statements. Here is a hint: Try using the string replace method. Here is the method signature:
String replace(CharSequence target, CharSequence replacement)
On a minor note, the first condition in your if statement can be simplified from:
str.contains(".xyz") == false
to:
!str.contains(".xyz")
The contains method already returns true or false, so there is no need for the explicit equals comparison.
public boolean xyzThere(String str) {
return str.startsWith("xyz") || str.matches(".*[^.]xyz.*");
}
You can use the equivalent java code for the following solution:
def xyz_there(str):
pres = str.count('xyz')
abs = str.count('.xyz')
if pres>abs:
return True
else:
return False
Ok, let's translate your question into a regexp:
^ From the start of the string
(|.*[^\.]) followed by either nothing or any amount of any chars and and any char except .
xyz and then xyz
Java code:
public static boolean xyzThere(String str) {
return str.matches("^(|.*[^\\.])xyz");
}
boolean flag = false;
if(str.length()<=3){
flag = str.contains("xyz");
}
for (int i = 0; i < str.length()-3; i++) {
if (!str.substring(i, i+3).equals("xyz") &&
str.substring(i, i+4).equals(".xyz")) {
flag=false;
}else{
if(str.contains("xyz")) flag=true;
}
}
return flag;
public boolean xyzThere(String str) {
boolean res=false;
if(str.length()<3)res=false;
if(str.length()==3){
if(str.equals("xyz"))res=true;
else res=false;
}
if(str.length()>3){
for(int i=0;i<str.length()-2;i++){
if(str.charAt(i)=='x' && str.charAt(i+1)=='y' && str.charAt(i+2)=='z'){
if(i==0 || str.charAt(i-1)!='.')res=true;
}
}
}
return res;
}
public class XyzThereDemo {
public static void main(String[] args) {
System.out.println(xyzThere("abcxyz"));
System.out.println(xyzThere("abc.xyz"));
System.out.println(xyzThere("xyz.abc"));
}
public static boolean xyzThere(String str) {
int xyz = 0;
for (int i = 0; i < str.length() - 2; i++) {
if (str.charAt(i) == '.') {
i++;
continue;
}
String sub = str.substring(i, i + 3);
if (sub.equals("xyz")) {
xyz++;
}
}
return xyz != 0;
}
}
Another method
public boolean xyzThere(String str) {
if(str.startsWith("xyz")) return true;
for(int i=0;i<str.length()-3;i++) {
if(str.substring(i+1,i+4).equals("xyz") && str.charAt(i)!='.') return true;
}
return false;
}
public boolean xyzThere(String str) {
if (str.startsWith("xyz")){
return true;
}
for (int i = 0; i < str.length()-2; i++) {
if (str.subSequence(i, i + 3).equals("xyz") && !(str.charAt(i-1) == '.')) {
return true;
}
}
return false;
}
This is the best possible and easiest way to solve this question with very simple logic:
def xyz_there(str):
for i in range(len(str)):
if str[i-1]!= '.' and str[i:i+3]=='xyz' :
return True
return False
public boolean xyzThere(String str) {
boolean flag = false;
if (str.startsWith("xyz"))
{
return true;
}
for (int i = 0; i < str.length() - 3; i++)
{
if (str.charAt(i) != '.' && str.charAt(i + 1) == 'x'
&& str.charAt(i + 2) == 'y' && str.charAt(i + 3) == 'z')
{
flag = true;
break;
}
}
return flag;
}
def xyz_there(str1):
for i in range(len(str1)):
if str1[i-1] != '.' and str1[i:i+3] == 'xyz':
return True
else:
return False
def xyz_there(str):
if '.xxyz' in str:
return'.xxyz' in str
if '.' in str:
a=str.replace(".xyz","")
return 'xyz' in a
if '.' not in str:
return 'xyz' in str
'''python
def xyz_there(str):
dot=str.find('.') # if period is present in str if not dot==-1
if dot==-1: # if yes dot will show position of period
return 'xyz' in str
elif dot!=-1: #if period is present at position dot
if 'xyz' in str[:dot]:
return True
while str[dot+1:].find('.')!=-1: #while another period is present
if '.xyz' in str[dot+1:]==False: # .xyz will not be counted
return True
else:
dot=dot+str[dot+1:].find('.')+2 #now dot=previous dot+new dot+2
else:
return 'xyz' in str[dot+2:]
'''
def xyz_there(str):
list = [i for i in range(len(str)) if str.startswith('xyz', i)]
if list == []:
return False
else:
found = 0
for l in list:
if str[l-1:l+3] != ".xyz":
found += 1
if found >=1:
return True
else:
return False
simple solution just by replace and check the "xyz " in a thats it
def xyz_there(str):
a=str.replace('.xyz','')
return 'xyz' in a
This question already has answers here:
How to check if a String is numeric in Java
(41 answers)
Closed 6 years ago.
I have a gpa program, and it works with the equalsIgnoreCase() method which compares two strings, the letter "a" to the user input, which checks if they put "a" or not. But now I want to add an exception with an error message that executes when a number is the input. I want the program to realize that the integer input is not the same as string and give an error message. Which methods can I use to compare a type String variable to input of type int, and throw exception?
Many options explored at http://www.coderanch.com/t/405258/java/java/String-IsNumeric
One more is
public boolean isNumeric(String s) {
return s != null && s.matches("[-+]?\\d*\\.?\\d+");
}
Might be overkill but Apache Commons NumberUtils seems to have some helpers as well.
If you are allowed to use third party libraries, suggest the following.
https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/math/NumberUtils.html
NumberUtils.isDigits(str:String):boolean
NumberUtils.isNumber(str:String):boolean
Use this
public static boolean isNum(String strNum) {
boolean ret = true;
try {
Double.parseDouble(strNum);
}catch (NumberFormatException e) {
ret = false;
}
return ret;
}
You can also use ApacheCommons StringUtils.isNumeric - http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringUtils.html#isNumeric(java.lang.String)
Simple method:
public boolean isBlank(String value) {
return (value == null || value.equals("") || value.equals("null") || value.trim().equals(""));
}
public boolean isOnlyNumber(String value) {
boolean ret = false;
if (!isBlank(value)) {
ret = value.matches("^[0-9]+$");
}
return ret;
}
Use below method,
public static boolean isNumeric(String str)
{
try
{
double d = Double.parseDouble(str);
}
catch(NumberFormatException nfe)
{
return false;
}
return true;
}
If you want to use regular expression you can use as below,
public static boolean isNumeric(String str)
{
return str.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal.
}
public static boolean isNumeric(String string) {
if (string == null || string.isEmpty()) {
return false;
}
int i = 0;
int stringLength = string.length();
if (string.charAt(0) == '-') {
if (stringLength > 1) {
i++;
} else {
return false;
}
}
if (!Character.isDigit(string.charAt(i))
|| !Character.isDigit(string.charAt(stringLength - 1))) {
return false;
}
i++;
stringLength--;
if (i >= stringLength) {
return true;
}
for (; i < stringLength; i++) {
if (!Character.isDigit(string.charAt(i))
&& string.charAt(i) != '.') {
return false;
}
}
return true;
}
I wrote this little method lastly in my program so I can check if a string is numeric or at least every single char is a number.
private boolean isNumber(String text){
if(text != null || !text.equals("")) {
char[] characters = text.toCharArray();
for (int i = 0; i < text.length(); i++) {
if (characters[i] < 48 || characters[i] > 57)
return false;
}
}
return true;
}
You can use Character.isDigit(char ch) method or you can also use regular expression.
Below is the snippet:
public class CheckDigit {
private static Scanner input;
public static void main(String[] args) {
System.out.print("Enter a String:");
input = new Scanner(System.in);
String str = input.nextLine();
if (CheckString(str)) {
System.out.println(str + " is numeric");
} else {
System.out.println(str +" is not numeric");
}
}
public static boolean CheckString(String str) {
for (char c : str.toCharArray()) {
if (!Character.isDigit(c))
return false;
}
return true;
}
}
Here's how to check if the input contains a digit:
if (input.matches(".*\\d.*")) {
// there's a digit somewhere in the input string
}
To check for all int chars, you can simply use a double negative.
if (!searchString.matches("[^0-9]+$")) ...
[^0-9]+$ checks to see if there are any characters that are not integer, so the test fails if it's true. Just NOT that and you get true on success.