How to find character frequency in a 2D character array? - java

I am trying to create a program that searches through an array of characters. If there is a character that repeats itself, it should be shown.
I've tried creating a triple loop
1 to go through the the character array, and then 2 remaining ones to compare each letter with each other
public static void main(String[] args) {
char [][] tab = new char[][]{
{'S','a','m','s','u','n','g'},
{'N','o','k','i','a'},
{'A','p','p','l','e'},
{'B','l','a','c','k','B','e','r','r','y'},
{'A','l','c','a','t','e','l'},
{'S','o','n','y'},
{'J','o','l','l','a'}};
Litery(tab);
}
public static void Litery(char tab[][])
{
int[] freq = new int[tab.length];
int counter=0;
for(int i=0;i<7;i++)
{
int size = tab[i].length;
for(int j=0;i<tab.length;i++)
{
counter=0;
freq[i] = 1;
for(int z = j+1;z<tab[j].length;z++)
{
if(tab[j] == tab[z])
{
freq[i]++;
}
}
}
}
for(int i=0;i<tab.length;i++)
{
if(freq[i] > 1)
{
System.out.println(tab[i]);
}
}
}
I want the ouputs to be
SAMSUNG
APPLE
BLACBERRY
ALCATEL
JOLLA
Capitalisation doesn't matter
Thank you in advance!

Use a hash map whose keys are values in your array and values are num times that value has appeared.
Start with an empty map
Iterate through your array and for each char
get a lowercase version of the char since you're case-insensitive
if the map does not have a key with that char, add an entry (char, 1) to your map
otherwise, increment the number associated with char in your map
If you need the list of characters that appear more than once, you can iterate through your map and filter out the characters whose values are 1.

If you want to print "rows" (aka words) that has at least one duplicate character (case-insensitive), then you can do it easily with some stream logic in Java 8+:
public static void Litery(char tab[][]) {
Stream.of(tab)
.filter(w -> w.length != new String(w).toUpperCase().chars().distinct().count())
.forEach(System.out::println);
}
Output
Samsung
Apple
BlackBerry
Alcatel
Jolla
Of course, it might make more sense if the input was an actual String[], so it can support characters from the supplementary planes, e.g. emoticons:
public static void main(String[] args) {
Litery("Samsung", "Nokia", "Apple", "BlackBerry", "Alcatel", "Sony", "Jolla",
"😀😁😂😃😄😅😆😇", "😀😁😂😃😄😅😆😇😀");
}
public static void Litery(String... tab) {
Stream.of(tab)
.filter(w -> w.codePointCount(0, w.length()) != w.toUpperCase().codePoints().distinct().count())
.forEach(System.out::println);
}
Output
Samsung
Apple
BlackBerry
Alcatel
Jolla
😀😁😂😃😄😅😆😇😀

