Getting a list of binary numbers composing a number - java

In Java, having a number like 0b1010, I would like to get a list of numbers "composing" this one: 0b1000 and 0b0010 in this example: one number for each bit set.
I'm not sure about the best solution to get it. Do you have any clue ?

Use a BitSet!
long x = 0b101011;
BitSet bs = BitSet.valueOf(new long[]{x});
for (int i = bs.nextSetBit(0); i >=0 ; i = bs.nextSetBit(i+1)) {
System.out.println(1 << i);
}
Output:
1
2
8
32
If you really want them printed out as binary strings, here's a little hack on the above method:
long x = 0b101011;
char[] cs = new char[bs.length()];
Arrays.fill(cs, '0');
BitSet bs = BitSet.valueOf(new long[]{x});
for (int i = bs.nextSetBit(0); i >=0 ; i = bs.nextSetBit(i+1)) {
cs[bs.length()-i-1] = '1';
System.out.println(new String(cs)); // or whatever you want to do with this String
cs[bs.length()-i-1] = '0';
}
Output:
000001
000010
001000
100000

Scan through the bits one by one using an AND operation. This will tell you if a bit at one position is set or not. (https://en.wikipedia.org/wiki/Bitwise_operation#AND). Once you have determined that some ith-Bit is set, make up a string and print it. PSEUDOCODE:
public static void PrintAllSubbitstrings(int number)
{
for(int i=0; i < 32; i++) //32 bits maximum for an int
{
if( number & (1 << i) != 0) //the i'th bit is set.
{
//Make up a bitstring with (i-1) zeroes to the right, then one 1 on the left
String bitString = "1";
for(int j=0; j < (i-1); j++) bitString += "0";
System.out.println(bitString);
}
}
}

Here is a little test that works for me
public static void main(String[] args) {
int num = 0b1010;
int testNum = 0b1;
while(testNum < num) {
if((testNum & num) >0) {
System.out.println(testNum + " Passes");
}
testNum *= 2;
}
}

Related

Algorithm to create all permutations and lengths

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

Credit card validator , calling method doesn't work

I'm relatively new to java and am trying to break my code down as much as possible. This question is really on how to organize methods to work together
My credit card validator works if checkSum() code is written in the validateCreditCard() method. I think it's weird 'cause it works when called by the checkDigitControl() method
I used these sources for the program's logic:
To Check ~ https://www.creditcardvalidator.org/articles/luhn-algorithm
To Generate ~ https://en.wikipedia.org/wiki/Luhn_mod_N_algorithm
Here's my code(I apologize in advance if it's rather clumsy)
public class CreditCards {
public static void main(String[] args) {
long num;
num = genCreditCard();
boolean bool = validateCreditCard(num);
}
// Validity Check
public static boolean validateCreditCard(long card) {
String number = card+"";
String string=null;
int i;
for(i=0; i<number.length()-1; i++) {//Populate new string, leaving out last digit.
string += number.charAt(i)+"";
}
String checkDigit = number.charAt(i)+"";// Stores check digit.
long sum = checkSum(string);// Program works if this line is swapped for the code below(from checkSum)
//**********************************************************************
// int[] digits = new int[number.length()];
// int lastIndex = digits.length-1;
// int position=2; int mod=10;
// int sum=0;
//
// for(int j=lastIndex; j>=0; j--) {// Populate array in REVERSE
// digits[j] = Integer.parseInt(number.charAt(j)+"");
// digits[j] *= ( (position%2 == 0) ? 2: 1 );// x2 every other digit FROM BEHIND
// position++;
//
// digits[j] = ( (digits[j] > 9) ? (digits[j] / mod)+(digits[j] % mod) : digits[j] );//Sums integers of double-digits
// sum += digits[j];
// }
//**********************************************************************
sum *= 9;
string = sum+"";
string = string.charAt(string.length()-1)+"";// Last digit of result.
return (string.equals(checkDigit));
}
public static long genCreditCard() {
String number = "34";// American Express(15 digits) starts with 34 or 37
for(int i=0; i<12; i++)
number += (int)(Math.random() * 10) + "";// Add 12 random digits 4 base.
number += checkDigitControl(number);// Concat the check digit.
System.out.println(number);
return Long.parseLong(number);
}
// Algorithm to calculate the last/checkSum digit.
public static int checkDigitControl(String number) {
int i;
for(i=0; i<5; i++)
++i;
int sum = checkSum(number);
return 10 - sum%10;// Returns number that makes checkSum a multiple of 10.
}
public static int checkSum(String number) {
int[] digits = new int[number.length()];
int lastIndex = digits.length-1;
int position=2; int mod=10;
int sum=0;
for(int j=lastIndex; j>=0; j--) {// Populate array in REVERSE
digits[j] = Integer.parseInt(number.charAt(j)+"");
digits[j] *= ( (position%2 == 0) ? 2: 1 );// x2 every other digit FROM BEHIND
position++;
digits[j] = ( (digits[j] > 9) ? (digits[j] / mod)+(digits[j] % mod) : digits[j] );//Sums integers of double-digits
sum += digits[j];
}
return sum;
}
}
Thx in advance, sorry if this isn't the right format; it's also my 1st Stackoverflow post ¯\_(ツ)_/¯
You are initializing the variable string with null value:
String string=null;
And in the following for you are adding every char of the card number to this string.
for(i=0; i<number.length()-1; i++) {
string += number.charAt(i)+"";
}
But this will result in the variable string to be null + cardnumbers, because you didn't initialize the String string, and the value null is converted to the string "null" (Concatenating null strings in Java)
This will fix you code:
String string = new String();
Note, this code:
for(i=0; i<number.length()-1; i++) {
string += number.charAt(i)+"";
}
can be easily replace by this line that does the same thing:
number = number.substring(0, number.length() -1);
If you switch to this code just pass number to checkSum method

