Modify longest palindromic substring condition with specific input.? - java

I was trying to find the algo for finding the longest palindromic substring problem.
However, my algo is failing few testcases.
public static String longestPalindrome2(String s) {
String maxPal = "";
if (s == null || s.length() < 1) return "";
String rev = new StringBuilder(s).reverse().toString();
for (int i = 0; i < s.length(); i++) {
for (int j = i; j < s.length(); j++) {
String temp = s.substring(i, j);
if(rev.contains(temp) ) {
if(temp.length() > maxPal.length()) {
maxPal = temp;
}
}
}
}
return maxPal;
}
When I pass "abacdgfdcaba" since the "abacd" is present 2 times in differnet parts of string and because of this reason it fails.
How can i change my condition so that i can pass this type of testcases ?
Thanks in advance.

You are not checking if the String is a palindrome when you search for temp in rev.
private static boolean isPalindrome(String s) {
String rev = new StringBuilder(s).reverse().toString();
return s.equals(rev);
}
Add this method and check it before assigning maxPal = temp value.

Related

How to ignore spaces while Sorting a string in java?

I tried to code a program to detect an anagram with 2 Strings given.
My approach is to convert both strings to char Arrays and then sort them before comparing them.
I know I could use the sort() function but I don't want to use any imports for training purposes.
The problem is i want my programm to ignore blanks while scanning for an anagram.
in the current version the ouput is like this:
(triangle, relating) ---> true
(tri angle, relating) ---> false
while it should be both true.
i would be thankful for any help!
heres my code, (please ignore my comments):
public static boolean anagramCheck(String a, String b) {
boolean r = true;
// In Char Arrays umwandeln /
char[] Ca = a.toCharArray();
char[] Cb = b.toCharArray();
// Laengen Abfrage
int L1 = Ca.length;
int L2 = Cb.length;
// Erste For-Schleife
for (int i = 0; i < L1; i++) {
for (int j = i + 1; j < L1; j++) {
if (Ca[j] < Ca[i]) {
char temp = Ca[i];
Ca[i] = Ca[j];
Ca[j] = temp;
}
}
}
// Zweite For-schleife
for (int i = 0; i < L2; i++) {
for (int j = i + 1; j < L2; j++) {
if (Cb[j] < Cb[i]) {
char temp = Cb[i];
Cb[i] = Cb[j];
Cb[j] = temp;
}
}
}
// Char Arrays zu Strings
String S1 = String.valueOf(Ca);
String S2 = String.valueOf(Cb);
// Vergleich und Ausgabe
if (S1.compareTo(S2) == 0) {
return r;
}
else {
r = false;
return r;
}
}
}
The String.replace(String, String) is the non-regexp replace method.
So remove all spaces:
String S1 = String.valueOf(Ca).replace(" ", "");
String S2 = String.valueOf(Cb).replace(" ", "");
It would be nicer to do this on a and b.
public static boolean isAnagram(String one, String two) {
char[] letters = new char[26];
for (int i = 0; i < one.length(); i++) {
char ch = Character.toLowerCase(one.charAt(i));
if (Character.isLetter(ch))
letters[ch - 'a']++;
}
for (int i = 0; i < two.length(); i++) {
char ch = Character.toLowerCase(two.charAt(i));
if (Character.isLetter(ch))
letters[ch - 'a']--;
}
for (int i = 0; i < letters.length; i++)
if (letters[i] != 0)
return false;
return true;
}
Generally, less code is better (if it’s readable). And learning a language means learning the built in libraries.
Here’s a method to return a String of sorted chars:
public static String sortChars(String str) {
return str.replace(" ", "").chars().sorted()
.mapToObj(c -> (char)c + "")
.collect(Collectors.joining(""));
}
With this method, your main method becomes:
public static boolean anagramCheck(String a, String b) {
return sortedChars(a).equals(sortedChars(b));
}
Refactoring like this, using well-named methods makes your code easier to understand, test, debug and maintain.
It’s worth noting that you don’t actually need a sorted String… a sorted array would serve equally well, and requires less code:
public static int[] sortChars(String str) {
return str.replace(" ", "").chars().sorted().toArray();
}
public static boolean anagramCheck(String a, String b) {
return Arrays.equal(sortedChars(a), sortedChars(b));
}
A frequency map could be created with the characters from String one incrementing and the characters from String two decrementing, then the resulting map should contain only 0 as values.
To skip non-letters, Character::isLetter can be used.
public static boolean isAnagram(String a, String b) {
Map<Character, Integer> frequencies = new HashMap<>();
for (int i = 0, na = a.length(), nb = b.length(), n = Math.max(na, nb); i < n; i++) {
if (i < na && Character.isLetter(a.charAt(i)))
frequencies.merge(Character.toLowerCase(a.charAt(i)), 1, Integer::sum);
if (i < nb && Character.isLetter(b.charAt(i)))
frequencies.merge(Character.toLowerCase(b.charAt(i)), -1, Integer::sum);
}
return frequencies.values().stream().allMatch(x -> x == 0);
}