You don't need to create a int array for checking the frequency, just initialize a boolean array of size of tab which is by initialized to an array of false values.
Now in the inner loop compare the char by lower-casing both character as you want to check irrespective of the case:
public static void Litery(char tab[][]) {
boolean[] freq = new boolean[tab.length];
int counter = 0;
for (int i = 0; i < tab.length; i++) {
for(int j = 0; j < tab[i].length; j++){
for (int z = 0; z < tab[i].length; z++) {
if (j != z && Character.toLowerCase(tab[i][j]) == Character.toLowerCase(tab[i][z])) {
freq[i] = true;
break;
}
}
}
}
for (int i = 0; i < tab.length; i++) {
if (freq[i]) {
System.out.println(tab[i]);
}
}
}
You can also avoid using three loops by using a Set, simply convert the array of char for each row in a Set<Character> of lowercase, if the value is repeated the resulting Set<Character> will be of size less than the array as Set does not contain duplicates:
public static void Litery(char tab[][]) {
for(int i = 0; i < tab.length; i++){
final int idx = i;
if(IntStream.range(0, tab[idx].length)
.mapToObj(j -> tab[idx][j])
.map(Character::toLowerCase)
.collect(Collectors.toSet()).size() != tab[i].length){
System.out.println(String.valueOf(tab[i]));
}
}
Output:
Samsung
Apple
BlackBerry
Alcatel
Jolla

Related

JAVA code for the possible number of combinations of a 6-digit code between ranges of two integers

Conditions of the 6-digit code:
None of the digits are 0
Each digit of the combination is different
The 6-digit number is divisible by each one of the digits
Input:
Two integers, L and H
L is the limit on the smallest number on the range
H is the limit on the largest number on the range
Output:
C, which defines the number of possible combinations where L<=c<=H
I thought I could use arrays as the condition check, then realized I couldn't use it to find the number of possible combinations. Tried using loops, but couldn't figure it out, all I got for the pseudocode is the input, then a condition if L is less or equal to H. Then I sort of ran to a brick wall.
Here's the code.
''''''''
public static void main(String[] args) {
Scanner FF = new Scanner(System.in);
List<Integer> result = new ArrayList<>();
int l = FF.nextInt();
int h = FF.nextInt();
for (int i = l; i <= h; i++) {
result.add(i);
}
for (int i=l; i<=h; i++){
if (result.get(i) == result.get(i)){
result.remove(i);
}
int temp = result.get(i);
while (result.get(i)>0){
int k = result.get(i)%10;
if (temp % k != 0){
result.remove(i);
}
}
if (String.valueOf(result.get(i)).contains("0")){
result.remove(i);
}
}
System.out.println(result);
}
}
You can create a stream of integers, here 111111 to 1000000 and then filter out everything what doesnot meet your conditions.
public class SixDigitCode {
public static void main(String[] args) {
IntStream.iterate(111111, i -> i < 1000000, i -> i + 1)
.filter(containsZero.negate())
.filter(digitDifferent)
.filter(divideByDigits)
.forEach(System.out::println);
}
static IntPredicate containsZero = i -> Integer.toString(i).contains("0");
static IntPredicate digitDifferent = i -> Integer.toString(i).chars().boxed().collect(Collectors.toSet()).size() == 6;
static IntPredicate divideByDigits = i -> Integer.toString(i).chars().boxed()
.filter( x -> i%Character.getNumericValue(x) ==0)
.count() ==6;
}
There are multiple ways to solve this problem.
Let's start with an easy, but inefficient one:
boolean isOk(int number){
String numberStr = Integer.toString(number);
if(numberStr.contains("0"))
return false;
for(int i = 0; i < numberStr.length(); i++){
for(int j = i + 1; j < numberStr.length(); j++){
if(numberStr.charAt(i) == numberStr.charAt(j))
return false;
}
}
return true;
}
...
int count = 0;
for(int i = L; i <= H; i++){
if(isOk(i))
count ++;
}
Note: this code is by no means optimal, but I think it is a straight forward easy to understand solution.
However, I cannot test it right now, so it may contain minor issues.

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

Specific element permutation within an array of characters in JAVA?

