Printing out an array of Fibonacci numbers [closed] - java

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

Related

Find the Least Common Multiple (LCM) of exactly N-1 numbers chosen among N numbers

Find the smallest number M, which is divided by exactly n-1 numbers from the input array. If there is no such M then return -1.
Example:
array = [2,3,5]
Answer :
6
Explanation :
6 can be divided by 2 and 3
Example:
array = [2,3,6]
Answer:
-1
Explanation :
It's not possible in this case so return -1.
My code:
As we need to find the smallest M, I am selecting only the elements from 0 to n-2
public int process(int[] arr) {
int answer = 1;
for(int i=0; i<arr.length-1; i++) {
answer *= arr[i];
}
return answer;
}
This program works for these 2 sample test cases but it was failing for multiple hidden test cases. I trying to understand what I am missing here.
Calculation of the Least Common Multiple (LCM)
A problem inside the task is the calculation of the Least Common Multiple of 2 numbers. The method public int lowerCommonMultiple(int x1, int x2) solves this problem and I think it can be used in other context.
List of the class methods
All the code is included in the methods of the BestMultiple class. These methods (excluding the main) are:
public int[] removeElem(int[] tensArray, int rm_index): used to remove an element from an array
public int leastCommonMultiple(int x1, int x2): calculates the Least Common Multiple of 2 numbers
private int getLeastCommonMultipleNnumber(int[] arr): Calculates the least common multiple of N-1 integer contain in an array
public int process(int[] arr): calculates the least multiple of exactly N-1 number of an array of N integer; it manages many test strange cases (array empty, elem<=0, etc.)
May be the code is not optimized, but I hope it is correct (the output added, shows that it works correctly, at least with the test cases chosen).
public class BestMultiple {
/*++++++++++++++++++++++++++++++++++++++++++++
Method: removeElem() remove an element from
an array.
+++++++++++++++++++++++++++++++++++++++++++*/
public int[] removeElem(int[] tensArray, int rm_index) {
// Create a proxy array of size one less than original array
int[] proxyArray = new int[tensArray.length - 1];
// copy all the elements in the original to proxy array
// except the one at index
for (int i = 0, k = 0; i < tensArray.length; i++) {
// check if index is crossed, continue without copying
if (i == rm_index) {
continue;
}
// else copy the element
proxyArray[k++] = tensArray[i];
}
return proxyArray;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Method: leastCommonMultiple() Calculates the Least Common
multiple for 2 numbers
++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
public int leastCommonMultiple(int x1, int x2) {
int lcm = 1;
int max = x1;
if ((x1 == 0) || (x2 == 0)) {
lcm = 0;
} else {
if (x2 > x1) {
max = x2;
}
for (int i = 2; i <= max; i++) {
int exp_x1 = 0;
int exp_x2 = 0;
int exp = 0;
if (x1 > 1) {
while ((x1 % i) == 0) {
exp_x1++;
x1 /= i;
}
}
if (x2 > 1) {
while ((x2 % i) == 0) {
exp_x2++;
x2 /= i;
}
}
if ((exp_x1 > 0) || (exp_x2 > 0)) {
exp = exp_x1;
if (exp_x2 > exp) {
exp = exp_x2;
}
while (exp > 0) {
lcm *= i;
exp--;
}
}
}
}
return lcm;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Method: getLeastCommonMultipleNnumber()
Calculates the least common multiple of N-1
integer contain in an array
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
public int getLeastCommonMultipleNnumber(int[] arr) {
int multiple = 1;
if (arr.length >= 2) {
multiple = leastCommonMultiple(arr[0], arr[1]);
for (int j = 2; j < arr.length; j++) {
multiple = leastCommonMultiple(multiple, arr[j]);
}
} else {
// array with only 2 elements
multiple = arr[0];
}
return multiple;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Method: process()
Calculates the least multiple of EXACTLY N-1
number of an array of N integer
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
public int process(int[] arr) {
int answer;
if (arr.length <= 1) {
// array contains only one element or is empty => return -1
answer = -1;
} else {
int pos_elem_zero = -1;
int prod = 1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] > 0) {
prod *= arr[i];
} else {
if (arr[i] < 0) {
// integer < 0 are not allowed
return -1;
}
if (pos_elem_zero == -1) {
pos_elem_zero = i;
} else {
// there are more element == 0
return -1;
}
}
}
if (pos_elem_zero >= 0) {
// there is one element == 0
arr = this.removeElem(arr, pos_elem_zero);
return getLeastCommonMultipleNnumber(arr);
}
// managing of normal test case
answer = prod;
for (int i = 0; i < arr.length; i++) {
int elem = arr[i];
int[] arr2 = this.removeElem(arr, i);
int multiple = getLeastCommonMultipleNnumber(arr2);
if (multiple > elem) {
if ((multiple % elem) != 0) {
if (multiple < answer) {
answer = multiple;
}
}
} else {
if (multiple < elem) {
answer = multiple;
}
}
}
if (answer == prod) {
answer = -1;
}
}
return answer;
}
/*++++++++++++++++++++++++++++++++++++++++++
Method: main() Executes test of process()
method
+++++++++++++++++++++++++++++++++++++++++*/
public static void main(String[] args) {
BestMultiple bm = new BestMultiple();
int[] arr1 = {6,30,5,3};
int[] arr2 = {1,2,3};
int[] arr3 = {1,2,3,3};
int[] arr4 = {6,7,5,3};
int[] arr5 = {9,14, 21};
int[] arr6 = {2,4};
int[] arr7 = {2,3,5};
int[] arr8 = {2,3,6};
int[] arr9 = {2};
int[] arr10 = {};
int[] arr11 = {2,3,0};
int[] arr12 = {0,2,3,0};
int[] arr13 = {20,3};
int[] arr14 = {0,6,15};
int[] arr15 = {1,6,15,-1};
int[] arr16 = {1,6,15};
int[] arr17 = {2,3,0,6,15};
System.out.println("{6,30,5,3} --> " + bm.process(arr1));
System.out.println("{1,2,3} --> " + bm.process(arr2));
System.out.println("{1,2,3,3} --> " + bm.process(arr3));
System.out.println("{6,7,5,3} --> " + bm.process(arr4));
System.out.println("{9,14,21} --> " + bm.process(arr5));
System.out.println("{2,4} --> " + bm.process(arr6));
System.out.println("{2,3,5} --> " + bm.process(arr7));
System.out.println("{2,3,6} --> " + bm.process(arr8));
System.out.println("{2} --> " + bm.process(arr9));
System.out.println("{} --> " + bm.process(arr10));
System.out.println("{2,3,0} --> " + bm.process(arr11));
System.out.println("{0,2,3,0} --> " + bm.process(arr12));
System.out.println("{20,3} --> " + bm.process(arr13));
System.out.println("{0,6,15} --> " + bm.process(arr14));
System.out.println("{1,6,15,-1} --> " + bm.process(arr15));
System.out.println("{1,6,15} --> " + bm.process(arr16));
System.out.println("{2,3,0,6,15} --> " + bm.process(arr17));
}
}
Output of the program
The output of the program with the test cases chosen is:
{6,30,5,3} --> -1
{1,2,3} --> 2
{1,2,3,3} --> 3
{6,7,5,3} --> 30
{9,14,21} --> 42
{2,4} --> 2
{2,3,5} --> 6
{2,3,6} --> -1
{2} --> -1
{} --> -1
{2,3,0} --> 6
{0,2,3,0} --> -1
{20,3} --> 3
{0,6,15} --> 30
{1,6,15,-1} --> -1
{1,6,15} --> 6
{2,3,0,6,15} --> 30
You start by writing a method process that computes the minimum number for each subarray with one element excluded:
public static int process(int... arr) {
int min = -1;
for (int i = 0; i < arr.length; ++i) {
int r = process(arr, i);
if (r != -1) {
if (min == -1) {
min = r;
} else {
min = Math.min(min, r);
}
}
}
return min;
}
Where the second process method looks like this:
private static int process(int[] arr, int exclude) {
int result = 0;
for (int i = 0; i < arr.length; ++i) {
if (i != exclude) {
if (result == 0) {
result = arr[i];
} else {
result = lcm(result, arr[i]);
}
}
}
if (result%arr[exclude] == 0) {
return -1;
}
return result;
}
You need a method that computes the LCM of two numbers. Here, I'll use a second method that computes the GCD:
private static int lcm(int a, int b) {
return a*b/gcd(a,b);
}
private static int gcd(int a, int b) {
if (a == 0) {
return b;
} else if (b == 0) {
return a;
} else {
while (a != b) {
if (a > b) {
a -= b;
} else {
b -= a;
}
}
return a;
}
}
Examples:
System.out.println(process(2, 3, 5)); // prints 6
System.out.println(process(2, 3, 6)); // prints -1
System.out.println(process(9, 14, 21)); // prints 42 (divisible by 14 and 21, but not by 9
System.out.println(process(6, 7, 5, 3)); // prints 30 (divisible by 6, 5, 3, but not by 7
The way you implemented process() assumes the input array is sorted. But anyway, I don't think sorting will help here. Note that the number satisfying the given conditions can be divided by the biggest number. For [2, 3, 5, 6] it is 6. Dividing the product of all the elements by consecutive elements from the biggest to the lowest and stopping at the first that is not a divisor is also not correct. In the example [2, 4, 5, 6] this would give 2 * 4 * 5 = 40 when the correct answer is 20.
My idea is to use an algorithm inspired by Sieve of Eratosthenes. Note that the number that satisfies the conditions can't be bigger than the product of all the elements. So create a table divisors[] with indices from 0 through the product of the elements of array where divisors[i] indicates how many elements from array divide i. Iterate over elements of array and increment all elements in divisors[i] where i is divided by the element. Then find the first i for which divisors[i] == n - 1.
The limitation is that divisors can be quite big depending on what is the product of array, so applicability will be limited to relatively small values in array.

