Print number of possible non-empty sequences of letters - java

I want to print number of possible non-empty sequences of letters .
Eg.
String str="ABC";
Expected output is
A,B,C
AB,AC,BC,BA,CA,CB
ABC,ACB,BAC,BCA,CAB,CBA`
But i get the below output which is incorrect. How to fix my code
BB CC A AB ACC BC ABC AC B BBC CCC BCC C CBC CB
I have written the below code using Recurion
String tiles = "ABC";
Set<String> ans = new HashSet<>();
solve(tiles, 0, "", ans);
public static void solve(String tiles, int idx, String output, Set<String> ans) {
ans.add(output);
if (idx >= tiles.length()) {
return;
}
for (int i = idx; i < tiles.length(); i++) {
solve(tiles, idx + 1, output + tiles.charAt(i), ans);
}
}
This is how recursion tree would look like for str="AAB"

You need to ignore the first passing of the "" from output and then you need to ignore each letter you already passed through
public static void main(String[] args) {
String tiles = "ABC";
List<String> ans = new ArrayList<>();
solve(tiles, "", ans);
System.out.println(ans);
}
public static void solve(String tiles, String output, List<String> ans) {
if (!output.equals("")) ans.add(output);
for (int i = 0; i < tiles.length(); i++) {
String str = tiles.substring(0, i) + tiles.substring(i + 1);
solve(str, output + tiles.charAt(i), ans);
}
}
Output
[A, AB, ABC, AC, ACB, B, BA, BAC, BC, BCA, C, CA, CAB, CB, CBA]

you can try this
public class Permutation {
public static List<String> getPermutations(String str) {
Set<String> permutations = new HashSet<>();
permute(str, "", permutations);
return new ArrayList<>(permutations);
}
private static void permute(String string, String prefix, Set<String> permutations) {
if (string.length() == 0) {
permutations.add(prefix);
} else {
for (int i = 0; i < string.length(); i++) {
char charAt = string.charAt(i);
String remainingString = string.substring(0, i) + string.substring(i + 1);
permute(remainingString, prefix + charAt, permutations);
}
}
}
}
The "permute" method takes in 3 parameters: a string, a prefix string and a set of permutations.
The "permute" method takes in 3 parameters: a string, a prefix string and a set of permutations.
If the input string is not empty, it uses a for loop to iterate through the characters of the input string.
For each iteration, it gets the character at the current index, creates a new string by removing that character from the input string.
it then calls the permute method 3 times:
it then calls the permute method 3 times:
One with the original string and prefix
One with the remaining string and prefix
This way, the function explores all the possible permutations of the characters in the input string, including the option of not having one of the characters in the permutation and the permutation of positions, without including an empty string as an option.
Then you use like:
Permutation p = new Permutation();
List<String> permutations = p.getPermutations("abc");

Make 1 change:
Set<String> ans = new TreeSet<>(Comparators.comparing(String::length).thenComparing(s -> s));

It's a quite popular backtracking problem. You can find almost same problem here:
https://leetcode.com/problems/subsets/
The input are numbers instead of characters but the idea is the same.
You can switch to the solution tab and explore different answers:
https://leetcode.com/problems/subsets/solutions/

Related

Split a String after every n characters ignoring whitespaces in java store it in arraylist

I have a string which I want to split after every n characters and store the same in an array of strings, but this should ignore all the whitespaces.
For example I have a string as follows,
String str = "This is a String which needs to be splitted after every 10 characters";
The output should be,
["This is a Str", "ing which nee", "ds to be split", "ted after ev", "ery 10 chara", "cters"]
(Edit) --> I am using the function below. How can I store this in an array of Strings.
As seen in the output it ignores indexes of all the whitespaces. Is there any way to do it in java.
public static String test(int cnt, String string) {
AtomicInteger n = new AtomicInteger(cnt);
return string
.chars()
.boxed()
.peek(value -> {
if (!Character.isWhitespace(value)) {
n.decrementAndGet();
}
})
.takeWhile(value -> n.get() >= 0)
.map(Character::toString)
.collect(Collectors.joining());
I have used a standard approach with looping through the string and counting chars:
public static void main(String[] args) throws ParseException {
String str = "This is a String which needs to be splitted after every 10 characters";
System.out.println(split(str, 10));
}
public static List<String> split(String string, int splitAfter) {
List<String> result = new ArrayList<String>();
int startIndex = 0;
int charCount = 0;
for (int i = 0; i < string.length(); i++) {
if (charCount == splitAfter) {
result.add(string.substring(startIndex, i));
startIndex = i;
charCount = 0;
}
// only count non-whitespace characters
if (string.charAt(i) != ' ') {
charCount++;
}
}
// check if startIndex is less than string length -> if yes, then last element wont be 10 characters long
if (startIndex < string.length()) {
result.add(string.substring(startIndex));
}
return result;
}
And the result differs slightly from what you posted, but looking at your expected result, it doesn't quite match the description anyways:
[This is a Str, ing which ne, eds to be spl, itted after, every 10 cha, racters]

Storing and printing consecutive characters in a String?

the task is to store consecutive characters in a List. Main with Input/Output looks like this:
public static void main(String[] args) {
List<String> blocks = blocks("Hello faaantastic world");
System.out.println(blocks); // => ["ll", "aaa"]
System.out.println(blocks("aaabccdeeeefaaa")); // => ["aaa", "cc", "eeee", "aaa"]
System.out.println(blocks("This is an example")); // => []
System.out.println(blocks("Another example ...")); // => [" ", "..."]
System.out.println(blocks("")); // => []
My method looks like this:
public static LinkedList<String> blocks(String s) {
LinkedList<String> list = new LinkedList<>();
String word = "";
for(char c : s.toCharArray()) {
if (c == ??) {
}
}
return list;
the String word is used to store consecutive letters. I found the toCharArray, to split each character of the String. But I have a problem with the if-block. If I do c == c+1 to check I and the following character of I, it's not working...I don't know how to solve this problem. Can someone help me? trying to solve it for 2 days now...
There are other ways to write this code, but to fully use what you have done, just cache the prevChar so you can compare c with it. How to init prevChar is tricky, either to choose something not possible in the text, or add another bool variable to indicate you are working on the first char, or peek into the array to make sure prevChar is different from the 1st char.
In this case it may be preferable to use String::charAt method to retrieve characters in the input string and their comparing to previous character.
public static LinkedList<String> blocks(String s) {
LinkedList<String> list = new LinkedList<>();
String word = "" + s.charAt(0);
for(int i = 1, n = s.length(); i < n; i++) {
if (s.charAt(i) == s.charAt(i - 1)) {
word += s.charAt(i);
} else {
if (word.length() > 1) {
list.add(word);
}
word = "" + s.charAt(i);
}
}
if (word.length() > 1) {
list.add(word);
}
return list;
}
Test
System.out.println(blocks("Hello faaantastic worlddd"));
Output
[ll, aaa, ddd]
A shorter solution is possible using a regular expression to find repeating characters (.)\1+:
public static List<String> findConsecutive(String s) {
return Pattern.compile("(.)\\1+").matcher(s).results() // Stream<MatchResult>
.map(mr -> mr.group(0)) // 0 group contains repeated characters
.collect(Collectors.toList());
}
Test
System.out.println(findConsecutive("Hello faaantastic worlddd"));
Output
[ll, , aaa, ddd]

Recursively generate string array of all combinations (of length k) of characters in a char array

For java practice, I'm trying to write a class that generates all combinations of letters in a character array and puts them in String array.
The object should be built with a character array, and it should have a method that takes an int as input. The int will determine how long the combinations should be.
So, for example, input:
char[] charArray = { 'a', 'b' };
int k = 3;
Output:
[ "aaa", "aab", "aba", "abb", "baa", "bab", "bba", "bbb" ]
The method should be recursive, each time it should call itself with k-1.
I've tried a simplified version, generating a String with all the permutations separated by an underscore, but I'm not getting the output I want.
public String generate(int k) {
if (k == 0) return "_";
String s = "";
for (char c : charArray) {
s = s+c+generate(k-1);
}
return s;
}
My output is:
"aaa_b_ba_b_baa_b_ba_b_"
Instead of:
"aaa_aab_aba_abb_baa_bab_bba_bbb"
You need one more parameter for your method which holds prevalues.
You can try below code segment for your purpose:
public static String generate(String prefix, int k) {
String s = "";
if (k == 0)
return prefix + "_";
for (char c : charArray) {
String newPrefix = prefix + c;
s = s + generate(newPrefix, k - 1);
}
return s;
}
This code will generate "aaa_aab_aba_abb_baa_bab_bba_bbb_" so you have to remove last underscore.
Try something like this (uses java 8):
public String generate(String[] stringArray, String accumulator, int k) {
if (k == 0) return accumulator;
return Arrays.stream(stringArray).map(s -> generate(accumulator + s, k - 1)).collect(Collectors.joining("_"));
}
public String generate(String[] stringArray, int k) {
returngenerate(stringArray, "", k);
}
I just needed to change the array of chars to array of Strings:
String[] stringArray = new String[]{ "a", "b" };
Then invoking the method generate(stringArray, 3) generates the result:
aaa_aab_aba_abb_baa_bab_bba_bbb

Creating substrings array from a string

I have a string that has no spaces and I wanted to create an array that consists of the substrings of the word. For instance, let the string is stackoverflow The array should be like:
[sta, cko, ver, flo, w]
The code that I use is below and that does give me only the first item. Any help will be appreciated.
public static ArrayList<String> getWords(String s){
ArrayList<String> words = new ArrayList<String>();
for(int i=0;i<s.length(); i=i+3){
words.add(s.substring(i, 3));
}
return words;
}
There are two issues with your code. First, the "3" in
s.substring(i, 3)
means the 3rd index from the beginning of the string, not the 3rd index from i, so you'd want
s.substring(i, i + 3)
Second, if the string is shorter than i + 3, you'll get an exception. To solve this, you can use Math.min. It would look something like this:
public static ArrayList<String> getWords(String s){
ArrayList<String> words = new ArrayList<String>();
for(int i=0;i<s.length(); i=i+3){
words.add(s.substring(i, Math.min(i + 3, i.length())));
}
return words;
}
You need to pass i + 3 as the second parameter of the substring call (it takes begin and end indexes). Also, I would prefer to program to the List interface. You might use += instead of i = i + 3. And you need an else clause for when there aren't three letters in the String. Like,
public static List<String> getWords(String s) {
List<String> words = new ArrayList<>();
for (int i = 0; i < s.length(); i += 3) {
if (i + 3 < s.length()) {
words.add(s.substring(i, i + 3));
} else {
words.add(s.substring(i));
}
}
return words;
}
Then, for completeness, I tested it with a basic main method like
public static void main(String[] args) {
System.out.println(getWords("stackoverflow"));
}
Which outputs (as requested)
[sta, cko, ver, flo, w]
You are on the right track, but your substring should be (i, i+3) as the following:
public static ArrayList<String> getWords(String s){
ArrayList<String> words = new ArrayList<String>();
for(int i=0;i<s.length(); i+=3){
if (i+3 >= s.length())
words.add(s.substring(i));
else
words.add(s.substring(i, i+3));
}
return words;
You can ease it significantly by using guava's Splitter:
String f = "stackoverflow";
List<String> p = Splitter.fixedLength(3).splitToList(f);
System.out.println(p); // [sta, cko, ver, flo, w]

How would I split this expression with regex?

I'm working on solving an equation but I will like to use the constants to program my solution.
The method I'm working on is called decompose which decomposes the equation into constants. The problem is that when I split, an equation with a negative constant will yield an array with the absolute value of the constants. How can I achieve the minus sign while still using regex?
If the input is ax+by=c, the output should be {a,b,c}.
Helpful bonus: Is there a way to delete the empty elements that is created when I split. For example, if I type equation 2x+3y=6, I end up with a "raw" array that contains the elements {2,,3,,6}
Code:
public static int[] decompose(String s)
{
s = s.replaceAll(" ", "");
String[] termRaw = s.split("\\D"); //Splits the equation into constants *and* empty spaces.
ArrayList<Integer> constants = new ArrayList<Integer>(); //Values are placed into here if they are integers.
for(int k = 0 ; k < termRaw.length ; k++)
{
if(!(termRaw[k].equals("")))
{
constants.add(Integer.parseInt(termRaw[k]));
}
}
int[] ans = new int[constants.size()];
for(int k = 0 ; k < constants.size(); k++) //ArrayList to int[]
{
ans[k] = constants.get(k);
}
return ans;
}
The general strategy to this answer is to split the input equation by operator, then extract out the coefficients in a loop. However, there are several edge cases which need to be considered:
a plus symbol (+) is prefixed to every minus which does not appear either as the first term
after splitting, a coefficient of positive one is detected by seeing empty string
after splitting, a coefficient of negative one is detected by seeing a minus sign
String input = "-22x-77y+z=-88-10+33z-q";
input = input.replaceAll(" ", "") // remove whitespace
.replaceAll("=-", "-"); // remove equals sign
.replaceAll("(?<!^)-", "+-"); // replace - with +-, except at start of line
// input = -22x+-77y+z+-88+-10+33z+-
String[] termRaw = bozo.split("[\\+*/=]");
// termRaw contains [-22x, -77y, z, -88, -10, 33z, -]
ArrayList<Integer> constants = new ArrayList<Integer>();
// after splitting,
// termRaw contains [-22, -77, '', -88, -10, 33, '-']
for (int k=0 ; k < termRaw.length ; k++) {
termRaw[k] = termRaw[k].replaceAll("[a-zA-Z]", "");
if (termRaw[k].equals("")) {
constants.add(1);
}
else if (termRaw[k].equals("-")) {
constants.add(-1);
}
else {
constants.add(Integer.parseInt(termRaw[k]));
}
}
If you're using java8, then you can use this one line method:
public static int[] decompose(String s) {
return Arrays.stream(s.replaceAll("[^0-9]", " ").split("\\s+")).mapToInt(Integer::parseInt).toArray();
}
DEMO:
1. Output
[2, 3, 6]
2. Code
import java.util.*;
public class HelloWorld {
public static void main(String args[]) {
String s = "2x+3y=6";
int[] array = decompose(s);
System.out.println(Arrays.toString(array));
}
public static int[] decompose(String s) {
return Arrays.stream(s.replaceAll("[^0-9]", " ").split("\\s+")).mapToInt(Integer::parseInt).toArray();
}
}

Categories