How can I list all uppercase/lowercase permutations for any letter specified in a character array?
So, say I have an array of characters like so: ['h','e','l','l','o']
and I wanted print out possible combinations for say the letter 'l' so it would print out [hello,heLlo,heLLo,helLo].
This is what I have so far(the only problem is that I can print the permutations however I'm not able to print them inside the actual word. so my code prints [ll,lL,Ll,LL] instead of the example above.
my code:
import java.util.ArrayList;
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
//Sample Word
String word = "Tomorrow-Today";
//Sample Letters for permutation
String rule_char_set = "tw";
ArrayList<Character> test1 = lettersFound(word, rule_char_set);
printPermutations(test1);
}
public static void printPermutations(ArrayList<Character> arrayList) {
char[] chars = new char[arrayList.size()];
int charIterator = 0;
for(int i=0; i<arrayList.size(); i++){
chars[i] = arrayList.get(i);
}
for (int i = 0, n = (int) Math.pow(2, chars.length); i < n; i++) {
char[] permutation = new char[chars.length];
for (int j =0; j < chars.length; j++) {
permutation[j] = (isBitSet(i, j)) ? Character.toUpperCase(chars[j]) : chars[j];
}
System.out.println(permutation);
}
}
public static boolean isBitSet(int n, int offset) {
return (n >> offset & 1) != 0;
}
public static ArrayList<Character> lettersFound(String word, String rule_char_set) {
//Convert the two parameter strings to two character arrays
char[] wordArray = word.toLowerCase().toCharArray();
char[] rule_char_setArray = rule_char_set.toLowerCase().toCharArray();
//ArrayList to hold found characters;
ArrayList<Character> found = new ArrayList<Character>();
//Increments the found ArrayList that stores the existent values.
int foundCounter = 0;
for (int i = 0; i < rule_char_setArray.length; i++) {
for (int k = 0; k < wordArray.length; k++) {
if (rule_char_setArray[i] == wordArray[k]) {
found.add(foundCounter, rule_char_setArray[i]);
foundCounter++;
}
}
}
//Convert to a HashSet to get rid of duplicates
HashSet<Character> uniqueSet = new HashSet<>(found);
//Convert back to an ArrayList(to be returned) after filtration of duplicates.
ArrayList<Character> filtered = new ArrayList<>(uniqueSet);
return filtered;
}
}
You need to make few changes in your program. Your logic is perfect that you need to find first the characters to be changed in the given word. After finding them, find powerset of characters to print all the permutation but this will only print permuatation of the characters of rule-char-set which are present in the given word.
Few changes you need to make is that first find all the indexes of word which contains characters of rule-char-set. Then find all subsets of indexes stored in an ArrayList and then for each element of each of the subsets, make the character present on that index to uppercase letter which will give you all permutation you require.
Consider an example that word = "Hello" and rule-char-set="hl" Then here first you need to find all indexes of h and l in the String word.
So here indexes are 0,2,3. Store it in ArrayList and then find its powerset.Then for each subset ,make the character present on that index to the uppercase letter.
Word[] = {'h','e','l','l','o'}
indexes = 0 , 1 , 2 , 3 , 4
index[]= { 0 , 2 ,3} //Store the indexes of characters which are to be changed
BITSET | SUBSET | word
000 | - | hello
001 | {3} | helLo
010 | {2} | heLlo
011 | {2,3} | heLLo
100 | {0} | Hello
101 | {0,3} | HelLo
110 | {0,2} | HeLlo
111 | {0,2,3} | HeLLo
Code :
import java.util.ArrayList;
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
//Sample Word
String word = "Tomorrow-Today";
//Sample Letters for permutation
String rule_char_set = "tw";
ArrayList<Integer> test1 = lettersFound(word, rule_char_set); //To store the indexes of the characters
printPermutations(word,test1);
}
public static void printPermutations(String word,ArrayList<Integer> arrayList) {
char word_array[]=word.toLowerCase().toCharArray();
int length=word_array.length;
int index[]=new int[arrayList.size()];
for(int i=0; i<arrayList.size(); i++){
index[i] = arrayList.get(i);
}
for (int i = 0, n = (int) Math.pow(2, index.length); i < n; i++) {
char[] permutation = new char[length];
System.arraycopy(word_array,0,permutation,0,length);
//First copy the original array and change
//only those character whose indexes are present in subset
for (int j =0; j < index.length; j++) {
permutation[index[j]] = (isBitSet(i, j)) ? Character.toUpperCase(permutation[index[j]]) : permutation[index[j]];
}
System.out.println(permutation);
}
}
public static boolean isBitSet(int n, int offset) {
return (n >> offset & 1) != 0;
}
public static ArrayList<Integer> lettersFound(String word, String rule_char_set) {
//Convert the two parameter strings to two character arrays
char[] wordArray = word.toLowerCase().toCharArray();
char[] rule_char_setArray = rule_char_set.toLowerCase().toCharArray();
//ArrayList to hold found characters;
ArrayList<Integer> found = new ArrayList<Integer>();
//Increments the found ArrayList that stores the existent values.
int foundCounter = 0;
for (int i = 0; i < rule_char_setArray.length; i++) {
for (int k = 0; k < wordArray.length; k++) {
if (rule_char_setArray[i] == wordArray[k]) {
found.add(foundCounter, k); //Store the index of the character that matches
foundCounter++;
}
}
}
return found;
}
}
Output :
tomorrow-today
Tomorrow-today
tomorrow-Today
Tomorrow-Today
tomorroW-today
TomorroW-today
tomorroW-Today
TomorroW-Today
Sanket Makani answer is perfect.
I may offer a more objective approach of this problem.
As an input you have a string to modify, and characters, which should be replaced with the modified case ( upper or lower ).
As an output you will have all permutated strings.
I would create a structure which contains index, and possible values to change with:
class Change {
int index;
char values[];
}
We will need to make all possible combinations, so lets include field which will tell which character is currently used in to our structure, and add some methods:
class Change {
int index;
char values[];
int cur;
void reset() {cur=0;}
boolen isMax(){return cur==values.length-1;}
void next(){cur++;}
char getValue(){ return values[cur]; }
}
We will have a list or array of these classes then, which we will put in to a separate class
class Combination {
Change changes[];
void reset() { for (Change c: changes) c.reset();}
boolean next() {
for ( int i=0; i<changes.length; i++)
if ( changes[i].isMax())
changes[i].reset(); // next change will be taken in cycle, with "next()"
else {changes[i].next(); return true;}
return false; // all changes are max
}
}
So when you initialize your "Combination" class by your input data, you may use it in cycle then.
Combination c = new Combination();
.... // initialization here
c.reset();
do {
... // update and print your string
} while ( c.next() );
The initialization of "Combination" and using of values for updating the input string I leave after you :)
For the permutation case, I think recursion is the best fit in terms of readability, taking into account that maybe is not best in terms of performance.
My approach would be this:
public static void main(String[] args) {
generateCombinations("hello", "l", "");
}
public static void generateCombinations(String text, String changingLetters, String current) {
if (0 == text.length()) {
System.out.println(current);
return;
}
String currentLetter = text.substring(0, 1);
if (changingLetters.contains(currentLetter)) {
generateCombinations(text.substring(1), changingLetters, current + currentLetter.toUpperCase());
}
generateCombinations(text.substring(1), changingLetters, current + currentLetter);
}
The output for the main execution will be:
heLLo
heLlo
helLo
hello