How can I compare these two strings and remove a common letter without using arrays?

This was the code I designed to solve this problem but it seems not to work at all.I used nested for loops to compare the letters of the first string and the second string since they are likely to have different lengths
import java.util.*;
public class Trim
{
public static String myTrim(String input, String list)
{
String r = "";
for (int i = 1; i < input.length();i++)
{
for (int k = 1; k < list.length();k++)
{
if (input.charAt(i) != list.charAt(i))
{
r += input.charAt(i);
}
}
}
return r;
}
}
I guess you should use the method String.indexOf.
So:
public static String myTrim(String input, String list)
{
StringBuilder result = new StringBuilder();
char c;
for (int i = 0; i < input.length(); i++)
{
c = input.charAt(i);
if (list.indexOf(c) < 0)
result.append(c);
}
return result.toString();
}
Try using a flag to determine whether to character gets repeated or not:
String r = "";
for (int i = input.length() - 1; 0 <= i; i --) {
if (-1 == list.indexOf(input.charAt(i))) {
r += input.charAt(i);
}
}
OR
String r = "";
boolean found;
for (int i = input.length() - 1, j = list.length() - 1; 0 <= i; i--) {
found = false;
for (int k = j; 0 <= k; k--) {
if (list.charAt(k) == input.charAt(i)) {
found = true;
break;
}
}
if (!found) {
r += input.charAt(i);
}
}
We have to filter out the characters from input which appears in list.
Now we have to check whether each character of the input appears in the list or not.
The k value will be less then list.length() if the character of input present in the list string.
After the loop we check the k value and append it to the new string.
public static String myTrim(String input, String list)
{
String r = "";
for (int i = 0; i < input.length();i++)
{
int k = 0;
for (; k < list.length();k++)
{
if (input.charAt(i) == list.charAt(k))
{
break;
}
}
if(k == list.length())
r += input.charAt(i);
}
return r;
}
A nice one-liner solution would be to use Guava Charmatcher:
CharMatcher.anyOf(list).removeFrom(input);
I have tried this code and it's working fine with both of your inputs
for (int i = 0; i < S1.length(); i++) {
for(int j=0;j< S2.length();j++) {
if(S1.charAt(i)==S2.charAt(j)) {
char Temp= S2.charAt(j);
String Temp2=String.valueOf(Temp);
S1=S1.replace(Temp2, "");
}
}
}
This is code
import java.util.Scanner;
public class StringRemoveChar {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String S1, S2;
S1 = scanner.nextLine();
S2 = scanner.nextLine();
for (int i = 0; i < S1.length(); i++) {
for (int j = 0; j < S2.length(); j++) {
if (S1.charAt(i) == S2.charAt(j)) {
char Temp = S2.charAt(j);
String Temp2 = String.valueOf(Temp);
S1 = S1.replace(Temp2, "");
System.out.println(S1.length());
}
}
}
System.out.println(S1);
}
}
Input:
Miyazaki
you
Output:
Miazaki
We can use replaceAll and use one loop over ,this will make the solution simple
public static String myTrim(String input, String list)
{
for(int i=0;i<list.length();i++)
{
input=input.replaceAll(list.charAt(i)+"","");
}
return input;
}
Input: myTrim("Miyazaki","you")
Output: Miazaki
Full code for reference
package stackoverflow.string;
public class StringManipulation
{
public static void main(String[] args)
{
System.out.println(myTrim("University of Miami","city"));
}
public static String myTrim(String input, String list)
{
for(int i=0;i<list.length();i++)
{
input=input.replaceAll(list.charAt(i)+"","");
}
return input;
}
}

