Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have been trying to solve a problem of finding longest palindrome of a String.
Though I am able to do it by going to middle element but i wanted to try it through string.reverse :
Here is my code :
Doubt : I am using string.reverse to find the reverse of the given string and Then trying to compare each and every substring in reversed string and input string, but this will not give me largest palindrome but it will give all the possible palindromes...
Also I am doing some mistake somewhere, kindly help me to find that...
public class StringPalindrome {
public static void main(String args[]) {
StringBuilder strBuilder = new StringBuilder("Shubham");
StringBuilder a = new StringBuilder("");
a = strBuilder.reverse(); //Reverse the string and saving it into other string
for(int i=0;i<strBuilder.length();i++){ // Loop one for begin index
for(int j=1;i<strBuilder.length() + 1;j++){ // Loop two for end index
if(a.substring(i, j).equals(strBuilder.substring(i, j))){ // comparing
System.out.println(strBuilder.substring(i, j)); //printing palindrome
}
}
}
}
I am not able to think to How to find longest Palindrome ?
I think by using string.reverse, it will be a short code :
Though I am able to do it this way :
public class LongestPalindrome
{
static public String expand(String string, int a, int b)
{
if (a > b)
return null;
int left = a, right = b;
while (left >= 0 && right < string.length() && string.charAt(left) == string.charAt(right))
{
left--;
right++;
}
return string.substring(left + 1, right);
}
static public String longestPalindrome(String string)
{
if (string == null)
return null;
String longest = string.substring(0, 1);
for (int i = 0; i < string.length() - 1; i++)
{
String palindrome = expand(string, i, i);
if (palindrome.length() > longest.length())
{
longest = palindrome;
}
palindrome = expand(string, i, i + 1);
if (palindrome.length() > longest.length())
{
longest = palindrome;
}
}
return longest;
}
public static void main(String[] args)
{
System.out.println(longestPalindrome("baraik"));
}
}
public class StringPalindrome {
public static void main(String args[]) {
int big=0;
String pstr ="";
StringBuilder str = new StringBuilder("aabbccabbabhhakllkjiooijpawan-nawap");
for(int i=0;i<str.length()-1;i++)
for(int j=i+1;j<str.length();j++){
if(str.charAt(i)== str.charAt(j) && pldrm(str.subSequence(i,j+1).toString()) && big<(j-i)){
pstr=str.subSequence(i,j+1).toString();
big=j-i;
}
}
System.out.println(pstr);
}
static boolean pldrm(String str){
int length=str.length()-1;
for(int i=0;i<length;i++){
if(str.charAt(i)!= str.charAt(length-i))
return false;
}
return true;
}
}
output is
pawan-nawap
So, finally I found out that you were looking for the longest palindrome in a string.
Observe the base case for a palindrome for
For any given index i(which progresses from 0 to end of the string) and j(which progresses from end of the string to 0)
Indices of j and i are equal. They are obviously equal. Single character strings are palindromes.
Indices of i and j differ by exactly 1. ie. You are comparing consecutive characters. If they are equal you have found a 2 character palindrome.
Else we have 2 ways to go to step 1 or 2.
Consider string from index[i, j - 1]
Consider string from index[i + 1, j]
Max of the above 2 conditions gives you the length of the longest palindrome.
Memoize steps 1, 2, 3 to get the values from a cache.
Here is a sample implementation which prints all the palindromes. This is O(n**2).
public static int maxPalindrome(char ch[], int i, int j, int cache[][]) {
if (cache[i][j] != -1) {
return cache[i][j];
}
if (i == j) {
return cache[i][j] = 1;
}
if (j - i == 1) {
return cache[i][j] = (ch[i] == ch[j] ? 2 : 0);
}
int max = 0;
//easy if they are equal
if (ch[i] == ch[j]) {
int inCount = maxPalindrome(ch, i + 1, j - 1, cache);
max = inCount == 0 ? 0 : 2 + inCount;
}
//there are 2 ways to go step 3
maxPalindrome(ch, i + 1, j, cache);
maxPalindrome(ch, i, j - 1, cache);
return cache[i][j] = max;
}
public static void main(String[] args) {
String str = "abbzbasddeeaaaccffertrecca";
char ch[] = str.toCharArray();
int cache[][] = new int[ch.length][ch.length];
for (int row[] : cache) {
Arrays.fill(row, -1);
}
maxPalindrome(ch, 0, ch.length - 1, cache);
//print all the pallindromes
for (int i = 0; i < cache.length; ++i) {
for (int j = 0; j < cache.length; ++j) {
if (cache[i][j] > 0) {
System.out.println(str.substring(i, j+1) + " " + cache[i][j]);
}
}
}
}
Returns
bb 2
bzb 3
z 1
dd 2
ee 2
aa 2
aaa 3
a 1
aa 2
cc 2
ff 2
ertre 5
rtr 3
t 1
cc 2
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I am trying to write a recursive algorithm to compute Fibonacci numbers. However, the program struggles with printing out the results.
My idea was to store each calculated value into an array (so the algorithm should be faster).
My desired output:
The fibonacci of n = 1 is fn= 1
The fibonacci of n = 2 is fn= 2
The fibonacci of n = 3 is fn= 2
The fibonacci of n = 4 is fn= 3
...
The fibonacci of n = 8 is fn= 21
public class fibonacciCalculator {
static int[] arr = new int[50];
static int fibo (int n, int arr[]) {
if ( n == 0 ) {
return 0;
}else if ( n == 1 ) {
return 1;
}
if ( arr[n-1] == 0) {
arr[n-1] = fibo(n-1, arr);
}
if ( arr[n-2] == 0) {
arr[n-2] = fibo(n-2, arr);
}
return arr[n-1] + arr[n - 2];
}
public static void main(String[] args) {
for (int i = 1; i == 8; i++) {
if (arr [i] == 0) {
fibo(i, arr);
int x = arr[i];
String a = String.format("The fibonacci of n = %d is fn= %d", i , x);
System.out.println(a);
}
}
}
}
You can do this without declaring an array. This way, the intermediate values are stored in the execution stack:
public class fibonacciCalculator {
static int fibo (int n) {
if ( n == 0 ) {
return 0;
} else if ( n == 1 ) {
return 1;
} else {
return fibo(n-2) + fibo(n-1);
}
}
public static void main(String[] args) {
for (int i = 1; i <= 8; i++) {
int x = fibo(i);;
String a = String.format("The fibonacci of n = %d is fn= %d", i , x);
System.out.println(a);
}
}
}
Here is one way to do it.
public int[] fib(int values[], int count) {
if (count <= 0) {
return values;
}
int k = values.length + 1;
values = Arrays.copyOf(values, k);
values[k - 1] = values[k - 2] + values[k - 3];
return fib(values, count - 1);
}
But an even better way is to memoize the values as you create them. This permits you to start calculating at the last computed terms and then continue until you meet your goal. If you specify a value less than the number computed, only those requested are returned.
A defensive copy of the list is used so you can't taint the returned sublist.
List<Integer> fibs = new ArrayList(List.of(0, 1));
public List<Integer> fib(int count) {
int s = fibs.size();
if (count < s) {
// return a defensive copy to protect cached values.
return new ArrayList<>(fibs.subList(0, count));
}
int e = fibs.get(s - 1) + fibs.get(s - 2);
fibs.add(e);
return fib(count);
}
Okay to close this up I will post the working code.
Maybe that will help anyone else.
public class fibonacciCalculator {
static int[] arr = new int[48];
static int fibo (int n, int arr[]) {
if ( n == 1|| n == 2 ) {
return 1;
}else if ( n == 0 ) {
return 0;
}
if (arr[n-1] == 0) {
arr[n-1] = fibo(n-1, arr);
}
if (arr[n-2] == 0) {
arr[n-2] = fibo(n-2, arr);
}
return arr[n-1] + arr[n - 2];
}
public static void main(String[] args) {
for (int i = 1; i <= arr.length-1; i++) {
if (arr [i] == 0) {
arr[i] = fibo(i, arr);
System.out.print("The Fibonacci number " + i);
System.out.println(" is: " + arr[i]);
}
}
}
}
However ... int will exceed its limit at Fibonacci 48. If you want higher values int should be replaced to long.
but after that well don't know.. :D
Greetings Synix
Given a string representing the starting number and a maximum number of changes allowed, create the largest palindromic string of digits possible or the string -1 if it's impossible to create a palindrome under the contstraints.
I wrote a code who answer on the questions, but i have an error that i dont know where it is, or if even the code work.
static String highestValuePalindrome(String s, int n, int k) {
for(int i =0 ; i < n ; i++){
char[] ch =s.toCharArray();
if(n==1)
return s ;
else if ((ch[i] != ch[n-i-1]) && (k != 0) ){
ch[i] = ch[n-i-1] = 9 ;
k--;
}
}
String str = new String(ch);
return str ;
}
Output Format
Print a single line with the largest number that can be made by changing no more than digits. If this is not possible, print -1.
Sample Input
n=4, k=1
3943
Sample Output
3993
Sample Input
n=6, k=3
092282
Sample Output
992299
Sample Input
n=4, k=1
0011
Sample Output
-1
First of all there is no need to pass n as a parameter because it's just the length of the string. Secondly, this is not the complete program. I have made many changes to the given code.
public class largestPalindorme {
public static void main(String[] args) {
System.out.println(highestValuePalindrome("0011", 1));
}
static String highestValuePalindrome(String s, int k) {
char[] ch = s.toCharArray();
int n = s.length(); // which is same as n which you passed as parameter
int minChangesRequired = MinumumChangesNeeded(s);
//if the changes required to make the given string a palindrome is less then k then only it will go inside or it will return -1
if (k >= minChangesRequired) {
int diff = 0;
if (k > minChangesRequired) {
diff = k - minChangesRequired;
for (int l = 0; l < diff; l++) {
ch[l] = '9';
ch[n - l - 1] = '9';
}
}
for (int i = diff; i < n - diff / 2; i++) {
if (ch[i] != ch[n - i - 1]) {
//if checks which number is greater
int greater = Integer.parseInt(String.valueOf(ch[i])) > Integer.parseInt(String.valueOf(ch[n - i - 1])) ? Integer.parseInt(String.valueOf(ch[i])) : Integer.parseInt(String.valueOf(ch[n - i - 1]));
//replaces the smaller number from the greater number.
if (Integer.parseInt(String.valueOf(ch[i])) != greater) {
ch[i] = ch[n - i - 1];
} else {
ch[n - i - 1] = ch[i];
}
}
}
String str = new String(ch);
return str;
}
return "-1";
}
//this function returns the minimum changes we need to do to make it a palindrome.
public static int MinumumChangesNeeded(String s) {
int count = 0;
char[] ch = s.toCharArray();
int n = s.length();
for (int i = 0; i < n / 2; i++) {
if (ch[i] != ch[n - i - 1]) {
count++;
}
}
return count;}}
For a given positive integer N of not more than 1000000 digits, write the value of the smallest palindrome larger than N to output.
Here is my code:
public class Palin {
public static String reverseString(String s) {
String newS = "";
for(int i = s.length() - 1; i >= 0; i--)
newS += s.charAt(i);
return newS;
}
public static String getPalin(String s) {
int lth = s.length();
String left = "", mid = "", right = "", newS = "";
if(lth % 2 != 0) {
left = s.substring(0, lth / 2);
mid = s.substring(lth / 2, lth / 2 + 1);
right = reverseString(left);
newS = left + mid + right;
if(s.compareTo(newS) < 0) return newS;
else {
int temp = Integer.parseInt(mid);
temp++;
mid = Integer.toString(temp);
newS = left + mid + right;
return newS;
}
}
else {
left = s.substring(0, lth / 2 - 1);
mid = s.substring(lth / 2 - 1, lth / 2);
right = reverseString(left);
newS = left + mid + mid + right;
if(s.compareTo(newS) < 0) return newS;
else {
int temp = Integer.parseInt(mid);
temp++;
mid = Integer.toString(temp);
newS = left + mid + mid + right;
return newS;
}
}
}
public static void main(String[] args) throws java.lang.Exception {
Scanner input = new Scanner(System.in);
//Scanner input = new Scanner(System.in);
int k = input.nextInt();
String[] s = new String[k];
for(int i = 0; i < k; i++) {
s[i] = input.next();
}
for(int i = 0; i < k; i++) {
System.out.println(getPalin(s[i]));
}
}
}
My idea is use a String represent for a number. I divide this String into 2 part, coppy first part and reverse it for second part. I think my solve is correct but it not fast enough. I need a more efficient algorithm.
Thanks
EDITED
Since you said that:
For a given positive integer N of not more than 1000000 digits
My previous solution won't work since I have converted them to int and an int can't accommodate 1000000 digits. Thus I have made a new approach, an approach that doesn't need any String to int conversion.
Refer to the code and comment below for details.
CODE:
package main;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// Scanner input = new Scanner(System.in);
int k = Integer.parseInt(input.nextLine());
String[] s = new String[k];
for (int i = 0; i < k; i++) {
s[i] = input.nextLine();
}
for (int i = 0; i < k; i++) {
System.out.println(getPalin(s[i]));
}
input.close();
}
public static String getPalin(String s) {
// initialize the result to "" since if input is 1 digit, nothing is printed
String result = "";
// if input is greater than 1000000 digits
if (s.length() >= 1000000) {
// return the highest palindrome less than 1000000
result = "999999";
} else if (s.length() > 1) {
// get the middle index of the string
int mid = s.length() % 2 == 0 ? s.length() / 2 : (s.length() / 2) + 1;
// get the left part of the string
String leftPart = getPalindrome(s.substring(0, mid));
if (s.length() % 2 == 0) {
// attach the left part and the reverse left part
result = leftPart + new StringBuilder(leftPart).reverse().toString();
} else {
// attach the left part and the reverse left part excluding the middle digit
result = leftPart
+ new StringBuilder(leftPart.substring(0, leftPart.length() - 1)).reverse().toString();
}
// check if the new result greater than 1000000 digits
if (result.length() >= 1000000) {
// return the highest palindrome less than 1000000
result = "999999";
}
}
return result;
}
public static String getPalindrome(String param) {
String result = "";
// iterate through the string from last index until index 0
for (int i = param.length() - 1; i >= 0; i--) {
// get the char at index i
char c = param.charAt(i);
/*
* increment char since the next palindrome is the current digit + 1. Example:
* User input is 121, then param will be 12 so the next is 13
*/
c++;
/*
* check if the current character is greater than '9', which means it is not a
* digit after incrementing
*/
if (c > '9') {
// set the current char to 0
c = '0';
// check if index is at index 0
if (i - 1 < 0) {
// if at index 0 then add '1' at start
result = '1' + result;
} else {
// if not then append c at result
result = result + c;
}
} else {
// check if index is at index 0
if (i - 1 < 0) {
// if not then prepend c at result
result = c + result;
} else {
// if not then get the rest of param then append c and result
result = param.substring(0, i) + c + result;
}
break;
}
}
return result;
}
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
What is the most efficient way to solve this problem using Java ?
For example: generate all numbers containing three 1's & two 0's
Solution:
11100
11010
10110
01110
11001
10101
01101
10011
01011
00111
You can use recursion:
public static void generateBits(String s, int ones, int zeros)
{
if(ones > 0)
generateBits(s + "1", ones - 1, zeros);
if(zeros > 0)
generateBits(s + "0", ones, zeros - 1);
if(ones == 0 && zeros == 0)
System.out.println(s);
}
The function accepts a partially completed string and a count of how many ones and zeros are left to add, then recurses for the case of adding a one and adding a zero (if any are remaining). When there are no more left to add it prints the string. This will generate each number once with no duplicates. You can parse the string into a number if you need to instead of printing it out. Call like this:
generateBits("", 3, 2);
I used the String type to allow leading zeros, while keeping it simple, however as pointed out in a comment by #Aivean, string concantenation can be expensive. Here's an alternative, more efficient solution that uses longs, and converts to a binary string representation with leading zeros when printing out the values:
public static void generateBits(long val, int ones, int zeros, int len)
{
if(ones > 0)
generateBits((val << 1) + 1L, ones - 1, zeros, len + 1);
if(zeros > 0)
generateBits(val << 1, ones, zeros - 1, len + 1);
if(ones == 0 && zeros == 0)
System.out.println(String.format("%"+len+"s", Long.toBinaryString(val)).replace(' ', '0'));
}
You need to pass in 0 for the length when calling it at the top level. You would call it like this:
generateBits(0L, 3, 2, 0);
Here's non-recursive BitSet-based solution:
static void genCombinations(int n, int k) {
BitSet bs = new BitSet(n);
bs.set(0, k);
while(true) {
// output
for(int i=0; i<n; i++)
System.out.print(bs.get(i) ? "1" : "0");
System.out.println();
int b = bs.previousClearBit(n-1); // the last zero
int b1 = bs.previousSetBit(b); // the last one before that zero
if(b1 == -1)
return;
bs.clear(b1);
bs.set(b1+1, b1+(n-b)+1);
bs.clear(b1+(n-b)+1, n);
}
}
public static void main(String[] args) {
genCombinations(5, 3);
}
Such iterative approach sometimes more convenient as you can create an Iterable class like this:
public static class Combinations implements Iterable<String> {
private int n;
private int k;
public Combinations(int n, int k) {
this.n = n;
this.k = k;
}
#Override
public Iterator<String> iterator() {
return new Iterator<String>() {
BitSet bs = new BitSet(n);
{
bs.set(0, k);
}
#Override
public boolean hasNext() {
return bs != null;
}
#Override
public String next() {
char[] res = new char[n];
for (int i = 0; i < n; i++)
res[i] = bs.get(i) ? '1' : '0';
int b = bs.previousClearBit(n - 1);
int b1 = bs.previousSetBit(b);
if (b1 == -1)
bs = null;
else {
bs.clear(b1);
bs.set(b1 + 1, b1 + (n - b) + 1);
bs.clear(b1 + (n - b) + 1, n);
}
return new String(res);
}
};
}
}
And use it in the for loop:
for(String comb : new Combinations(5, 3)) {
System.out.println(comb);
}
To get an int with leading zero's, you will have to generate it as a String. This is the fastest way without duplicates:
public final class Permutator {
public static void main(String[] args) {
new Permutator(3, 5);
}
public Permutator(int numberOfOnes, int length) {
StringBuilder start = new StringBuilder();
for (int x = 0; x < length; x++)
start.append('0');
permutate(numberOfOnes, 0, 0, length, start);
System.exit(0);
}
public void permutate(int numberOfOnes, int first, int depth, int length, StringBuilder base) {
for (int x = first; x < length; x++) {
StringBuilder onesAndZeros = new StringBuilder(base.toString());
onesAndZeros.setCharAt(x, '1');
if (numberOfOnes == depth + 1)
System.out.println(onesAndZeros.toString());
else
permutate(numberOfOnes, x + 1, depth + 1, length, onesAndZeros);
}
}
}
Nice puzzle, not utmost optimized, but my attempt: 0/1 for bit in int, recursion on ones only (and bit count). The number of results is (ones + zeros over ones).
int ones = 3;
int zeroes = 2;
allIntsWithOnesAndZeroes(ones, zeroes);
public static void allIntsWithOnesAndZeroes(int ones, int zeroes) {
int bitCount = ones + zeroes;
int bits = 0;
SortedSet<Integer> results = new TreeSet<>();
all(results, bits, 0, bitCount, ones);
System.out.printf("(%d over %d) = %d, #%d: %s%n",
bitCount, ones, over(bitCount, ones), results.size(), results);
long a = 0;
for (int n : results) {
System.out.println("- " + Integer.toBinaryString(n));
a |= 1L << n;
}
System.out.printf("all: %s%n", Long.toBinaryString(a));
}
private static void all(Set<Integer> results, int bits, int i, int bitCount, int ones) {
if (ones == 0) {
results.add(bits); // Assumes ones > 0.
}
if (i >= bitCount) {
return;
}
all(results, bits, i + 1, bitCount, ones);
int bits2 = bits | (1 << i);
all(results, bits2, i + 1, bitCount, ones - 1);
}
Some math:
public static long fac(long x) {
long n = 1;
while (x > 1) {
n *= x;
--x;
}
return n;
}
public static long over(long x, long y) {
return fac(x) / fac(y) / fac(x - y);
}
String s="101010101010";
String sub=""; //substring
int k=2;
package coreJava;
import java.util.Scanner;
public class substring {
public static void main(String args[])
{
String string, sub;
int k, c, i;
Scanner in = new Scanner(System.in);
System.out.println("Enter a string to print it's all substrings");
string = in.nextLine();
i = string.length();
System.out.println("Substrings of \""+string+"\" are :-");
for( c = 0 ; c < i ; c++ )
{
for( k = 1 ; k <= i - c ; k++ )
{
sub = string.substring(c, c+k);
System.out.println(sub);
}
}
}
}
take a binary string s="1010011010"; //etc
take one variable k=2;
take another variable i; //which is the length of the sub string(i>k)
now i want to find sub string of the above string, in such a way that if k=2,the number of 1's in sub string must be 2,if k=3,the number of 1's in substring must be 3 and so on...
Output should be like this:
string s="1010011010"
Enter value of k=2;
Enter length of substring i=3;
substring= 101 110 101 011
Create a "window" the length of your desired substrings which you move along the string, maintaining a count of the number of 1s in your current window. Each iteration you move the window along one, testing the next character outside the current window, the first character in the current window and updating the count accordingly. During each iteration, if your count is equal to the desired length, print the substring from the current window.
public class Substring {
public static void main(String[] args) {
String str = "1010011010";
int k = 2;
int i = 3;
printAllSubstrings(str, i, k);
}
private static void printAllSubstrings(String str, int substringLength, int numberOfOnes) {
// start index of the current window
int startIndex = 0;
// count of 1s in current window
int count = 0;
// count 1s in the first i characters
for (int a = 0; a < substringLength; a++) {
if (str.charAt(a) == '1') {
count++;
}
}
while (startIndex < str.length() - substringLength + 1) {
if (count == numberOfOnes) {
System.out.print(str.substring(startIndex, startIndex + substringLength));
System.out.print(" ");
}
// Test next bit, which will be inside the window next iteration
if (str.length() > startIndex + substringLength && str.charAt(startIndex + substringLength) == '1') {
count ++;
}
// Test the starting bit, which will be outside the window next iteration
if (str.charAt(startIndex) == '1') {
count --;
}
startIndex++;
}
}
}
This outputs:
101 011 110 101
Iterate over the characters and count the number of one's. If the counter reaches the desired number, stop iterating and take the substring from index zero to where you got.
String str = "010101001010";
int count = 0;
int k = 2;
int i = 0;
for (; i < str.length() && count < k; ++i)
{
if (str.charAt(i) == '1') count++;
}
You could use regular expressions:
public class BinaryString {
public static void main(String[] args) {
String binary = "11000001101110";
int count = 3;
String regEx = "1{" + count + "}";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(binary);
if (m.find()) {
int startIndex = m.start();
System.out.println("MATCH (#index " + startIndex + "): "+ m.group());
} else {
System.out.println("NO MATCH!");
}
}
}
OUTPUT
MATCH (#index 10): 111