How to display the two arrays as the instructions stated

I'm doing this assignment for my Java course, so the instruction is:
"Write a program that generates 100 random integers in the range 1 to 100, and stores them in an array. Then, the program should call a class method that extracts the numbers that are even multiplesof4intoanarray and returns the array. The program should then call another method that extracts the numbers that are not even multiples of 4 into a separate array and returns the array. Both arrays should then be displayed."
public class Assignment8
{
public static void main (String [] args)
{
int [] numbers = new int [100];
for (int i = 1; i < numbers.length; i++) {
numbers[i] = (int)(Math.random()*((100)+1))+1;
}
int EMO4N [] = evenMultiplesOf4(numbers);
System.out.println("The even multiples of four are: ");
for (int m = 8; m < EMO4N.length; m++) {
System.out.println(EMO4N [m] + " " );
}
int NEMO4N [] = nonEvenMultiplesOf4(numbers);
System.out.println("The numbers that are not even multiples of four are: ");
for (int k = 1; k < NEMO4N.length; k++) {
System.out.println(NEMO4N [k] + " ");
}
}
public static int [] evenMultiplesOf4(int [] numbers)
{
int EMO4 = 8;
for (int x : numbers) {
if (x % 4 == 0 & (x / 4) % 2 == 0) {
EMO4++;
}
}
int [] EMO4N = new int [EMO4];
int y = 8;
for (int m : numbers) {
if(y % 4 == 0 & (y / 4) % 2 == 0) {
EMO4N[y] = m;
y++;
}
}
return EMO4N;
}
public static int [] nonEvenMultiplesOf4( int [] numbers)
{
int NEMO4 = 1;
for (int j : numbers) {
if (j % 4 != 0 || (j / 4) % 2 != 0) {
NEMO4++;
}
}
int [] NEMO4N = new int [NEMO4];
int k = 1;
for (int n : numbers) {
if(k % 4 != 0 || (k / 4) % 2 != 0) {
NEMO4N[k] = n;
k++;
}
}
return NEMO4N;
}
}
The result displayed is​ always a combination of 0s and some other random numbers.
You have several small logic errors.
You start m and y off at 8, which doesn't make sense as they are meant to keep track of the index that you will be inserting at.
You use the expression if (x % 4 == 0 & (x / 4) % 2 == 0) to determine if the number is divisible by four, but if(x % 4 == 0) is sufficient.
In your loops:
for (int n : numbers) {
if(k % 4 != 0) {
NEMO4N[k] = n;
k++;
}
}
You are checking to see if k is divisible by four, when you should be checking n. Change it to:
for (int n : numbers) {
if(n % 4 != 0) {
NEMO4N[k] = n;
k++;
}
}
I won't provide working code as this seems to be a homework assignment.
Here is working solution - requires Java8.
public static void main(String[] args) throws IOException, ClassNotFoundException {
List c1 = generateArray(100);
Divisors divisors = getDivisors(c1, 4);
print("Even", divisors.evens);
print("Odd", divisors.odds);
}
private static void print(String what, List<Integer> items) {
StringJoiner joiner = new StringJoiner(",");
items.stream().map(String::valueOf).forEach(joiner::add);
System.out.println(what + " divisors are: " + joiner.toString());
}
private static Divisors getDivisors(List<Integer> c1, int i) {
Divisors divisors = new Divisors();
divisors.value = i;
c1.stream()
.filter(value->value>=i)// it is not dividable, so ill skip
.forEach(value -> {
int modulo = value % i;
List<Integer> arr = modulo == 0 ? divisors.evens : divisors.odds;
arr.add(value);
});
return divisors;
}
private static List<Integer> generateArray(int size) {
return IntStream.rangeClosed(1,100).limit(size).boxed().collect(Collectors.toList());
}
static class Divisors {
int value;
List<Integer> evens = new LinkedList<>();
List<Integer> odds = new LinkedList<>();
}
example output:
Even divisors are: 4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100
Odd divisors are: 5,6,7,9,10,11,13,14,15,17,18,19,21,22,23,25,26,27,29,30,31,33,34,35,37,38,39,41,42,43,45,46,47,49,50,51,53,54,55,57,58,59,61,62,63,65,66,67,69,70,71,73,74,75,77,78,79,81,82,83,85,86,87,89,90,91,93,94,95,97,98,99

