I need to write a short recursive program for a class that checks if a string - t is transformation of another string - s. It simply needs to check if every character in s is also in t.
For ex:
"sddbs" is not a transformation of "sdb"
"sddbs" is a transformation of "sddb".
public static boolean isTrans (String s, String t)
{
if (t.indexOf(s.charAt(0)) != -1)
return true;
else
return false;
return isTrans(s.substring(1), t);
}
And still.. the code doesn't work as expected. "unreachable statement" in the last line of the code.
The reason is quite simple:
there is no possible way to execute this line:
return isTrans(s.substring(1), t);
why?:
you have a return IF this condition (t.indexOf(s.charAt(0)) != -1) is met and another if not....
It's because of the Law of Excluded Middle. You can treat return as exit function.
public static boolean isTrans (String s, String t) {
if (condition)
return true;
else
return false;
//the condition must have been true or false so the method has already exited.
return isTrans(s.substring(1), t);
}
If the condition is true, you return true, if it's false you return false. Otherwise you call recursively. There is no otherwise.
You final return statement is unreachable because your method body contains return statement for both if and else condition, hence assuring that the last return statement will never be reached.
But besides this I don't understand why you need to write a recursive function, though a non-recursive function using similar method calls will do the same thing:
public static boolean isTrans (String s, String t)
{
if (t.indexOf(s) > -1)
return true;
else
return false;
}
Edit:
As suggested by #Holger you can avoid unnecessary if else and replace your code with:
public static boolean isTrans (String s, String t)
{
return (t.indexOf(s) > -1) //returns true or false just like your if else
}
or even shorter:
public static boolean isTrans (String s, String t)
{
return t.contains(s); //internally contains() calls indexOf(), similar to what you are doing
}
According to your recursion method once you enter the if condition it would either return a true or false output. so your code never reaches the recursion statement.
I would like to suggest my way of implementing your transformation program using recursion.
import java.util.Scanner;
public class Recursion {
static int flag;
public void isTransformation(String str1, String str2) {
flag = str2.length();
char ch1[], ch2[];
ch1 = str1.toCharArray();
ch2 = str2.toCharArray();
if (ch1[0] == ch2[0]) {
flag--;
if (flag == 0) {
System.out.println("Transformation");
return;
}
isTransformation(str1.substring(1), str2.substring(1));
} else
System.out.println("Not a Transformation");
}
public static void main(String args[]) {
String str1, str2;
Scanner sc = new Scanner(System.in);
System.out.print("Enter string 1: ");
str1 = sc.nextLine();
System.out.print("Enter string 2: ");
str2 = sc.nextLine();
Recursion r = new Recursion();
if (str1.length() >= str2.length())
r.isTransformation(str1, str2);
else
r.isTransformation(str2, str1);
sc.close();
}
}
Related
I'm trying to build a palindrome. I think I might be overthinking the solution with way too many conditional loops inside my if statement. I'm having trouble trying to update the while loop to check whether it has gone through and checked for equality throughout each character of the string, and to update it. Can someone point me in the right direction, and also how can I do a cleaner job with code?
public class Main {
public static void main(String[] args) {
Main main = new Main();
main.isPalindrome("saippuakivikauppias");
main.isPalindrome("Hello World");
main.isPalindrome("Was it a car or a cat I saw");
}
private boolean isPalindrome(String word) {
int first = word.charAt(0);
int last = word.charAt(word.length() - 1);
if(word.length() <= 1) {
return true;
} else if(word.trim().length() > 1) {
if(Character.isLetter(first) && Character.isLetter(last)) {
while(first == last) {
first++;
last--;
//if loop to check if the while loop as gone through the entire string?
//update?
}
} else {
return false;
}
}
return false;
}
}
You really overthought this one - you should think a bit more basic about your problem:
A palindrome is a string that is the same read backward and forward -> create a reverse of word and compare to word
public static boolean isPalindrome(String word){
StringBuilder reverse = new StringBuilder(word).reverse();
return word.equals(reverse.toString());
}
You could even do this - depending on your coding style - in one line.
First off, I will admit that this is an assignment of mine. however, I am at my wits end. I tried need to validate that the user input a proper expression (ie: "7 + 5;") and I managed to do it with split methods but I was told that I can't do that. I'm sure there is a simple solution to the problem but I am not seeing it.
The code is rather lengthy so I won't post it but if I will if needed.
Thanks!
Edit to answer questions: I am writing in jGrasp, so they can do whatever is on the keyboard. I was told to "Find a creative way to use substrings" which I don't know what that means. The expression needs to be Number Space operand Space number semicolon
here is what I have for the validation... I am using arrays for each character in the expression
public static boolean validFormat(String expr)
{
String tokens[] = expr.substring()
if (tokens.length == 3)
{
if (tokens[0].equals(""))
{
return false;
}
if (tokens[1].equals(""))
{
return false;
}
if (tokens[2].length < 2)
{
return false;
}
else
{
if (tokens[2].endwith(";"));
{
return false;
}
else
{
return true;
}
}
}
return false;
}
I get an error with calling the substring as well as an "else without if" error
First, you should limits the input to 6 characters using an if statement. Then use the CharAt() method to return each character to check the condition.
I was told to "Find a creative way to use substrings".
As told, try using String.substring() for the same.
public class Demo {
public static void main (String[] args) {
String exp = "7 + 5;";
System.out.printf("%s\t%b%n", exp, validate(exp));
exp = "4 + d;";
System.out.printf("%s\t%b%n", exp, validate(exp));
}
public static boolean validate(String exp) {
String n1 = exp.substring(0,1);//operand
String n2 = exp.substring(4,5);//operand
String co = exp.substring(5);//semicolon
String s1 = exp.substring(1,2);//space
String s2 = exp.substring(3,4);//space
String op = exp.substring(2,3);//operator
return num(n1) && num(n2) && semi(co) && space(s1) && space(s2) && opt(op);
}
public static boolean num(String n) {
return "0123456789".contains(n);
}
public static boolean semi(String s) {
return ";".equals(s);
}
public static boolean space(String s) {
return " ".equals(s);
}
public static boolean opt(String s) {
return "-+*%/^".contains(s);
}
}
This solution uses RegExp:
public class Demo {
public static void main (String[] args) {
String exp = "7 + 5;";
System.out.printf("%s\t%b%n", exp, validate(exp));
exp = "4 + d;";
System.out.printf("%s\t%b%n", exp, validate(exp));
}
public static boolean validate(String exp) {
return exp.matches("\\d\\s(\\+|\\-|\\*|\\/|\\^|\\%)\\s\\d\\;");
}
}
import java.util.Scanner;//import Scanner
public class review{ //name of the program
public static void main(String[]args){ // main statement
Scanner i=new Scanner(System.in);
System.out.println("Enter a string");
String b=i.nextLine();
System.out.println("Enter a letter");
char c=i.next().charAt(0);
System.out.println("Answer is "+test1(b,c));
}
public static boolean test1(String a, char b){
boolean result= true;
for(int i=0;i<a.length();i++)
if(a.charAt(i)==b)
result =true;
else
result=false;
return result;
}
}
this program is looking for checking the char is in the string or not.
Hello, E = true
Hello, a = false
In this method test1, your forloop will traverse the whole line although it finds the letter into the string. so update it like this:
public static boolean test1(String a, char b){
for(int i=0;i<a.length();i++) {
if(a.charAt(i)==b)
return true;
}
return false;
}
Because, if the letter is found into the string you don't need to check further, hence:
if(a.charAt(i)==b) // if condition finds true path
return true; // so return true
Note that, return statement causes execution to leave the current function or tersely current subordinate.
You're never breaking out of the loop. Consider "Hello" and 'e'
see H: result = false
see e: result = true
see l: result = false...
break from the loop. Or, just use String.indexOf(char)
after each check you are changing result, without considering the option the the character is already found.
you can see is in twentylemon's answer.
i just wanted to say something that will be more correct and efficient.
insted of using break and return result you can do return true if the character is found.
in the end of the loop return false.
in this way, you dont need the result variable and the break.
this is how you write it as i suggested:
public static boolean test1(String a, char b)
{
for(int i=0;i<a.length();i++)
{
if(a.charAt(i)==b)
{
return true;
}
}
return false;
}
if you will check it, you will see how simple and good it is :)
http://codingbat.com/prob/p126880
Given two strings, return true if either of the strings appears at the very end of the other string, ignoring upper/lower case differences (in other words, the computation should not be "case sensitive"). Note: str.toLowerCase() returns the lowercase version of a string.
I cannot get when it is true, it always gives false.
public boolean endOther(String a, String b)
{
//variables
a.toLowerCase();
b.toLowerCase();
String f1="";
String f2="";
int d=0;
int sum=0;
//Program code;
if(a.length()-b.length()>0)
{
(f1).equals(a);
(f2).equals(b);
d=a.length();
}
else if(a.length()-b.length()<0)
{
(f1).equals(b);
(f2).equals(a); //gett**ing bigger and lower String**
d=b.length();
}
else if((a).equals(b))
sum++;
// I think problem is because it is not enter the for.
for(int i=0; i>d; i++)
{
if((f1.substring(i,i+f2.length())).equals(f2))
sum++;
}
if(sum>0)
return true;
else
return false;
}
This is a working example of what you are trying to achieve to test in your Java IDE like Netbeans or Eclipse whatever. This is really simple, the String object has an endsWith method so why try to invent something yourself.
If you have any troubles reading this code hit me up, should be quite straight forward. You will just have to convert your string to lowercase, that's for you to add.
public class StringEnds {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.printf("String a: ");
String a = scanner.next();
System.out.printf("String b: ");
String b = scanner.next();
// Compare a and b
if (endsWith(a, b)) {
System.out.printf("Succes\n");
} else {
System.out.printf("Fail\n");
}
}
public static boolean endsWith(String firstString, String secondString) {
return firstString.endsWith(secondString) || secondString.endsWith(firstString);
}
}
Here's your codebat solution (it is quite short):
public boolean endOther(String a, String b) {
return a.toLowerCase().endsWith(b.toLowerCase()) || b.toLowerCase().endsWith(a.toLowerCase());
}
This is my answer. I tried both ways, hope it helps.
public boolean endOther(String a, String b) {
int small = Math.min(a.length(), b.length());
if (a.length()==b.length() && a.equalsIgnoreCase(b)) {
return true;
}
if (small==a.length()) {
if (b.substring(b.length()-small).equalsIgnoreCase(a)) {
return true;
}
// from here is the toLowerCase() method.
a = a.toLowerCase();
b = b.toLowerCase();
} else if (small==b.length()) {
if (a.endsWith(b)) {
return true;
}
}
return false;
}
I have a string like a>5 and b<6 or c>=7 in java
When I check whether string contains > then output is true for both > and >=
How can I restrict my check only to specific character?
How can I use matches function?
Your mistake is, you think of a lexical entity, >=, as of a "character." That will bite you more than once, as there actually are two characters, > and =, and > is indeed here. So depending on what you need, the answer may be different.
Why don't you want to see >= found?
What usage of > is of interest for you? Will e.g. <tag>some text</tag> be a proper string which you'd prefer to allow?
You want to discriminate between greater than and greater than or equal to. Why not write a method that returns the operator?
enum Operator {
...
}
public Operator getOperator(String s) {
if(s.contains(">=")) {
return Operator.GREATER_THAN_OR_EQUAL_TO;
} else if (s.contains(">") {
return Operator.GREATER_THAN;
}
}
If the input can be a complex expression that contains multiple operators, instead of contains, try using indexOf(...) and look ahead one character for the '='.
I just threw this together based on the updated specifications. Basically a real simple parser rather mechanically created: (And I'm not good with naming at 7 in the morning oh well)
public class Main {
public static void main(String[] args) {
String test = "a > b >= c > x";
Main m = new Main(test);
System.out.println(m.getTokenNumber());
test = "aasdfasdf asdfdasf";
m = new Main(test);
System.out.println(m.getTokenNumber());
}
private String input;
private int pos;
public Main(String input) {
this.input = input;
pos = 0;
}
public TokenNumber getTokenNumber() {
TokenNumber tokenNumber = new TokenNumber();
Token t = nextToken();
while (t != Token.NONE) {
tokenNumber.addToken(t);
t = nextToken();
}
return tokenNumber;
}
private Token nextToken() {
while (pos < input.length() && input.charAt(pos) != '>') pos++;
if (pos == input.length()) return Token.NONE;
pos++;
if (pos == input.length() || input.charAt(pos) != '=') return Token.GREATER;
return Token.GREATER_EQUAL;
}
enum Token {
GREATER, GREATER_EQUAL, NONE;
}
static class TokenNumber {
public int greater;
public int greater_than;
public void addToken(Token t) {
if (t == Token.GREATER) greater++;
else greater_than++;
assert t != Token.NONE;
}
public String toString() {
return String.format("Greater: %d%nGreater Than: %d", greater, greater_than);
}
}
}
"your string >".contains(">");// returns true
boolean value = Pattern.compile(">").matcher("a>5").find(); // returns true