Problem:
Develop a recursive algorithm to determine if there is a palindrome hidden within a longer word or phrase. A palindrome is a word or phrase that has the same sequence of letters when read from left to right and when read from right to left, ignoring the spaces (e.g., Some like cake, but I prefer pie contains the palindrome I prefer pi).
Below is my code:
public class e125 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
int i = 0;
String sLine = "Some like cake, but I prefer pie";
sLine.replaceAll("\\s+", "");
System.out.println(PlainRet(sLine, i));
}
public static String PlainRet(String sLine, int i) {
int nNum;
char c = 0;
String sPlain = "";
if (i >= sLine.length()) {
return "No Plaindrome";
}
c = sLine.charAt(i);
nNum = Isgood(sLine, c, i);
if (nNum != 0) {
for (; i < nNum; i++) {
sPlain += sLine.charAt(i);
}
return sPlain;
}
return PlainRet(sLine, i + 1);
}
public static int Isgood(String sLine, char c, int i) {
for (int j = i + 1; j < sLine.length(); j++) {
if (Character.toUpperCase(sLine.charAt(j)) == Character.toUpperCase(c)) {
if (Isplain(sLine, i, j)) {
return j;
}
}
}
return 0;
}
public static boolean Isplain(String sLine, int i, int j) {
if (Character.toUpperCase(sLine.charAt(j)) != Character.toUpperCase(sLine.charAt(i))) {
return false;
}
else if (i == j || j == i + 1) {
return true;
}
return (Isplain(sLine, i + 1, j - 1));
}
}
I keep getting an output of "I"
I have no idea what is wrong.
Like FatalError commented sLine.replaceAll() returns a new String. You need to reassign sLine or pass the results of the replaceAll() into the method.
You'll find a new error to fix after you do that, but it's just an off-by-one!
Related
The following code prints all strings of length k where the characters are in sorted order. It does this by generating all strings of length k and then checking if each is sorted. What is its runtime?
public static int numChars = 26;
public static void printSortedStrings(int remaining) {
printSortedStrings(remaining, "");
}
public static void printSortedStrings(int remaining, String prefix) {
if (remaining == 0) {
if (isInOrder(prefix)) {
System.out.println(prefix); // Printing the string
}
} else {
for (int i = 0; i < numChars; i++) {
char c = ithLetter(i);
printSortedStrings(remaining - 1, prefix + c);
}
}
}
public static boolean isInOrder(String s) {
for (int i = 1; i < s.length(); i++) {
int prev = ithLetter(s.charAt(i - 1));
int curr = ithLetter(s.charAt(i));
if (prev > curr) {
return false;
}
}
return true;
}
public static char ithLetter(int i) {
return (char) (((int) 'a') + i);
}
public static void main(String[] args) {
printSortedStrings(2);
}
I am suppose to use Boolean to check if the string is palindrome. I'm getting an error, not sure what I am doing wrong. My program already has 3 strings previously imputed by a user. Thank you, I am also using java
public boolean isPalindrome(String word1, String word2, String word3){
int word1Length = word1.length();
int word2Length = word2.length();
int word3Length = word3.length();
for (int i = 0; i < word1Length / 2; i++)
{
if (word1.charAt(i) != word1.charAt(word1Length – 1 – i))
{
return false;
}
}
return isPalindrome(word1);
}
for (int i = 0; i < word2Length / 2; i++)
{
if (word2.charAt(i) != word2.charAt(word2Length – 1 – i))
{
return false;
}
}
return isPalindrome(word2);
}
for (int i = 0; i < word3Length / 2; i++)
{
if (word3.charAt(i) != word3.charAt(word3Length – 1 – i))
{
return false;
}
}
return isPalindrome(word3);
}
// my output should be this
if (isPalindrome(word1)) {
System.out.println(word1 + " is a palindrome!");
}
if (isPalindrome(word2)) {
System.out.println(word2 + " is a palindrome!");
}
if (isPalindrome(word3)) {
System.out.println(word3 + " is a palindrome!");
}
You could do a method for it like this:
First you build a new String and than you check if it is equal.
private static boolean test(String word) {
String newWord = new String();
//first build a new String reversed from original
for (int i = word.length() -1; i >= 0; i--) {
newWord += word.charAt(i);
}
//check if it is equal and return
if(word.equals(newWord))
return true;
return false;
}
//You can call it several times
test("malam"); //sure it's true
test("hello"); //sure it's false
test("bob"); //sure its true
i'm writing a program in java that checks if a letter appers exactly twice, i was able to write it but my problem is that for some words the code doesn't check if the letter appear exactly twice.
here is my code:
public class Test {
public static void main(String[] args) {
isDoubloon("abba");
isDoubloon("Shanghaiingss");/*it still prints out true though 's' does appear exactly twice*/}
//checks if every letter appears twice in a word
public static void isDoubloon(String s){
String l=s.toLowerCase();
int count=0;
for(int i= 0; i<l.length()-1;i++){
for(int j=i+1;j<l.length();j++){
if(l.charAt(i)==l.charAt(j)) count++;
}
}
if(count%2==0){
System.out.println("True, This is a doubloon");
}else
System.err.println("False, This is not a doubloon");
}}
Your whole logic is not correct. You have to check for every letter in your text if it occurs twice.
Try this:
String l=s.toLowerCase();
boolean check = true;
for(int i= 0; i<l.length();i++){
int count=0;
for(int j=0;j<l.length();j++){
if(l.charAt(i)==l.charAt(j)) count++;
}
if (count != 2) {
check = false;
break;
}
}
if(check==true){
System.out.println("True, This is a doubloon");
}else
System.out.println("False, This is not a doubloon");
}
Your code counts how often each letter occurs (-1) and adds all this values. If the result is even you imply that each letter is exactly twice in the word. That cannot work.
Simply try the word "aaabbbb". (your code think it is a doubloon)
So you need to check if no character occurs exactly twice and that for each character separately.
You could do it this way:
public static void main(String[] args) {
if(isDoubloon("Shanghaiingss")){
System.out.println("True, This is a doubloon");
}else{
System.err.println("False, This is not a doubloon");
}
}
public static boolean isDoubloon(final String s) {
final String l = s.toLowerCase();
for (int i = 0; i < l.length(); i++) {
int count = 0;
for (int j = 0; j < l.length(); j++) {
if (l.charAt(i) == l.charAt(j)) {
count++;
if (2 < count) {
return false; // more than twice
}
}
}
if (1 == count) {
return false; // character occurs only once
}
}
return true;
}
This algorithm is similar to yours. But it is far from fast O(n²). Is you need it you can implement it faster O(n) but you would need some extra space.
The main flaw here is that you are using a single "count" variable when you want to do a count for each letter.
I would suggest using a map to hold a count for each letter, loop over the list and add each letter to your map and finally iterate over the map and confirm all values are 2.
public static void isDoubloon(String s){
String l=s.toLowerCase();
Map<Character, Integer> counts = new HashMap();
for(int i= 0; i<l.length()-1;i++){
int prevValue = counts.getOrDefault(l.charAt(i), 0);
counts.put(l.charAt(i), prevValue + 1);
}
for (Map.Entry<Character, Integer> entry: counts.entrySet()) {
if (entry.getValue() != 2) {
System.err.println("False, This is not a doubloon");
}
}
System.out.println("True, This is a doubloon");
}
Other solution
private boolean isDoubloon(String s) {
String convertWord = s.toLowerCase();
char[] letter = convertWord.toCharArray();
int[] count = new int[26];
for (int letters = 0; letters < letter.length; letters++) {
char index = letter[letters];
count[index - 97]++;
}
for( int i = 0; i < 26; i++ ) {
if (count[i] != 0 && count[i] != 2) return false;
}
return true;
}
public static boolean isDoubloon(String s) {
if (s.length() %2 != 0)
return false;
String str = s.toLowerCase();
while (str.length() > 0) {
int index2 = str.indexOf(str.charAt(0), 1);
if (index2 == -1) {
return false;
}
int index3 = str.indexOf(str.charAt(0), index2 + 1);
if (index3 != -1) {
return false;
}
str = str.substring(1, index2) + str.substring(index2 + 1);
}
return true;
}
Obligatory Java Streams examples:
groupingBy() and counting()
public static boolean isDoubloon(String str) {
return
// Stream over chars, and box to Integer
// These will be the ASCII values of the chars
!str.chars().boxed()
// Group by identity
.collect(Collectors.groupingBy(Function.identity(),
// and map each key to the count of characters
Collectors.counting()))
// We now have a Map<Integer, Long>, the Integer being the character
// value and the Long being the number of occurrences.
// Stream over the Map's values
.values().stream()
// Retain all values unequal to 2
.filter(i -> !Objects.equals(i, 2L))
// Shortcut if found and check if a value is present
.findAny().isPresent();
// If a value is present, that means that there are one or more
// characters with less or more than two occurrences.
}
https://ideone.com/PT8sQi
distinct() and count()
public static boolean isDoubloon(String str) {
long distinct = str.chars().distinct().count();
long length = str.length();
return (length % 2 == 0 && length / 2 == distinct);
}
https://ideone.com/UaOKDF
Here's my application
"Textform", take value from the searchbox.
"listKamus", take value from the array. Then "player name", change it value to string.
"KMP.knutMorris(textform, playerName)", send textform, playerName value to knutMorris class
MAIN CLASS
public void onTextChanged(CharSequence s, int arg1, int arg2, int arg3)
{
String textform = s.toString();
searchResults.clear();
for(int i=0;i<listKamus.size();i++)
{
String playerName=listKamus.get(i).toString();
KMP.knutMorris(textform, playerName);
if(KMP.value==1){
searchResults.add(listKamus.get(i));
}
}
adapter.notifyDataSetChanged();
}
KMP CLASS
public class KMP {
/** Failure array **/
private int[] failure;
public static int value;
/** Constructor **/
public KMP(String text, String pat)
{
/** pre construct failure array for a pattern **/
failure = new int[pat.length()];
fail(pat);
/** find match **/
int pos = posMatch(text, pat);
if (pos >= 0)
{
KMP.value = 1;
}
}
/** Failure function for a pattern **/
private void fail(String pat)
{
int n = pat.length();
failure[0] = -1;
for (int j = 1; j < n; j++)
{
int i = failure[j - 1];
while ((pat.charAt(j) != pat.charAt(i + 1)) && i >= 0)
i = failure[i];
if (pat.charAt(j) == pat.charAt(i + 1))
failure[j] = i + 1;
else
failure[j] = -1;
}
}
/** Function to find match for a pattern **/
private int posMatch(String text, String pat)
{
int i = 0, j = 0;
int lens = text.length();
int lenp = pat.length();
while (i < lens && j < lenp)
{
if (text.charAt(i) == pat.charAt(j))
{
i++;
j++;
}
else if (j == 0)
i++;
else
j = failure[j - 1] + 1;
}
return ((j == lenp) ? (i - lenp) : -1);
}
/** Main Function **/
public static void knutMorris(String textform, String isidatabase)
{
String text = textform;
String pattern = isidatabase;
KMP kmp = new KMP(text, pattern);
}
I want when people type on the searchbox it shows the right list of array.
I think the error one is here
MAIN CLASS
if(KMP.value==1){
searchResults.add(listKamus.get(i));
}
Or here
KMP CLASS
if (pos >= 0)
{
KMP.value = 1;
}
Can anyone tell me how to fix this ?
I want to get an output that displays something like 1*2*3*4 but instead I get 4*3*2*1
this is my code:
public static int fact(int n)
{
if(n ==1)
return 1;
else
return n * fact(n-1);
}
public static int factorForm(int n)
{
System.out.print(n);
if (n == 1)
return 1;
else
{
System.out.print("*");
return n + '*' + factorForm(n-1);
}
}
You are calling fact(4)
Then you print
Then you call fact(3)
If you invert that you'll get what you want:
public class fact {
static int f(int n)
{
if (n ==1 )
{
System.out.print(1);
return 1;
}
int ret= (n * f(n-1));
System.out.print("*");
System.out.print(n);
return ret;
}
public static void main(String[] args)
{
int ret=f(4);
System.out.print("=");
System.out.println(ret);
}
}
To reverse the output, n should be printed after making the recursive call:
public static int factorForm(int n)
{
if (n == 1)
{
System.out.print(1);
return 1;
}
else
{
int rest = factorForm(n-1); // prints 1*2*...*n-1
System.out.print("*");
System.out.print(n);
return rest * n;
}
}
The expression n + '*' + factorForm(n-1) performs integer addition, not multiplication or string concatenation. I changed it to perform multiplication. If the intention is to return the string that was printed, the return type and the type of rest should be changed to String, the return value in the base case should be "1", and that expression should be changed to rest + "*" + n.
Return after printing as below, more importantly understand how recursion works:
public static int factorForm(int n)
{
if (n == 1){
System.out.print("1*");
return 1;
}
else
{
int val = n * factorForm(n-1);
System.out.print(n + "*");
return val;
}
}
if you want to get like 1*2*3*4 result. i think you can do this.
this is my code:
public static String fact(int n) {
if (n < 1) {
throw new RuntimeException("n must be int type and up 0");
}
else if (n == 1) {
return "1";
} else {
return n + "*" + fact(n - 1);
}
}
public static String factorForm(String str) {
String [] arr = str.split("\\*");
String [] newArr = new String[arr.length];
String result = "";
if (arr.length > 1) {
for (int i = 0; i < arr.length; i++) {
newArr[arr.length - i - 1] = arr[i];
}
for (int i = 0; i < newArr.length; i++) {
result += newArr[i] + (i != newArr.length - 1 ? "*" : "");
}
return result;
} else {
return str;
}
}
like this. you can get results what you get. may be complicated.