How to generate sums of combinations of elements of a set efficiently in terms of time and memory?

I have a random set S of integers and the cardinality (n) of this set may vary from 10 to 1000. I need to store all sums of the nCr combinations of size r generated from this set. Usually r range from 3 to 10.
E.g. if S={102,233,344,442,544,613,71289,836,97657,12} and r=4, Then The sums generated will be {0,1,2,3}=102+233+344+442, {0,1,2,4}=102+233+344+544,....so on.
I implemented a findCombi function (below) in Java which gave me all nCr combinations in terms of r sized sets of indices and then I sifted through these sets in another function to generate the sum of corresponding elements.
But the program is giving heapspace error, probably because of exponential nature and I have 100-5000 of such sets, S. Or may be there is a memory leak?
Is there a faster and lesser-memory consuming way to do it?
Note: dsize=n, combiSize=r
List <List<Integer>> findCombi(int dsize,int combiSize) {
if( (combiSize==0) || (dsize==0) ){
return null;
}
long n=dsize;
int r=combiSize;
for(int i=1;i<combiSize;i++) {
n=n*(dsize-i);
r=r*i;
}
int totalcombi=(int) n/r;
List <List<Integer>> combiData=new ArrayList<>(totalcombi);
int pos;
List <Integer> combi=new ArrayList<>(combiSize);
for(int i=0;i<combiSize;i++) {
combi.add(i,i);
}
combiData.add(new ArrayList<>(combi));
pos=combiSize-1;
while(true) {
if(combi.get(pos)<(dsize-combiSize+pos)) {
combi.set(pos,combi.get(pos)+1);
if(pos==(combiSize-1)) {
combiData.add(new ArrayList<>(combi));
}
else {
combi.set(pos+1,combi.get(pos));
pos++;
}
}
else {
pos--;
}
if(pos==-1) {
break;
}
}
return combiData;
}
I needed something like that earlier, so here is some code adapted from the project I made back then. The method allSums builds a list of indices of size r, which is used to represent all the possible combinations. At each step, the current sum is added to the result set, then the next combination is generated. Since the results are put in a set, there is no way a result could appear twice. I included a main method so you can see it work. I hope this is clear, feel free to ask questions.
import java.util.*;
public class Program {
static private Set<Integer> allSums(List<Integer> values, int r) {
HashSet<Integer> res = new HashSet<>();
if ((values.isEmpty()) || r > values.size()) {
return res;
}
// build the list of indices
List<Integer> li = new ArrayList<>();
for (int i = 0; i < r; i++) {
li.add(i);
}
li.add(values.size()); // artificial last index : number of elements in set
while (true) {
// add the current sum to the result
int sum = 0;
for (int i = 0; i < r; i++) {
sum += values.get(li.get(i));
}
res.add(sum);
// move to the next combination
// first, find the last index that can be incremented
int i = r-1;
while ((i >= 0) && (li.get(i) == li.get(i+1)-1)) {
i--;
}
// was such an index found ?
if (i == -1) {
break; // if not, it's over
}
// increment the last index and set all the next indices to their initial value
li.set(i,li.get(i)+1);
for (int j = i+1; j < r; j++) {
li.set(j, li.get(j-1)+1);
}
}
return res;
}
public static void main(String[] args) {
List<Integer> values = new ArrayList<>();
values.add(10);
values.add(100);
values.add(1000);
values.add(10000);
values.add(100000);
Set<Integer> s = allSums(values, 3);
for (int i : s) {
System.out.println(i);
}
}
}

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