Adding Numbers and printing the sum vertically using arrays

I have to create a program which adds two integers and prints the sum vertically.
For example, I have.
a=323, b=322.
The output should be:
6
4
5
I've created the code for when the integers are up to two digits, but I want it to work for at least three digits.
Below is the best I could think of.
It may be completely wrong, but the only problem I'm facing is the declaration of array.
It says that the array might not be initialized.
If I set it to null then also it won't assign values to it later.
I know maybe I'm making a big mistake here, but I'll really appreciate if anyone could help me out.
Please keep in mind that I must not use any other functions for this code.
Hope I'm clear.
public class Vert
{
public static void main(String args[])
{
int n,i=0,j,a=323,b=322;
int s[];
n=a+b;
while(n>9)
{
s[i]=n%10;
i++;
s[i]=n/10;
if(s[i]>9)
{
n=s[i];
}
}
j=i;
for(j=i;j>=0;j--)
{
System.out.println(+s[j]);
}
}
}
String conversion seems like cheating, so here's a Stack.
int a = 323, b = 322;
java.util.Stack<Integer> stack = new java.util.Stack<>();
int n = a + b;
while (n > 0) {
stack.push(n % 10);
n = n / 10;
}
while (!stack.isEmpty())
System.out.println(stack.pop());
If an array is required, you need two passes over the sum
int a = 323, b = 322;
// Get the size of the array
int n = a + b;
int size = 0;
while (n > 0) {
size++;
n = n / 10;
}
// Build the output
int s[] = new int[size];
n = a + b;
for (int i = size - 1; n > 0; i--) {
s[i] = n % 10;
n = n / 10;
}
// Print
for (int x : s) {
System.out.println(x);
}
To initialize an array, you need to specify the size of your array as next:
int s[] = new int[mySize];
If you don't know the size of your array, you should consider using a List of Integer instead as next:
List<Integer> s = new ArrayList<Integer>();
Here is how it could be done:
// Convert the sum into a String
String result = String.valueOf(a + b);
for (int i=0; i <result.length();i++) {
// Print one character corresponding to a digit here per line
System.out.println(result.charAt(i));
}
I'd do it like this:
int a = 322;
int b = 322;
int sum = a + b;
String s = Integer.toString(sum);
for(int i = 0; i < s.length(); i++) {
System.out.println(s.charAt(i));
}
But your problem looks like an array is required.
The steps are same as in my solution:
Use int values
Sum the int values (operation)
Convert the int value in an array/string
Output the array/string

Large Optimized IO processing in Java

