I am trying to implement an algorithm to calculate all combinations of an Array where one character is replaced by '*' without changing the order of the Arrays entries.
For example the following Array with two entries:
{"A", "B"}
Should reproduce this Output:
[A, B]
[*, B]
[A, *]
[*, *]
My current code is:
public class TestCombination {
public static void combinations(List<String[]> values, String[] attr, String all, int iteration) {
String[] val = new String[attr.length];
for (int i = 0; i < attr.length; i++) {
val[i] = attr[i];
}
if (iteration < attr.length) {
val[iteration] = all;
}
values.add(val);
iteration = iteration + 1;
if (Math.pow(attr.length, 2) != iteration) {
combinations(values, attr, all, iteration);
}
}
public static void main() {
String[] values = new String[] {"A", "B"};
List<String[]> resultValues = new ArrayList<String[]>();
combinations(resultValues, values, "*", 0);
for (String[] res : resultValues) {
System.out.println(Arrays.deepToString(res));
}
}
}
The Output i get is:
[*, B]
[A, *]
[A, B]
[A, B]
This is especially because of this not correct code:
if (iteration < attr.length) {
val[iteration] = all;
}
I do not have any idea, how the next possible index can be calculated to replace the Array value at that index by '*'.
Can you give me please some hints on that?
One simple approach is to use a bit mask of length n. Iterate all n-digit binary numbers, and then for each of the n positions do the following:
If position i has one, output an asterisk *
If position i has zero, output the original value.
This will cover all combinations.
String[] a = new String[] {"A", "B", "C"};
for (int mask = 0 ; mask != 1<<a.length ; mask++) {
for (int i = 0 ; i != a.length ; i++) {
if ((mask & 1<<i) != 0) {
System.out.print("* ");
} else {
System.out.print(a[i]+" ");
}
}
System.out.println();
}
Demo.
My solution is a modification of #dasblinkenlight solution where I'm using recursive function and not mask bit. My solution is in javascript.
var arr = ['A', 'B', 'C'],
len = arr.length,
pattern = function(startIndex, arr) {
var newArr = [].concat(arr),
i;
newArr[startIndex] = '*';
console.log(newArr.toString());
for (i = startIndex + 1; i < len; i++) {
pattern(i, newArr);
}
};
console.log(arr.toString())
for (i = 0; i < len; i++) {
pattern(i, arr);
}
You can use a recursive function to get the current string and one index and one time change the character at that index to * and another time call the function without changing the character at that index. Print the result when index reaches end of the string:
public class Main{
public static void main(String args[]){
f(new StringBuilder("ABC"),0);
}
public static void f(StringBuilder str, int index){
if (index == str.length()){
System.out.println(str);
return;
}
f(str, index+1);
char c = str.charAt(index);
str.setCharAt(index, '*');
f(str, index+1);
str.setCharAt(index, c);
}
}
output
ABC
AB*
A*C
A**
*BC
*B*
**C
***
Related
I have to find the number of elements in two char[] arrays. These arrays are char arrays with a max size of 5, and only letters A to G can be used. I will separate this into two arrays - arr1 and arr0. arr1 has priority over arr2, as in if arr1 has 3 elements of 'A' but arr2 has 4, the max count is 3.
I have to find the number of common elements these arrays share, with arr1 having the priority in maximum count. I am stumped so far. I thought of iterating through the chars:
for (char x = 'A'; x <= G; x++) {
//code
}
But I have no idea what to do after that. Any help would be appreciated.
This feels like homework so instead of giving you a full solution I will give you pointers and the parts you need to disassemble / reassemble to make it work, hoping that this will better allow you to learn and understand the suggested solution.
Here's a solution to count elements in a String using HashMap, you can easily adapt it to count elements in an Array:
// Java prorgam to count frequencies of
// characters in string using Hashmap
import java.io.*;
import java.util.*;
class OccurenceOfCharInString {
static void characterCount(String inputString)
{
// Creating a HashMap containing char
// as a key and occurrences as a value
HashMap<Character, Integer> charCountMap
= new HashMap<Character, Integer>();
// Converting given string to char array
char[] strArray = inputString.toCharArray();
// checking each char of strArray
for (char c : strArray) {
if (charCountMap.containsKey(c)) {
// If char is present in charCountMap,
// incrementing it's count by 1
charCountMap.put(c, charCountMap.get(c) + 1);
}
else {
// If char is not present in charCountMap,
// putting this char to charCountMap with 1 as it's value
charCountMap.put(c, 1);
}
}
// Printing the charCountMap
for (Map.Entry entry : charCountMap.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
// Driver Code
public static void main(String[] args)
{
String str = "Ajit";
characterCount(str);
}
}
And finally you can sort by occurrence and get the highest occurrences, there are plenty of resources about that, here's an Example from StackOverflow:
Map<String, Person> people = new HashMap<>();
Person jim = new Person("Jim", 25);
Person scott = new Person("Scott", 28);
Person anna = new Person("Anna", 23);
people.put(jim.getName(), jim);
people.put(scott.getName(), scott);
people.put(anna.getName(), anna);
// not yet sorted
List<Person> peopleByAge = new ArrayList<>(people.values());
Collections.sort(peopleByAge, Comparator.comparing(Person::getAge));
for (Person p : peopleByAge) {
System.out.println(p.getName() + "\t" + p.getAge());
}
Source for OccurenceOfCharInString
Source for HashMap sorting
arr1;
arr2;
int find(char) {
int a = 0;
int b = 0;
for(let i = 0; i < arr1.length; i++) {
if(arr1[i] === char)
a++;
}
for(let j = 0; j < arr2.length; j++) {
if(arr2[j] === char)
b++;
}
if(a > 0){
return a;
} else {
return Math.max(a, b);
}
}
numOccurence = find(char);
I am looking to create an algorithm preferably in Java. I would like to go through following char array and create every possible permutations and lengths out of it.
For example, loop and print the following:
a
aa
aaaa
aaaaa
.... keep going ....
aaaaaaaaaaaaaaaaa ....
ab
aba
abaa .............
Till I hit all possible lengths and permutations from my array.
private void method(){
char[] data = "abcdefghiABCDEFGHI0123456789".toCharArray();
// loop and print each time
}
I think it would be silly to come up with 10s of for loops for this. I am guessing some form of recursion would help here but can't get my head around to even start with. Could I get some help with this please? Even if pointing me to a start or a blog or something. Been Googling and looking around and many permutations examples exists but keeps to fixed max length. None seems to have examples on multiple length + permutations. Please advice. Thanks.
Another way to do it is this:
public class HelloWorld{
public static String[] method(char[] arr, int length) {
if(length == arr.length - 1) {
String[] strArr = new String[arr.length];
for(int i = 0; i < arr.length; i ++) {
strArr[i] = String.valueOf(arr[i]);
}
return strArr;
}
String[] before = method(arr, length + 1);
String[] newArr = new String[arr.length * before.length];
for(int i = 0; i < arr.length; i ++) {
for(int j = 0; j < before.length; j ++) {
if(i == 0)
System.out.println(before[j]);
newArr[i * before.length + j] = (arr[i] + before[j]);
}
}
return newArr;
}
public static void main(String []args){
String[] all = method("abcde".toCharArray(), 0);
for(int i = 0; i < all.length; i ++) {
System.out.println(all[i]);
}
}
}
However be careful you'll probably run out of memory or the program will take a looooong time to compile/run if it does at all. You are trying to print 3.437313508041091e+40 strings, that's 3 followed by 40 zeroes.
Here's the solution also in javascript because it starts running but it needs 4 seconds to get to 4 character permutations, for it to reach 5 character permutations it will need about 28 times that time, for 6 characters it's 4 * 28 * 28 and so on.
const method = (arr, length) => {
if(length === arr.length - 1)
return arr;
const hm = [];
const before = method(arr, length + 1);
for(let i = 0; i < arr.length; i ++) {
for(let j = 0; j < before.length; j ++) {
if(i === 0)
console.log(before[j]);
hm.push(arr[i] + before[j]);
}
}
return hm;
};
method('abcdefghiABCDEFGHI0123456789'.split(''), 0).forEach(a => console.log(a));
private void method(){
char[] data = "abcdefghiABCDEFGHI0123456789".toCharArray();
// loop and print each time
}
With your given input there are 3.43731350804×10E40 combinations. (Spelled result in words is eighteen quadrillion fourteen trillion three hundred ninety-eight billion five hundred nine million four hundred eighty-one thousand nine hundred eighty-four. ) If I remember it correctly the maths is some how
1 + x + x^2 + x^3 + x^4 + ... + x^n = (1 - x^n+1) / (1 - x)
in your case
28 + 28^2 + 28^3 + .... 28^28
cause you will have
28 combinations for strings with length one
28*28 combinations for strings with length two
28*28*28 combinations for strings with length three
...
28^28 combinations for strings with length 28
It will take a while to print them all.
One way I can think of is to use the Generex library, a Java library for generating String that match a given regular expression.
Generex github. Look at their page for more info.
Generex maven repo. Download the jar or add dependency.
Using generex is straight forward if you are somehow familiar with regex.
Example using only the first 5 chars which will have 3905 possible combinations
public static void main(String[] args) {
Generex generex = new Generex("[a-e]{1,5}");
System.out.println(generex.getAllMatchedStrings().size());
Iterator iterator = generex.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
Meaning of [a-e]{1,5} any combination of the chars a,b,c,d,e wit a min length of 1 and max length of 5
output
a
aa
aaa
aaaa
aaaaa
aaaab
aaaac
aaaad
aaaae
aaab
aaaba
aaabb
aaabc
aaabd
aaabe
aaac
....
eeee
eeeea
eeeeb
eeeec
eeeed
eeeee
You can have a for loop that starts from 1 and ends at array.length and in each iteration call a function that prints all the permutations for that length.
public void printPermutations(char[] array, int length) {
/*
* Create all permutations with length = length and print them
*/
}
public void method() {
char data = "abcdefghiABCDEFGHI0123456789".toCharArray();
for(int i = 1; i <= data.length; i ++) {
printPermutations(data, i);
}
}
I think the following recursion could solve your problem:
public static void main(String[] args) {
final String[] data = {"a", "b", "c"};
sampleWithReplacement(data, "", 1, 5);
}
private static void sampleWithReplacement(
final String[] letters,
final String prefix,
final int currentLength,
final int maxLength
) {
if (currentLength <= maxLength) {
for (String letter : letters) {
final String newPrefix = prefix + letter;
System.out.println(newPrefix);
sampleWithReplacement(letters, newPrefix, currentLength + 1, maxLength);
}
}
}
where data specifies your possible characters to sample from.
Is this what you're talking about?
public class PrintPermutations
{
public static String stream = "";
public static void printPermutations (char[] set, int count, int length)
{
if (count < length)
for (int i = 0; i < set.length; ++i)
{
stream += set[i];
System.out.println (stream);
printPermutations (set, count + 1, length);
stream = stream.substring (0, stream.length() - 1);
}
}
public static void main (String[] args)
{
char[] set = "abcdefghiABCDEFGHI0123456789".toCharArray();
printPermutations (set, 0, set.length);
}
}
Test it using a smaller string first.
On an input string 28 characters long this method is never going to end, but for smaller inputs it will generate all permutations up to length n, where n is the number of characters. It first prints all permutations of length 1, then all of length 2 etc, which is different from your example, but hopefully order doesn't matter.
static void permutations(char[] arr)
{
int[] idx = new int[arr.length];
char[] perm = new char[arr.length];
Arrays.fill(perm, arr[0]);
for (int i = 1; i < arr.length; i++)
{
while (true)
{
System.out.println(new String(perm, 0, i));
int k = i - 1;
for (; k >= 0; k--)
{
idx[k] += 1;
if (idx[k] < arr.length)
{
perm[k] = arr[idx[k]];
break;
}
idx[k] = 0;
perm[k] = arr[idx[k]];
}
if (k < 0)
break;
}
}
}
Test:
permutations("abc".toCharArray());
Output:
a
b
c
aa
ab
ac
ba
bb
bc
ca
cb
cc
I want to sort the strings in the array, by alphabetizing them, but I get an error with argument types.
public class BubbleSort {
public static String[] sortStringArray(String[] stringArray) {
int s = stringArray.length;
String temp;
for (int i = 0 ; i < s; i++) {
for (int j = 1; j < (s - i); j++) {
String a1 = stringArray[j - 1];
String b1 = stringArray[j];
int result = a1.compareTo(b1);
if (result > stringArray[j]) {
temp = stringArray[j - 1];
stringArray[j - 1] = stringArray[j];
stringArray[j] = temp;
}
}
}
return stringArray;
}
}
Since you're calling compareTo(Object) on Strings, you need to check then if the result is bigger than zero:
if (0 < result) { // i.e. a1 is smaller than b1
//swap values as usual
}
To sort a String array by natural ordering you can use Arrays.stream
eg:
String[] s = {"b", "c", "a", "aaa", "abc"};
s = Arrays.stream(s).sorted().toArray(String[]::new);
gives s= [a, aaa, abc, b, c]
if (result > stringArray[j])
result is an integer, stringarray[j] is a string.
You can't compare with integer like that, if your string is an integer like stinrgArray[j] value is "11" and you want to compare it you need to parse it first to integer:
if(result > Integer.parseInt(stringArray[j]))
I have this code to find all pairs of string to form a palindrome. e.g) D: { AB, DEEDBA } => AB + DEEDBA -> YES and will be returned. Another example, { NONE, XENON } => NONE + XENON = > YES.
What would be running time of this ?
public static List<List<String>> pairPalindrome(List<String> D) {
List<List<String>> pairs = new LinkedList<>();
Set<String> set = new HashSet<>();
for (String s : D) {
set.add(s);
}
for (String s : D) {
String r = reverse(s);
for (int i = 0; i <= r.length(); i++) {
String prefix = r.substring(0, i);
if (set.contains(prefix)) {
String suffix = r.substring(i);
if (isPalindrom(suffix)) {
pairs.add(Arrays.asList(s, prefix));
}
}
}
}
return pairs;
}
private static boolean isPalindrom(String s) {
int i = 0;
int j = s.length() - 1;
char[] c = s.toCharArray();
while (i < j) {
if (c[i] != c[j]) {
return false;
}
i++;
j--;
}
return true;
}
private static String reverse(String s) {
char[] c = s.toCharArray();
int i = 0;
int j = c.length - 1;
while (i < j) {
char temp = c[i];
c[i] = c[j];
c[j] = temp;
i++;
j--;
}
return new String(c);
}
I'm going to take a few guesses here as I don't have much experience with Java.
First, isPalindrome is O(N) with the size of suffix string. Add operation to 'pairs' would probably be O(1).
Then, we have the for loop, it's O(N) with the length of r. Getting a substring I'd think is O(M) with the size of the substring. Checking if a hashmap contains a certain key, with a perfect hash function would be (IIRC) O(1), in your case we can assume O(lgN) (possibly). So, first for loop has O(NMlgK), where K is your hash table size, N is r's length and M is substring's length.
Finally we have the outmost for loop, it runs for each string in the string list, so that's O(N). Then, we reverse each of them. So for each of these strings we have another O(N) operation inside, with the other loop being O(NMlgK). So, overall complexity is O(L(N + NMlgK)), where L is the amount of strings you have. But, it'd reduce to O(LNMlgK). I'd like if someone verified or corrected my mistakes.
EDIT: Actually, substring length will at most be N, as the length of the entire string, so M is actually N. Now I'd probably say it's O(LNlgK).
If the input is 'abba' then the possible palindromes are a, b, b, a, bb, abba.
I understand that determining if string is palindrome is easy. It would be like:
public static boolean isPalindrome(String str) {
int len = str.length();
for(int i=0; i<len/2; i++) {
if(str.charAt(i)!=str.charAt(len-i-1) {
return false;
}
return true;
}
But what is the efficient way of finding palindrome substrings?
This can be done in O(n), using Manacher's algorithm.
The main idea is a combination of dynamic programming and (as others have said already) computing maximum length of palindrome with center in a given letter.
What we really want to calculate is radius of the longest palindrome, not the length.
The radius is simply length/2 or (length - 1)/2 (for odd-length palindromes).
After computing palindrome radius pr at given position i we use already computed radiuses to find palindromes in range [i - pr ; i]. This lets us (because palindromes are, well, palindromes) skip further computation of radiuses for range [i ; i + pr].
While we search in range [i - pr ; i], there are four basic cases for each position i - k (where k is in 1,2,... pr):
no palindrome (radius = 0) at i - k
(this means radius = 0 at i + k, too)
inner palindrome, which means it fits in range
(this means radius at i + k is the same as at i - k)
outer palindrome, which means it doesn't fit in range
(this means radius at i + k is cut down to fit in range, i.e because i + k + radius > i + pr we reduce radius to pr - k)
sticky palindrome, which means i + k + radius = i + pr
(in that case we need to search for potentially bigger radius at i + k)
Full, detailed explanation would be rather long. What about some code samples? :)
I've found C++ implementation of this algorithm by Polish teacher, mgr Jerzy Wałaszek.
I've translated comments to english, added some other comments and simplified it a bit to be easier to catch the main part.
Take a look here.
Note: in case of problems understanding why this is O(n), try to look this way:
after finding radius (let's call it r) at some position, we need to iterate over r elements back, but as a result we can skip computation for r elements forward. Therefore, total number of iterated elements stays the same.
Perhaps you could iterate across potential middle character (odd length palindromes) and middle points between characters (even length palindromes) and extend each until you cannot get any further (next left and right characters don't match).
That would save a lot of computation when there are no many palidromes in the string. In such case the cost would be O(n) for sparse palidrome strings.
For palindrome dense inputs it would be O(n^2) as each position cannot be extended more than the length of the array / 2. Obviously this is even less towards the ends of the array.
public Set<String> palindromes(final String input) {
final Set<String> result = new HashSet<>();
for (int i = 0; i < input.length(); i++) {
// expanding even length palindromes:
expandPalindromes(result,input,i,i+1);
// expanding odd length palindromes:
expandPalindromes(result,input,i,i);
}
return result;
}
public void expandPalindromes(final Set<String> result, final String s, int i, int j) {
while (i >= 0 && j < s.length() && s.charAt(i) == s.charAt(j)) {
result.add(s.substring(i,j+1));
i--; j++;
}
}
So, each distinct letter is already a palindrome - so you already have N + 1 palindromes, where N is the number of distinct letters (plus empty string). You can do that in single run - O(N).
Now, for non-trivial palindromes, you can test each point of your string to be a center of potential palindrome - grow in both directions - something that Valentin Ruano suggested.
This solution will take O(N^2) since each test is O(N) and number of possible "centers" is also O(N) - the center is either a letter or space between two letters, again as in Valentin's solution.
Note, there is also O(N) solution to your problem, based on Manacher's algoritm (article describes "longest palindrome", but algorithm could be used to count all of them)
I just came up with my own logic which helps to solve this problem.
Happy coding.. :-)
System.out.println("Finding all palindromes in a given string : ");
subPal("abcacbbbca");
private static void subPal(String str) {
String s1 = "";
int N = str.length(), count = 0;
Set<String> palindromeArray = new HashSet<String>();
System.out.println("Given string : " + str);
System.out.println("******** Ignoring single character as substring palindrome");
for (int i = 2; i <= N; i++) {
for (int j = 0; j <= N; j++) {
int k = i + j - 1;
if (k >= N)
continue;
s1 = str.substring(j, i + j);
if (s1.equals(new StringBuilder(s1).reverse().toString())) {
palindromeArray.add(s1);
}
}
}
System.out.println(palindromeArray);
for (String s : palindromeArray)
System.out.println(s + " - is a palindrome string.");
System.out.println("The no.of substring that are palindrome : "
+ palindromeArray.size());
}
Output:-
Finding all palindromes in a given string :
Given string : abcacbbbca
******** Ignoring single character as substring palindrome ********
[cac, acbbbca, cbbbc, bb, bcacb, bbb]
cac - is a palindrome string.
acbbbca - is a palindrome string.
cbbbc - is a palindrome string.
bb - is a palindrome string.
bcacb - is a palindrome string.
bbb - is a palindrome string.
The no.of substring that are palindrome : 6
I suggest building up from a base case and expanding until you have all of the palindomes.
There are two types of palindromes: even numbered and odd-numbered. I haven't figured out how to handle both in the same way so I'll break it up.
1) Add all single letters
2) With this list you have all of the starting points for your palindromes. Run each both of these for each index in the string (or 1 -> length-1 because you need at least 2 length):
findAllEvenFrom(int index){
int i=0;
while(true) {
//check if index-i and index+i+1 is within string bounds
if(str.charAt(index-i) != str.charAt(index+i+1))
return; // Here we found out that this index isn't a center for palindromes of >=i size, so we can give up
outputList.add(str.substring(index-i, index+i+1));
i++;
}
}
//Odd looks about the same, but with a change in the bounds.
findAllOddFrom(int index){
int i=0;
while(true) {
//check if index-i and index+i+1 is within string bounds
if(str.charAt(index-i-1) != str.charAt(index+i+1))
return;
outputList.add(str.substring(index-i-1, index+i+1));
i++;
}
}
I'm not sure if this helps the Big-O for your runtime, but it should be much more efficient than trying each substring. Worst case would be a string of all the same letter which may be worse than the "find every substring" plan, but with most inputs it will cut out most substrings because you can stop looking at one once you realize it's not the center of a palindrome.
I tried the following code and its working well for the cases
Also it handles individual characters too
Few of the cases which passed:
abaaa --> [aba, aaa, b, a, aa]
geek --> [g, e, ee, k]
abbaca --> [b, c, a, abba, bb, aca]
abaaba -->[aba, b, abaaba, a, baab, aa]
abababa -->[aba, babab, b, a, ababa, abababa, bab]
forgeeksskeegfor --> [f, g, e, ee, s, r, eksske, geeksskeeg,
o, eeksskee, ss, k, kssk]
Code
static Set<String> set = new HashSet<String>();
static String DIV = "|";
public static void main(String[] args) {
String str = "abababa";
String ext = getExtendedString(str);
// will check for even length palindromes
for(int i=2; i<ext.length()-1; i+=2) {
addPalindromes(i, 1, ext);
}
// will check for odd length palindromes including individual characters
for(int i=1; i<=ext.length()-2; i+=2) {
addPalindromes(i, 0, ext);
}
System.out.println(set);
}
/*
* Generates extended string, with dividors applied
* eg: input = abca
* output = |a|b|c|a|
*/
static String getExtendedString(String str) {
StringBuilder builder = new StringBuilder();
builder.append(DIV);
for(int i=0; i< str.length(); i++) {
builder.append(str.charAt(i));
builder.append(DIV);
}
String ext = builder.toString();
return ext;
}
/*
* Recursive matcher
* If match is found for palindrome ie char[mid-offset] = char[mid+ offset]
* Calculate further with offset+=2
*
*
*/
static void addPalindromes(int mid, int offset, String ext) {
// boundary checks
if(mid - offset <0 || mid + offset > ext.length()-1) {
return;
}
if (ext.charAt(mid-offset) == ext.charAt(mid+offset)) {
set.add(ext.substring(mid-offset, mid+offset+1).replace(DIV, ""));
addPalindromes(mid, offset+2, ext);
}
}
Hope its fine
public class PolindromeMyLogic {
static int polindromeCount = 0;
private static HashMap<Character, List<Integer>> findCharAndOccurance(
char[] charArray) {
HashMap<Character, List<Integer>> map = new HashMap<Character, List<Integer>>();
for (int i = 0; i < charArray.length; i++) {
char c = charArray[i];
if (map.containsKey(c)) {
List list = map.get(c);
list.add(i);
} else {
List list = new ArrayList<Integer>();
list.add(i);
map.put(c, list);
}
}
return map;
}
private static void countPolindromeByPositions(char[] charArray,
HashMap<Character, List<Integer>> map) {
map.forEach((character, list) -> {
int n = list.size();
if (n > 1) {
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (list.get(i) + 1 == list.get(j)
|| list.get(i) + 2 == list.get(j)) {
polindromeCount++;
} else {
char[] temp = new char[(list.get(j) - list.get(i))
+ 1];
int jj = 0;
for (int ii = list.get(i); ii <= list
.get(j); ii++) {
temp[jj] = charArray[ii];
jj++;
}
if (isPolindrome(temp))
polindromeCount++;
}
}
}
}
});
}
private static boolean isPolindrome(char[] charArray) {
int n = charArray.length;
char[] temp = new char[n];
int j = 0;
for (int i = (n - 1); i >= 0; i--) {
temp[j] = charArray[i];
j++;
}
if (Arrays.equals(charArray, temp))
return true;
else
return false;
}
public static void main(String[] args) {
String str = "MADAM";
char[] charArray = str.toCharArray();
countPolindromeByPositions(charArray, findCharAndOccurance(charArray));
System.out.println(polindromeCount);
}
}
Try out this. Its my own solution.
// Maintain an Set of palindromes so that we get distinct elements at the end
// Add each char to set. Also treat that char as middle point and traverse through string to check equality of left and right char
static int palindrome(String str) {
Set<String> distinctPln = new HashSet<String>();
for (int i=0; i<str.length();i++) {
distinctPln.add(String.valueOf(str.charAt(i)));
for (int j=i-1, k=i+1; j>=0 && k<str.length(); j--, k++) {
// String of lenght 2 as palindrome
if ( (new Character(str.charAt(i))).equals(new Character(str.charAt(j)))) {
distinctPln.add(str.substring(j,i+1));
}
// String of lenght 2 as palindrome
if ( (new Character(str.charAt(i))).equals(new Character(str.charAt(k)))) {
distinctPln.add(str.substring(i,k+1));
}
if ( (new Character(str.charAt(j))).equals(new Character(str.charAt(k)))) {
distinctPln.add(str.substring(j,k+1));
} else {
continue;
}
}
}
Iterator<String> distinctPlnItr = distinctPln.iterator();
while ( distinctPlnItr.hasNext()) {
System.out.print(distinctPlnItr.next()+ ",");
}
return distinctPln.size();
}
Code is to find all distinct substrings which are palindrome.
Here is the code I tried. It is working fine.
import java.util.HashSet;
import java.util.Set;
public class SubstringPalindrome {
public static void main(String[] args) {
String s = "abba";
checkPalindrome(s);
}
public static int checkPalindrome(String s) {
int L = s.length();
int counter =0;
long startTime = System.currentTimeMillis();
Set<String> hs = new HashSet<String>();
// add elements to the hash set
System.out.println("Possible substrings: ");
for (int i = 0; i < L; ++i) {
for (int j = 0; j < (L - i); ++j) {
String subs = s.substring(j, i + j + 1);
counter++;
System.out.println(subs);
if(isPalindrome(subs))
hs.add(subs);
}
}
System.out.println("Total possible substrings are "+counter);
System.out.println("Total palindromic substrings are "+hs.size());
System.out.println("Possible palindromic substrings: "+hs.toString());
long endTime = System.currentTimeMillis();
System.out.println("It took " + (endTime - startTime) + " milliseconds");
return hs.size();
}
public static boolean isPalindrome(String s) {
if(s.length() == 0 || s.length() ==1)
return true;
if(s.charAt(0) == s.charAt(s.length()-1))
return isPalindrome(s.substring(1, s.length()-1));
return false;
}
}
OUTPUT:
Possible substrings:
a
b
b
a
ab
bb
ba
abb
bba
abba
Total possible substrings are 10
Total palindromic substrings are 4
Possible palindromic substrings: [bb, a, b, abba]
It took 1 milliseconds