find subsequence in a string: Java

I have a string hackkkerrank and i have to find if any subsequence gives a result as hackerrank, if it is present then it gives result as YES otherwise NO.
Sample:
hereiamstackerrank: YES
hackerworld: NO
I don't know which String method should be applied, can anyone help me how to do it?
Here is my code:
static String hackerrankInString(String s) {
char str[] = {
'h','a','c','k','e','r','a','n','k'
};
while (s.length() >= 10) {
for (int i = 0; i < s.length(); i++) {
for (char c: str) {
if (s.indexOf(c)) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
}
}
Here is a built-in way, using regex:
String regex = "[^h]*+h[^a]*+a[^c]*+c[^k]*+k[^e]*+e[^r]*+r[^r]*+r[^a]*+a[^n]*+n[^k]*+k.*";
System.out.println("hereiamstackerrank".matches(regex) ? "YES" : "NO");
System.out.println("hackerworld".matches(regex) ? "YES" : "NO");
Output
YES
NO
You can make a generic method to check for subsequence like this:
public static boolean containsSubsequence(String subsequence, String text) {
StringBuilder buf = new StringBuilder();
for (int i = 0, j; i < subsequence.length(); i = j) {
j = subsequence.offsetByCodePoints(i, 1);
String ch = Pattern.quote(subsequence.substring(i, j));
buf.append("[^").append(ch).append("]*+").append(ch);
}
String regex = buf.append(".*").toString();
return text.matches(regex);
}
Test
System.out.println(containsSubsequence("hackerrank", "hereiamstackerrank") ? "YES" : "NO");
System.out.println(containsSubsequence("hackerrank", "hackerworld") ? "YES" : "NO");
Output
YES
NO
Of course, it is not very efficient, but it is one way to do it.
For a simpler and more efficient solution, that doesn't handle characters in the Supplement­ary Planes, you'd do this:
public static boolean containsSubsequence(String subsequence, String text) {
int j = 0;
for (int i = 0; i < text.length() && j < subsequence.length(); i++)
if (text.charAt(i) == subsequence.charAt(j))
j++;
return (j == subsequence.length());
}
Here is an old fashioned looping way, which increments the starting position of the second string based upon where the last char was found
String str1 = "hackerrank";
String str2 = "hereiamstackerrank";
int index = 0;
for (int i = 0; i < str1.length(); i++)
{
boolean notfound = true;
int x = index;
for (; x < str2.length(); x++) {
if (str1.charAt(i) == str2.charAt(x)) {
notfound = false;
break;
}
}
if (notfound) {
System.out.println("NO");
return;
}
index = x + 1;
}
System.out.println("YES");
An in-efficient alternative is
for (int i = 0; str1.length() > 0 && i < str2.length(); i++)
{
if (str1.charAt(0) == str2.charAt(i)) {
str1 = str1.substring(1);
}
}
System.out.println(str1.length() == 0 ? "YES" : "NO");
static String re="";
static String hackerrankInString(String s) {
String pattern="[^h]*+h[^a]*+a[^c]*+c[^k]*+k[^e]*+e[^r]*+r[^r]*+r[^a]*+a[^n]*+n[^k]*+k.*";
if(s.matches(pattern)){
re="YES";
}else{
re="NO";
}
return re;
}
There's no built in function in core libraries to check subsequence. There's one for substring but none for subsequence you're looking for.
You'll have to code it yourself.
Below is the pseudo code for this:
1. Traverse both original string and string under test.
2. Increment both's counter if characters are equal
3. Else increment originalString's counter only.
4. Repeat 2-3 `while` both strings are `not` empty.
5. Given string under test is subsequence if its counter is exhausted.

How to return longest sequence of chars in a string in java?

Following is what I end up doing but i did not find right answer.
Example - If I have the sequence "hellloo" the output will be "lll". Please tell me what is wrong?
public class LongestSequenceOfChar {
static String testcase1="hellloo";
public static void main(String[] args) {
LongestSequenceOfChar test = new LongestSequenceOfChar();
String result = test.longestSequenceOfChar(testcase1);
System.out.println(result);
}
public String longestSequenceOfChar(String str){
String result="";
for(int i=0;i<str.length();i++){
char ch=str.charAt(i);
for(int j=i+1;j<str.length();j++){
char ch1=str.charAt(j);
if(ch!=ch1){
continue;
}
result+=ch;
}
}
return result;
}
}
You should have a counter that counts the number of the longest sequence for now. When you find a longer sequence, you should reset result and update the counter accordingly.
However, you can have better solutions:
Have an array of size 26 (the size of the English alphabet). Now you iterate on the String and for each char in it you add 1 in the corresponding cell in the helper array.
Use a HashMap that has the char as a key and the number it appears as the value. If it's a new char you simply put it with 0 value, if it exists, you increment the existing value.
Tip: Use a debugger, it can save your life.
1. Create a HashMap<Character,Integer>.. Integer-->count
2. Start from the beginning of your String.. For each character, check if it is already present in the hashmap
a. If Yes, just increment the count
b. if No, then add the character as key to the Map and set its count value to 1.
If there are three 'l' you only add two and in the next step are two 'l' and you add one of them. Then the same with the two 'o' where you are adding one. You only have to clear the result string when you step to the next letter and before save the result in another variable, but only if its is longer!
public String longestSequenceOfChar(String str){
String interimresult="";
String result=""; //final result
for(int i=0;i<str.length();i++){
char ch=str.charAt(i);
interimresult += ch; //add the letter once
for(int j=i+1;j<str.length();j++){
char ch1=str.charAt(j);
if(ch!=ch1){
break;
}
interimresult +=ch;
}
if(interimresult.length()>result.length())//store the result if it is longer
result = interimresult;
interimresult = ""; //clear to continue with the next letter
}
return result;
}
Here is a solution:
public String longestSequenceOfChar(String str) {
String result = "";
for (int i = 0; i < str.length(); i++) {
int j = i;
while(j < str.length() && str.charAt(j) == str.charAt(i)) {
j++;
}
// If this one is longer than previous, then asign it to result.
if(j - i > result.length()) {
result = str.substring(i, j);
}
}
return result;
}
This can be solved easily using HashMap. Checkout this sample code:
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class MaximumOccuringCharUsingHashMap {
public static void main(String[] args) {
String test = "test samples";
MaximumOccuringCharUsingHashMap mc =
new MaximumOccuringCharUsingHashMap();
System.out.println( mc.findMaximunOccurenceCharacter(test));
}
char findMaximunOccurenceCharacter(String input){
Map<Character, Integer> countHash =
new HashMap<Character, Integer>();
for(int i=0; i<input.length() ;i++ ){
char currentChar = input.charAt(i);
if(countHash.get(currentChar)==null){
countHash.put(currentChar, 1);
}else{
countHash.
put(currentChar, countHash.get(currentChar)+1);
}
}
int max = Collections.max(countHash.values());
char maxCharacter =0;
for(Entry<Character, Integer> entry :countHash.entrySet()){
if(entry.getValue() == max){
maxCharacter = entry.getKey();
}
}
return maxCharacter;
}
}
Above code will print s as output, which is occurring maximum number of times in the given String.
Try This...
public class HelloWorld {
public static void main(String[] args) {
System.out.println(maxLen(null));
System.out.println(maxLen(""));
System.out.println(maxLen("a"));
System.out.println(maxLen("aa"));
System.out.println(maxLen("abcddd"));
System.out.println(maxLen("abcd"));
System.out.println(maxLen("aabbba"));
}
public static String maxLen(String input) {
// Avoid NPEs
if (input == null) {
return null;
}
int maxLen = 0;
int tempLen = 0;
char prevChar = 0;
char c = 0;
char repeatChar = 0;
for (int i = 0; i < input.length(); i++) {
c = input.charAt(i);
if (c == prevChar) {
tempLen++;
if (tempLen > maxLen)
repeatChar = c;
} else {
maxLen = (tempLen > maxLen) ? tempLen : maxLen;
prevChar = c;
tempLen = 1;
}
}
maxLen = (tempLen > maxLen) ? tempLen : maxLen;
if (maxLen == 0 || maxLen == 1)
return "no sequence found";
else {
String str = "";
for (int i = 1; i <= maxLen; i++)
str += String.valueOf(repeatChar);
return str;
}
}
}
This will pass all test cases.

How to find the longest repeated substring of given string

I am new java and I was given assignment to find the longest substring of a string.
I research online and seems that good way of approaching this problem will be implementing suffix tree.
Please let me know how I can do this or if you have any other solutions. keep in mind this is suppose to be done with low level of java knowledge.
Thanks in adavance.
P.S. the tester string is reassuring.
/**
This method will find the longest substring of a given string.
String given here is reassuring.
*/
public String longestRepeatedSubstring()
{
String longestRepeatedSubstring = "";
for (int i = 0; i<text.length(); i++ )
{
String one = text.substring(0,i);
for(int o = 0; o<text.length();o++)
{
Sting two = text.substring(0,o);
if(one.equals(two))
{
longestRepeatedSubstring = one;
}
}
}
return longestRepeatedSubstring;
}
If you debug your code you will see that you the code isn't doing what you think. AFAIK you need at least three loops and you can't assume you would only start from the first character. Here is one possible solution.
public static void main(String[] args) throws IOException {
String longest = longestDuplicate("ababcaabcabcaab");
System.out.println(longest);
}
public static String longestDuplicate(String text) {
String longest = "";
for (int i = 0; i < text.length() - 2 * longest.length() * 2; i++) {
OUTER:
for (int j = longest.length() + 1; j * 2 < text.length() - i; j++) {
String find = text.substring(i, i + j);
for (int k = i + j; k <= text.length() - j; k++) {
if (text.substring(k, k + j).equals(find)) {
longest = find;
continue OUTER;
}
}
break;
}
}
return longest;
}
prints
abcaab
for "reassuring" it prints r not s which was my first guess. ;)
public static void main(String[] args) {
String str = "testingString";
char[] strArr = str.toCharArray();
StringBuilder bm = new StringBuilder();
boolean isPresent = false;
int len = strArr.length;
int initial =0;
int dinitial=0;
HashMap<String, String> hm = new HashMap<String,String>();
HashMap<String, String> hl = new HashMap<String,String>();
while(initial<=len-1 && !(dinitial>=len-1)){
if(!hm.isEmpty()){
isPresent = hm.containsValue(strArr[initial]+"");
if(!isPresent){
bm.append(strArr[initial]);
hm.put(strArr[initial]+"",strArr[initial]+"");
if(initial==len-1){
System.out.println("Longest substring is::" + bm);
break;
}
}
else if(isPresent){
System.out.println("Longest substring is::" + bm);
bm.delete(0, bm.length());
++dinitial;
initial--;
hm.clear();
}
initial++;
}
else
{
bm.append(strArr[initial]);
hm.put(strArr[initial]+"",strArr[initial]+"");
initial++;
}
}
hm.clear();
}

Categories

Resources