An input n of the order 10^18 and output should be the sum of all the numbers whose set bits is only 2. For e.g. n = 5 setbit is 101--> 2 set bits. For n = 1234567865432784,How can I optimize the below code?
class TestClass
{
public static void main(String args[])
{
long N,s=0L;
Scanner sc = new Scanner(System.in);
N=sc.nextLong();
for(long j = 1; j<=N; j++)
{
long b = j;
int count = 0;
while(b!=0)
{
b = b & (b-1);
count++;
}
if(count == 2)
{
s+=j;
count = 0;
}
else
{
count = 0;
continue;
}
}
System.out.println(s%1000000007);
s=0L;
}
}
Java has a function
if (Integer.bitCount(i) == 2) { ...
However consider a bit: that are a lot of numbers to inspect.
What about generating all numbers that have just two bits set?
Setting the ith and jth bit of n:
int n = (1 << i) | (1 << j); // i != j
Now consider 31² steps, not yet 1000 with N steps.
As this is homework my advise:
Try to turn the problem around, do the least work, take a step back, find the intelligent approach, search the math core. And enjoy.
Next time, do not spoil yourself of success moments.
As you probably had enough time to think about Joop Eggen's suggestion,
here is how i would do it (which is what Joop described i think):
import java.util.Scanner;
public class Program {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong();
long sum = 0;
for (int firstBitIndex = 0; firstBitIndex < 64; firstBitIndex++) {
long firstBit = 1L << firstBitIndex;
if (firstBit >= n)
break;
for (int secondBitIndex = firstBitIndex + 1; secondBitIndex < 64; secondBitIndex++) {
long value = firstBit | (1L << secondBitIndex);
if (value > n)
break;
sum += value;
}
}
System.out.println(sum % 1000000007);
sc.close();
}
}
Java provides the class BigInteger, which includes a method nextProbablePrime(). This means you could do something like this:
BigInteger n = new BigInteger(stringInputN);
BigInteger test = BigInteger.valueOf(2);
BigInteger total = BigInteger.valueOf(0);
while (test.compareTo(n) < 0){
total = total.add(test);
test = test.nextProbablePrime();
}
System.out.println(total);
This this has an extremely low probability of getting the wrong answer (but nonzero), so you might want to run it twice just to doublecheck. It should be faster than manually iterating it by hand though.

Java - Listing combinations

I'm writing a program to list all possible combinations of letters A,B,C, and D. I have successfully written a program to list all possible permutations.
However, how would I rewrite the program to work and produce all combinations (i.e.: ABCD = DCBA and AB = BA, so as long as one is there, the other need not be listed).
So far, the code for my current program is:
import java.util.ArrayList;
public class Perms {
public static void main(String[] args) {
ArrayList<Character> characters = new ArrayList<Character>();
characters.add('A');
characters.add('B');
characters.add('C');
characters.add('D');
int count = 0;
for (int i = 0; i < characters.size(); i++) {
for (int j = 0; j < characters.size(); j++) {
for (int k = 0; k < characters.size(); k++) {
for (int d = 0; d < characters.size(); d++) {
count++;
System.out.println(count + ": " + characters.get(i) + characters.get(j) + characters.get(k) + characters.get(d));
}
}
}
}
}
}
Your second case is equivalent to the list of binary values of 4 digits. Let's assume that A is rightmost digit and D is leftmost. Then there are 16 combinations in total:
DCBA
0000
0001
0010
0011
0100
...
1110
1111
Each combination is decoded like follows:
DCBA
1010 = DB
since there are ones in B and D positions.
You have various of ways to generate and or decode binary numbers in Java.
For example, with bitwise operations:
public static void main(String[] args) {
// starting from 1 since 0000 is not needed
for(int i=1; i<16; ++i) {
// bitwise operation & detects 1 in given position,
// positions are determined by sa called "masks"
// mask has 1 in position you wish to extract
// masks are 0001=1, 0010=2, 0100=4 and 1000=8
if( (i & 1) > 0 ) System.out.print("A");
if( (i & 2) > 0 ) System.out.print("B");
if( (i & 4) > 0 ) System.out.print("C");
if( (i & 8) > 0 ) System.out.print("D");
System.out.println("");
}
}
Here is my code for your problem :)
I'm so sorry that my answer looks ugly because I just a new comer at Java.
import java.util.Vector;
public class StackOverFlow {
static int n ;
static Vector<String> set;
static int[] d ;
public static void recursion(int t){
if(t==n){
PRINT();
return;
}
d[t]=1;
recursion(t+1);
d[t]=0;
recursion(t+1);
}
public static void PRINT(){
System.out.println("ANSWER");
for(int i=0;i<n;i++)
if(d[i]==1) System.out.println(set.elementAt(i));
}
public static void main(String[] args) {
n = 4;
set = new Vector<String>(4);
d = new int[6];
set.add("a");
set.add("b");
set.add("c");
set.add("d");
recursion(0);
}
}
// Returns all combinations of a List of Characters (as Strings)
// THIS METHOD MODIFIES ITS ARGUMENT! Make sure to copy defensively if necessary
List<String> charCombinations(List<Character> chars)
{
if(chars.isEmpty())
{
List<String> result = new ArrayList<String>();
result.add("");
return result;
}
else
{
Character c = chars.remove(0);
List<String> result = charCombinations(chars);
int size = result.size();
for(int i = 0; i < size; i++)
result.add(c + result.get(i));
return result;
}
}
I used List for the argument, because Set doesn't have a method to pop a single item out from the set.
Take a look at Peter Lawrey's recursive solution, which handles combinations of a list containing repeated values.

Categories