How to find subsets that contains equal sum in an array:

How to find subsets that contains equal sum in an array.
For example
{1,2,3,4,2}->{1,2,3} && {4,2}
{1,1,3,3,2,8}->{1,3,3,2}&&{1,8}
{1,3,4,7}->no subset
I tried with below code, but not getting the appropriate output.
import java.util.*
public static void main(String[] args) {
int arr[] = {1,3,4,7};
int sum = getSum(arr, arr.length);
int[] solution = new int[arr.length];
find(arr, 0, 0, sum, solution);
}
public static int getSum(int arr[], int n) {
float sum = 0f;
for (int i = 0; i < n; i++)
sum = sum + arr[i];
return Math.round(sum / 2);
}
public static void find(int[] A, int currSum, int index, int sum,
int[] solution) {
if (currSum == sum) {
System.out.println("\nSum found");
for (int i = 0; i < solution.length; i++) {
if (solution[i] == 1) {
System.out.print(" " + A[i]);
}
}
} else if (index == A.length) {
return;
} else {
solution[index] = 1;// select the element
currSum += A[index];
find(A, currSum, index + 1, sum, solution);
currSum -= A[index];
solution[index] = 0;// do not select the element
find(A, currSum, index + 1, sum, solution);
}
return;
}
with this Input Array: 1,2,3,4,2 getting below output
1 2 3
1 3 2
2 4
4 2
Input Array: 1,1,3,3,2,8
1 3 3 2
1 8
1 3 3 2
1 8
Input Array:1,3,4,7
1 3 4
1 7
to solve this problem you need to have at least 3 nested loop in your code
the sudocode will be like
for (i=0,i< array.length-1,i++){
for(k=i;k<array.length-1,k++){
fsum=findSum(i/*from*/,k/*to*/,array);
ssum=0;
for(x=k,x<array.length,x++){
secondsum=findSum(k,x,array);
if(fsum==ssum){
prend(i,k,array);
print(k,x,array);
break;
}
}
}
}
note that this is just sudo code need to implement
The recurrence part of your code works fine. There are only two minor flaws in rather peripheral parts:
The two subsets only exists if the sum of the numbers is even. Your code doesn't consider this requirement which is the reason for the failure concerning {1,3,4,7}. For this, the body of the main function is slightly modified so that the recurrence is performed only for even sums.
You should sort out the duplicates which would prevent the repetitions concerning {1,2,3,4,2} and {1,1,3,3,2,8}. For this, the resulting subsets quite simply have to be stored. Then, after the elemination of the duplicates the remaining subsets are printed out. For convenience both functionalities are encapsulated in the added SubsetPair-class which provides the methods storeSubsetPair and printSubsetPairList for storage and printing, respectively.
The modified code is:
import java.util.*;
public class Main {
public static void main(String[] args) {
int arr[] = {1,3,4,7};
int sum = getSum(arr, arr.length);
int[] solution = new int[arr.length];
// find(arr, 0, 0, sum, solution); // REPLACED WITH: -----------------
if (sum % 2 == 0) {
sum = Math.round(sum / 2f);
find(arr, 0, 0,sum, solution);
}
SubsetPair.printSubsetPairList();
// -------------------------------------------------------------------
}
public static int getSum(int arr[], int n) {
// float sum = 0f; // REPLACED WITH: ---------------------------------
int sum = 0;
// -------------------------------------------------------------------
for (int i = 0; i < n; i++)
sum = sum + arr[i];
// return Math.round(sum / 2); // REPLACED WITH: ---------------------
return sum;
// -------------------------------------------------------------------
}
public static void find(int[] A, int currSum, int index, int sum,
int[] solution) {
if (currSum == sum) {
// System.out.println("\nSum found"); // REPLACED WITH: ----------
// for (int i = 0; i < solution.length; i++) {
// if (solution[i] == 1) {
// System.out.print(" " + A[i]);
// }
// }
SubsetPair.storeSubsetPair(A, solution);
// ---------------------------------------------------------------
} else if (index == A.length) {
return;
} else {
solution[index] = 1;// select the element
currSum += A[index];
find(A, currSum, index + 1, sum, solution);
currSum -= A[index];
solution[index] = 0;// do not select the element
find(A, currSum, index + 1, sum, solution);
}
return;
}
}
//NEW: Class for storage and print:
class SubsetPair {
private static List<SubsetPair> subsetPairList = new ArrayList<>();
private List<Integer> subset1 = new ArrayList<>();
private List<Integer> subset2 = new ArrayList<>();
//
// Storage of the subset pair
//
public static void storeSubsetPair(int[] A, int[] solution) {
SubsetPair subsetPair = new SubsetPair();
for (int i = 0; i < solution.length; i++) {
if (solution[i] == 1) {
subsetPair.subset1.add(A[i]);
} else {
subsetPair.subset2.add(A[i]);
}
}
if (!subsetPair.isDuplicate()) {
subsetPairList.add(subsetPair);
}
}
// Remove duplicates
private boolean isDuplicate() {
for (SubsetPair subsetPair : subsetPairList) {
if (isEqual(subset1, subsetPair.subset2) && isEqual(subset2, subsetPair.subset1) ||
isEqual(subset1, subsetPair.subset1) && isEqual(subset2, subsetPair.subset2)) {
return true;
}
}
return false;
}
private boolean isEqual(List<Integer> subset1, List<Integer> subset2) {
return subset1.containsAll(subset2) && subset2.containsAll(subset1);
}
//
// Output of the subset pairs
//
public static void printSubsetPairList() {
if (subsetPairList.size() == 0) {
System.out.println("No subset-pairs found!");
} else {
for (int i = 0; i < subsetPairList.size(); i++) {
subsetPairList.get(i).printSubsetPair(i + 1);
}
}
}
private void printSubsetPair(int i) {
System.out.print(i + ". Subset-Pair:\n");
System.out.print("Subset 1: ");
for (Integer i1 : subset1) {
System.out.print(i1 + " ");
}
System.out.println();
System.out.print("Subset 2: ");
for (Integer i2 : subset2) {
System.out.print(i2 + " ");
}
System.out.print("\n\n");
}
}
With those changes the output becomes:
For {1,2,3,4,2} with an even sum of 12:
1. Subset-Pair:
Subset 1: 1 2 3
Subset 2: 4 2
For {1,1,3,3,2,8} with an even sum of 18:
1. Subset-Pair:
Subset 1: 1 3 3 2
Subset 2: 1 8
For {1,3,4,7} with an odd sum of 15:
No subset-pairs found!
For {3,1,1,2,2,1} with an even sum of 10:
1. Subset-Pair:
Subset 1: 3 1 1
Subset 2: 2 2 1
2. Subset-Pair:
Subset 1: 3 2
Subset 2: 1 1 2 1
For {2,4,8} with an even sum of 14:
No subset-pairs found!
As in the comments already stated the problem is related to the "partition problem" which is the task to decide if a multiset of positive integers can be partitioned into two subsets with equal sum. This is in detail explained e.g. in
https://en.wikipedia.org/wiki/Partition_problem or in https://www.geeksforgeeks.org/partition-problem-dp-18/ (the latter includes a Java implementation). But both problems are not exactly identical because the solution of the "partition problem" just answers the question if the multiset can be partitioned into two subsets, but does not explicitly determine the subsets itself.

Java. How to generate all integers with certain number of 1's and 0's in it? [closed]

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);
}

Longest String Palindrome Using string.reverse [closed]

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

Categories