Randomize and shuffling a string without using stringbuilder or power tools - java

I want to shuffle a string without using any arrays, StringBuilder, or power tools (packages or methods that do the work for you) and using Math.random().
My code below works but I don't like it because I can't use string builder or .append(). Could someone help me and fix it?
public class loopPrr
{
static String shuffle(int a) {
String s = "BaaBooDaaDoo";
StringBuilder sb = new StringBuilder(a);
for (int i = 0; i < a; i++) {
int r = (int)(s.length() * Math.random());
sb.append(s.charAt(r));
}
return sb.toString();
}
}

If I got it right, you can simply use String:
static String shuffle(int a) {
String s = "BaaBooDaaDoo";
String sb = "";
for (int i = 0; i < a; i++) {
int r = (int) (s.length() * Math.random());
sb += s.charAt(r);
}
return sb;
}
I would suggest changing the name of "sb" variable to avoid misunderstanding though.

It is possible to shuffle a string by applying Fisher--Yates algorithm to the character array of the input string.
The algorithm basically consists in swapping the characters at randomized indexes as shown below.
static String shuffle(String str) {
char[] arr = str.toCharArray();
for (int i = str.length() - 1; i > 0 ; i--) { // starting from the last character
int x = (int)(i * Math.random()); // next index is in range [0...i-1]
char t = arr[i];
arr[i] = arr[x];
arr[x] = t;
}
return new String(arr);
}
If a randomized String of length a from the predefined alphabet needs to be generated, the following method can be implemented based on previous implementation for String to guarantee that all characters of the alphabet are used at least once if a >= alphabet.length:
private static final String LETTERS = "AaBbCcDdEe";
static String shuffle(int a) {
if (a <= 0) {
return "";
}
if (a < LETTERS.length()) {
char[] res = new char[a];
for (int i = 0, x = LETTERS.length(); x > 0 && i < a; i++, x--) {
res[i] = LETTERS.charAt((int)(Math.random() * x));
}
return new String(res);
}
return shuffle(shuffle(LETTERS) + shuffle(a - LETTERS.length()));
}

Related

Highly effect find a byte[] is contained by another byte[] [duplicate]

Given a byte array, how can I find within it, the position of a (smaller) byte array?
This documentation looked promising, using ArrayUtils, but if I'm correct it would only let me find an individual byte within the array to be searched.
(I can't see it mattering, but just in case: sometimes the search byte array will be regular ASCII characters, other times it will be control characters or extended ASCII characters. So using String operations would not always be appropriate)
The large array could be between 10 and about 10000 bytes, and the smaller array around 10. In some cases I will have several smaller arrays that I want found within the larger array in a single search. And I will at times want to find the last index of an instance rather than the first.
The simpelst way would be to compare each element:
public int indexOf(byte[] outerArray, byte[] smallerArray) {
for(int i = 0; i < outerArray.length - smallerArray.length+1; ++i) {
boolean found = true;
for(int j = 0; j < smallerArray.length; ++j) {
if (outerArray[i+j] != smallerArray[j]) {
found = false;
break;
}
}
if (found) return i;
}
return -1;
}
Some tests:
#Test
public void testIndexOf() {
byte[] outer = {1, 2, 3, 4};
assertEquals(0, indexOf(outer, new byte[]{1, 2}));
assertEquals(1, indexOf(outer, new byte[]{2, 3}));
assertEquals(2, indexOf(outer, new byte[]{3, 4}));
assertEquals(-1, indexOf(outer, new byte[]{4, 4}));
assertEquals(-1, indexOf(outer, new byte[]{4, 5}));
assertEquals(-1, indexOf(outer, new byte[]{4, 5, 6, 7, 8}));
}
As you updated your question: Java Strings are UTF-16 Strings, they do not care about the extended ASCII set, so you could use string.indexOf()
Google's Guava provides a Bytes.indexOf(byte[] array, byte[] target).
Using the Knuth–Morris–Pratt algorithm is the most efficient way.
StreamSearcher.java is an implementation of it and is part of Twitter's elephant-bird project.
It is not recommended to include this library since it is rather sizable for using just a single class.
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
/**
* An efficient stream searching class based on the Knuth-Morris-Pratt algorithm.
* For more on the algorithm works see: http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/kmpen.htm.
*/
public class StreamSearcher
{
private byte[] pattern_;
private int[] borders_;
// An upper bound on pattern length for searching. Results are undefined for longer patterns.
#SuppressWarnings("unused")
public static final int MAX_PATTERN_LENGTH = 1024;
StreamSearcher(byte[] pattern)
{
setPattern(pattern);
}
/**
* Sets a new pattern for this StreamSearcher to use.
*
* #param pattern the pattern the StreamSearcher will look for in future calls to search(...)
*/
public void setPattern(byte[] pattern)
{
pattern_ = Arrays.copyOf(pattern, pattern.length);
borders_ = new int[pattern_.length + 1];
preProcess();
}
/**
* Searches for the next occurrence of the pattern in the stream, starting from the current stream position. Note
* that the position of the stream is changed. If a match is found, the stream points to the end of the match -- i.e. the
* byte AFTER the pattern. Else, the stream is entirely consumed. The latter is because InputStream semantics make it difficult to have
* another reasonable default, i.e. leave the stream unchanged.
*
* #return bytes consumed if found, -1 otherwise.
*/
long search(InputStream stream) throws IOException
{
long bytesRead = 0;
int b;
int j = 0;
while ((b = stream.read()) != -1)
{
bytesRead++;
while (j >= 0 && (byte) b != pattern_[j])
{
j = borders_[j];
}
// Move to the next character in the pattern.
++j;
// If we've matched up to the full pattern length, we found it. Return,
// which will automatically save our position in the InputStream at the point immediately
// following the pattern match.
if (j == pattern_.length)
{
return bytesRead;
}
}
// No dice, Note that the stream is now completely consumed.
return -1;
}
/**
* Builds up a table of longest "borders" for each prefix of the pattern to find. This table is stored internally
* and aids in implementation of the Knuth-Moore-Pratt string search.
* <p>
* For more information, see: http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/kmpen.htm.
*/
private void preProcess()
{
int i = 0;
int j = -1;
borders_[i] = j;
while (i < pattern_.length)
{
while (j >= 0 && pattern_[i] != pattern_[j])
{
j = borders_[j];
}
borders_[++i] = ++j;
}
}
}
Is this what you are looking for?
public class KPM {
/**
* Search the data byte array for the first occurrence of the byte array pattern within given boundaries.
* #param data
* #param start First index in data
* #param stop Last index in data so that stop-start = length
* #param pattern What is being searched. '*' can be used as wildcard for "ANY character"
* #return
*/
public static int indexOf( byte[] data, int start, int stop, byte[] pattern) {
if( data == null || pattern == null) return -1;
int[] failure = computeFailure(pattern);
int j = 0;
for( int i = start; i < stop; i++) {
while (j > 0 && ( pattern[j] != '*' && pattern[j] != data[i])) {
j = failure[j - 1];
}
if (pattern[j] == '*' || pattern[j] == data[i]) {
j++;
}
if (j == pattern.length) {
return i - pattern.length + 1;
}
}
return -1;
}
/**
* Computes the failure function using a boot-strapping process,
* where the pattern is matched against itself.
*/
private static int[] computeFailure(byte[] pattern) {
int[] failure = new int[pattern.length];
int j = 0;
for (int i = 1; i < pattern.length; i++) {
while (j>0 && pattern[j] != pattern[i]) {
j = failure[j - 1];
}
if (pattern[j] == pattern[i]) {
j++;
}
failure[i] = j;
}
return failure;
}
}
To save your time in testing:
http://helpdesk.objects.com.au/java/search-a-byte-array-for-a-byte-sequence
gives you code that works if you make computeFailure() static:
public class KPM {
/**
* Search the data byte array for the first occurrence
* of the byte array pattern.
*/
public static int indexOf(byte[] data, byte[] pattern) {
int[] failure = computeFailure(pattern);
int j = 0;
for (int i = 0; i < data.length; i++) {
while (j > 0 && pattern[j] != data[i]) {
j = failure[j - 1];
}
if (pattern[j] == data[i]) {
j++;
}
if (j == pattern.length) {
return i - pattern.length + 1;
}
}
return -1;
}
/**
* Computes the failure function using a boot-strapping process,
* where the pattern is matched against itself.
*/
private static int[] computeFailure(byte[] pattern) {
int[] failure = new int[pattern.length];
int j = 0;
for (int i = 1; i < pattern.length; i++) {
while (j>0 && pattern[j] != pattern[i]) {
j = failure[j - 1];
}
if (pattern[j] == pattern[i]) {
j++;
}
failure[i] = j;
}
return failure;
}
}
Since it is always wise to test the code that you borrow, you may start with:
public class Test {
public static void main(String[] args) {
do_test1();
}
static void do_test1() {
String[] ss = { "",
"\r\n\r\n",
"\n\n",
"\r\n\r\nthis is a test",
"this is a test\r\n\r\n",
"this is a test\r\n\r\nthis si a test",
"this is a test\r\n\r\nthis si a test\r\n\r\n",
"this is a test\n\r\nthis si a test",
"this is a test\r\nthis si a test\r\n\r\n",
"this is a test"
};
for (String s: ss) {
System.out.println(""+KPM.indexOf(s.getBytes(), "\r\n\r\n".getBytes())+"in ["+s+"]");
}
}
}
Copied almost identical from java.lang.String.
indexOf(char[],int,int,char[]int,int,int)
static int indexOf(byte[] source, int sourceOffset, int sourceCount, byte[] target, int targetOffset, int targetCount, int fromIndex) {
if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1);
}
if (fromIndex < 0) {
fromIndex = 0;
}
if (targetCount == 0) {
return fromIndex;
}
byte first = target[targetOffset];
int max = sourceOffset + (sourceCount - targetCount);
for (int i = sourceOffset + fromIndex; i <= max; i++) {
/* Look for first character. */
if (source[i] != first) {
while (++i <= max && source[i] != first)
;
}
/* Found first character, now look at the rest of v2 */
if (i <= max) {
int j = i + 1;
int end = j + targetCount - 1;
for (int k = targetOffset + 1; j < end && source[j] == target[k]; j++, k++)
;
if (j == end) {
/* Found whole string. */
return i - sourceOffset;
}
}
}
return -1;
}
package org.example;
import java.util.List;
import org.riversun.finbin.BinarySearcher;
public class Sample2 {
public static void main(String[] args) throws Exception {
BinarySearcher bs = new BinarySearcher();
// UTF-8 without BOM
byte[] srcBytes = "Hello world.It's a small world.".getBytes("utf-8");
byte[] searchBytes = "world".getBytes("utf-8");
List<Integer> indexList = bs.searchBytes(srcBytes, searchBytes);
System.out.println("indexList=" + indexList);
}
}
so it results in
indexList=[6, 25]
So,u can find the index of byte[] in byte[]
Example here on Github at: https://github.com/riversun/finbin
Several (or all?) of the examples posted here failed some Unit tests so I am posting my version along with the aforementioned tests over here. All of the Unit tests are BASED upon the requirement that Java's String.indexOf() always gives us the right answer!
// The Knuth, Morris, and Pratt string searching algorithm remembers information about
// the past matched characters instead of matching a character with a different pattern
// character over and over again. It can search for a pattern in O(n) time as it never
// re-compares a text symbol that has matched a pattern symbol. But, it does use a partial
// match table to analyze the pattern structure. Construction of a partial match table
// takes O(m) time. Therefore, the overall time complexity of the KMP algorithm is O(m + n).
public class KMPSearch {
public static int indexOf(byte[] haystack, byte[] needle)
{
// needle is null or empty
if (needle == null || needle.length == 0)
return 0;
// haystack is null, or haystack's length is less than that of needle
if (haystack == null || needle.length > haystack.length)
return -1;
// pre construct failure array for needle pattern
int[] failure = new int[needle.length];
int n = needle.length;
failure[0] = -1;
for (int j = 1; j < n; j++)
{
int i = failure[j - 1];
while ((needle[j] != needle[i + 1]) && i >= 0)
i = failure[i];
if (needle[j] == needle[i + 1])
failure[j] = i + 1;
else
failure[j] = -1;
}
// find match
int i = 0, j = 0;
int haystackLen = haystack.length;
int needleLen = needle.length;
while (i < haystackLen && j < needleLen)
{
if (haystack[i] == needle[j])
{
i++;
j++;
}
else if (j == 0)
i++;
else
j = failure[j - 1] + 1;
}
return ((j == needleLen) ? (i - needleLen) : -1);
}
}
import java.util.Random;
class KMPSearchTest {
private static Random random = new Random();
private static String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
#Test
public void testEmpty() {
test("", "");
test("", "ab");
}
#Test
public void testOneChar() {
test("a", "a");
test("a", "b");
}
#Test
public void testRepeat() {
test("aaa", "aaaaa");
test("aaa", "abaaba");
test("abab", "abacababc");
test("abab", "babacaba");
}
#Test
public void testPartialRepeat() {
test("aaacaaaaac", "aaacacaacaaacaaaacaaaaac");
test("ababcababdabababcababdaba", "ababcababdabababcababdaba");
}
#Test
public void testRandomly() {
for (int i = 0; i < 1000; i++) {
String pattern = randomPattern();
for (int j = 0; j < 100; j++)
test(pattern, randomText(pattern));
}
}
/* Helper functions */
private static String randomPattern() {
StringBuilder sb = new StringBuilder();
int steps = random.nextInt(10) + 1;
for (int i = 0; i < steps; i++) {
if (sb.length() == 0 || random.nextBoolean()) { // Add literal
int len = random.nextInt(5) + 1;
for (int j = 0; j < len; j++)
sb.append(alphabet.charAt(random.nextInt(alphabet.length())));
} else { // Repeat prefix
int len = random.nextInt(sb.length()) + 1;
int reps = random.nextInt(3) + 1;
if (sb.length() + len * reps > 1000)
break;
for (int j = 0; j < reps; j++)
sb.append(sb.substring(0, len));
}
}
return sb.toString();
}
private static String randomText(String pattern) {
StringBuilder sb = new StringBuilder();
int steps = random.nextInt(100);
for (int i = 0; i < steps && sb.length() < 10000; i++) {
if (random.nextDouble() < 0.7) { // Add prefix of pattern
int len = random.nextInt(pattern.length()) + 1;
sb.append(pattern.substring(0, len));
} else { // Add literal
int len = random.nextInt(30) + 1;
for (int j = 0; j < len; j++)
sb.append(alphabet.charAt(random.nextInt(alphabet.length())));
}
}
return sb.toString();
}
private static void test(String pattern, String text) {
try {
assertEquals(text.indexOf(pattern), KMPSearch.indexOf(text.getBytes(), pattern.getBytes()));
} catch (AssertionError e) {
System.out.println("FAILED -> Unable to find '" + pattern + "' in '" + text + "'");
}
}
}
Java strings are composed of 16-bit chars, not of 8-bit bytes. A char can hold a byte, so you can always make your byte arrays into strings, and use indexOf: ASCII characters, control characters, and even zero characters will work fine.
Here is a demo:
byte[] big = new byte[] {1,2,3,0,4,5,6,7,0,8,9,0,0,1,2,3,4};
byte[] small = new byte[] {7,0,8,9,0,0,1};
String bigStr = new String(big, StandardCharsets.UTF_8);
String smallStr = new String(small, StandardCharsets.UTF_8);
System.out.println(bigStr.indexOf(smallStr));
This prints 7.
However, considering that your large array could be up to 10,000 bytes, and the small array is only ten bytes, this solution may not be the most efficient, for two reasons:
It requires copying your big array into an array that is twice as large (same capacity, but with char instead of byte). This triples your memory requirements.
String search algorithm of Java is not the fastest one available. You may get sufficiently faster if you implement one of the advanced algorithms, for example, the Knuth–Morris–Pratt one. This could potentially bring the execution speed down by a factor of up to ten (the length of the small string), and will require additional memory that is proportional to the length of the small string, not the big string.
For a little HTTP server I am currently working on, I came up with the following code to find boundaries in a multipart/form-data request. Hoped to find a better solution here, but i guess I'll stick with it. I think it is as efficent as it can get (quite fast and uses not much ram). It uses the input bytes as ring buffer, reads the next byte as soon as it does not match the boundary and writes the data after the first full cycle into the output stream. Of course can it be changed for byte arrays instead of streams, as asked in the question.
private boolean multipartUploadParseOutput(InputStream is, OutputStream os, String boundary)
{
try
{
String n = "--"+boundary;
byte[] bc = n.getBytes("UTF-8");
int s = bc.length;
byte[] b = new byte[s];
int p = 0;
long l = 0;
int c;
boolean r;
while ((c = is.read()) != -1)
{
b[p] = (byte) c;
l += 1;
p = (int) (l % s);
if (l>p)
{
r = true;
for (int i = 0; i < s; i++)
{
if (b[(p + i) % s] != bc[i])
{
r = false;
break;
}
}
if (r)
break;
os.write(b[p]);
}
}
os.flush();
return true;
} catch(IOException e) {e.printStackTrace();}
return false;
}

String Index out of Range:java

I just want to create a application that could covert natural language into sql queries, in this snippet I want to extract the numbers from a given string.I don't why I am getting this error. Regardless of the length I enter it results with the same error.
public void insert(String low) {
String character = low;
int l = low.length();
int j[] = new int[20];
int m = 0;
for (int k = 0; k <= 2; k++) {
for (int i = 0; i <= l; i++) {
char c = character.charAt(i);
if (Character.isDigit(c)) {
String str = Character.toString(c);
j[k] = (j[k] * 10) + Integer.parseInt(str);
m++;
} else if (Character.isLetter(c)) {
if (m > 2) {
break;
}
}
}
}
for (int k = 0; k <= 2; k++) {
jTextField2.setText(Integer.toString(j[k]));
}
}
public void check(String low) {
int j;
String[] ins = {"into", "add", "insert"};
String cc = low;
for (int i = 0; i < 2; i++) {
String dd = ins[i];
if (cc.contains(dd)) {
j = 1;
insert(cc);
break;
}
}
}
If you're trying to extract all the numbers in a string, I'd highly recommend using regular expressions rather than writing your own code to loop over characters. How about something like this:
public List<Integer> extractNumbers(String line){
// Construct regex
Pattern digitsPattern = Pattern.compile("\\d+");
Matcher m = digitsPattern.matcher(line);
// Compile into list
List<Integer> numberList = new ArrayList<Integer>();
while (m.find()){
numberList.add(Integer.parseInt(m.group()));
}
return numberList;
}
Regular expressions are extremely powerful, mature and elegant - as you see here, you can do this in a couple of fairly simple lines, and if you ever need to change the matching rules you'll have a much simpler job.
change
for(int i=0;i<=l;i++)
{
char c = character.charAt(i);
..........
}
to
for(int i=0;i<l;i++)
{
char c = character.charAt(i);
..........
}
When you are write i<=l , the last iteration of the loop will execute character.chatAt(l), which is not present because indexing starts from 0 and only 0,1,2, .....l-1 characters are available. So executing character.chatAt(l) throws IndexOutofBound exception which is self explanatory.

Finding the intersection between two list of string candidates

I wrote the following Java code, to find the intersection between the prefix and the suffix of a String in Java.
// you can also use imports, for example:
// import java.math.*;
import java.util.*;
class Solution {
public int max_prefix_suffix(String S) {
if (S.length() == 0) {
return 1;
}
// prefix candidates
Vector<String> prefix = new Vector<String>();
// suffix candidates
Vector<String> suffix = new Vector<String>();
// will tell me the difference
Set<String> set = new HashSet<String>();
int size = S.length();
for (int i = 0; i < size; i++) {
String candidate = getPrefix(S, i);
// System.out.println( candidate );
prefix.add(candidate);
}
for (int i = size; i >= 0; i--) {
String candidate = getSuffix(S, i);
// System.out.println( candidate );
suffix.add(candidate);
}
int p = prefix.size();
int s = suffix.size();
for (int i = 0; i < p; i++) {
set.add(prefix.get(i));
}
for (int i = 0; i < s; i++) {
set.add(suffix.get(i));
}
System.out.println("set: " + set.size());
System.out.println("P: " + p + " S: " + s);
int max = (p + s) - set.size();
return max;
}
// codility
// y t i l i d o c
public String getSuffix(String S, int index) {
String suffix = "";
int size = S.length();
for (int i = size - 1; i >= index; i--) {
suffix += S.charAt(i);
}
return suffix;
}
public String getPrefix(String S, int index) {
String prefix = "";
for (int i = 0; i <= index; i++) {
prefix += S.charAt(i);
}
return prefix;
}
public static void main(String[] args) {
Solution sol = new Solution();
String t1 = "";
String t2 = "abbabba";
String t3 = "codility";
System.out.println(sol.max_prefix_suffix(t1));
System.out.println(sol.max_prefix_suffix(t2));
System.out.println(sol.max_prefix_suffix(t3));
System.exit(0);
}
}
Some test cases are:
String t1 = "";
String t2 = "abbabba";
String t3 = "codility";
and the expected values are:
1, 4, 0
My idea was to produce the prefix candidates and push them into a vector, then find the suffix candidates and push them into a vector, finally push both vectors into a Set and then calculate the difference. However, I'm getting 1, 7, and 0. Could someone please help me figure it out what I'm doing wrong?
I'd write your method as follows:
public int max_prefix_suffix(String s) {
final int len = s.length();
if (len == 0) {
return 1; // there's some dispute about this in the comments to your post
}
int count = 0;
for (int i = 1; i <= len; ++i) {
final String prefix = s.substring(0, i);
final String suffix = s.substring(len - i, len);
if (prefix.equals(suffix)) {
++count;
}
}
return count;
}
If you need to compare the prefix to the reverse of the suffix, I'd do it like this:
final String suffix = new StringBuilder(s.substring(len - i, len))
.reverse().toString();
I see that the code by #ted Hop is good..
The question specify to return the max number of matching characters in Suffix and Prefix of a given String, which is a proper subset. Hence the entire string is not taken into consideration for this max number.
Ex. "abbabba", prefix and suffix can have abba(first 4 char) - abba (last 4 char),, hence the length 4
codility,, prefix(c, co,cod,codi,co...),, sufix (y, ty, ity, lity....), none of them are same.
hence length here is 0.
By modifying the count here from
if (prefix.equals(suffix)) {
++count;
}
with
if (prefix.equals(suffix)) {
count = prefix.length();// or suffix.length()
}
we get the max length.
But could this be done in O(n).. The inbuilt function of string equals, i believe would take O(n), and hence overall complexity is made O(n2).....
i would use this code.
public static int max_prefix_suffix(String S)
{
if (S == null)
return -1;
Set<String> set = new HashSet<String>();
int len = S.length();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < len - 1; i++)
{
builder.append(S.charAt(i));
set.add(builder.toString());
}
int max = 0;
for (int i = 1; i < len; i++)
{
String suffix = S.substring(i, len);
if (set.contains(suffix))
{
int suffLen = suffix.length();
if (suffLen > max)
max = suffLen;
}
}
return max;
}
#ravi.zombie
If you need the length in O(n) then you just need to change Ted's code as below:
int max =0;
for (int i = 1; i <= len-1; ++i) {
final String prefix = s.substring(0, i);
final String suffix = s.substring(len - i, len);
if (prefix.equals(suffix) && max < i) {
max =i;
}
return max;
}
I also left out the entire string comparison to get proper prefix and suffixes so this should return 4 and not 7 for an input string abbabba.

Permutate a String to upper and lower case

I have a string, "abc". How would a program look like (if possible, in Java) who permute the String?
For example:
abc
ABC
Abc
aBc
abC
ABc
abC
AbC
Something like this should do the trick:
void printPermutations(String text) {
char[] chars = text.toCharArray();
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);
}
}
boolean isBitSet(int n, int offset) {
return (n >> offset & 1) != 0;
}
As you probably already know, the number of possible different combinations is 2^n, where n equals the length of the input string.
Since n could theoretically be fairly large, there's a chance that 2^n will exceed the capacity of a primitive type such as an int. (The user may have to wait a few years for all of the combinations to finish printing, but that's their business.)
Instead, let's use a bit vector to hold all of the possible combinations. We'll set the number of bits equal to n and initialize them all to 1. For example, if the input string is "abcdefghij", the initial bit vector values will be {1111111111}.
For every combination, we simply have to loop through all of the characters in the input string and set each one to uppercase if its corresponding bit is a 1, else set it to lowercase. We then decrement the bit vector and repeat.
For example, the process would look like this for an input of "abc":
Bits:   Corresponding Combo:
111    ABC
110    ABc
101    AbC
100    Abc
011    aBC
010    aBc
001    abC
000    abc
By using a loop rather than a recursive function call, we also avoid the possibility of a stack overflow exception occurring on large input strings.
Here is the actual implementation:
import java.util.BitSet;
public void PrintCombinations(String input) {
char[] currentCombo = input.toCharArray();
// Create a bit vector the same length as the input, and set all of the bits to 1
BitSet bv = new BitSet(input.length());
bv.set(0, currentCombo.length);
// While the bit vector still has some bits set
while(!bv.isEmpty()) {
// Loop through the array of characters and set each one to uppercase or lowercase,
// depending on whether its corresponding bit is set
for(int i = 0; i < currentCombo.length; ++i) {
if(bv.get(i)) // If the bit is set
currentCombo[i] = Character.toUpperCase(currentCombo[i]);
else
currentCombo[i] = Character.toLowerCase(currentCombo[i]);
}
// Print the current combination
System.out.println(currentCombo);
// Decrement the bit vector
DecrementBitVector(bv, currentCombo.length);
}
// Now the bit vector contains all zeroes, which corresponds to all of the letters being lowercase.
// Simply print the input as lowercase for the final combination
System.out.println(input.toLowerCase());
}
public void DecrementBitVector(BitSet bv, int numberOfBits) {
int currentBit = numberOfBits - 1;
while(currentBit >= 0) {
bv.flip(currentBit);
// If the bit became a 0 when we flipped it, then we're done.
// Otherwise we have to continue flipping bits
if(!bv.get(currentBit))
break;
currentBit--;
}
}
String str = "Abc";
str = str.toLowerCase();
int numOfCombos = 1 << str.length();
for (int i = 0; i < numOfCombos; i++) {
char[] combinations = str.toCharArray();
for (int j = 0; j < str.length(); j++) {
if (((i >> j) & 1) == 1 ) {
combinations[j] = Character.toUpperCase(str.charAt(j));
}
}
System.out.println(new String(combinations));
}
You can also use backtracking to solve this problem:
public List<String> letterCasePermutation(String S) {
List<String> result = new ArrayList<>();
backtrack(0 , S, "", result);
return result;
}
private void backtrack(int start, String s, String temp, List<String> result) {
if(start >= s.length()) {
result.add(temp);
return;
}
char c = s.charAt(start);
if(!Character.isAlphabetic(c)) {
backtrack(start + 1, s, temp + c, result);
return;
}
if(Character.isUpperCase(c)) {
backtrack(start + 1, s, temp + c, result);
c = Character.toLowerCase(c);
backtrack(start + 1, s, temp + c, result);
}
else {
backtrack(start + 1, s, temp + c, result);
c = Character.toUpperCase(c);
backtrack(start + 1, s, temp + c, result);
}
}
Please find here the code snippet for the above :
public class StringPerm {
public static void main(String[] args) {
String str = "abc";
String[] f = permute(str);
for (int x = 0; x < f.length; x++) {
System.out.println(f[x]);
}
}
public static String[] permute(String str) {
String low = str.toLowerCase();
String up = str.toUpperCase();
char[] l = low.toCharArray();
char u[] = up.toCharArray();
String[] f = new String[10];
f[0] = low;
f[1] = up;
int k = 2;
char[] temp = new char[low.length()];
for (int i = 0; i < l.length; i++)
{
temp[i] = l[i];
for (int j = 0; j < u.length; j++)
{
if (i != j) {
temp[j] = u[j];
}
}
f[k] = new String(temp);
k++;
}
for (int i = 0; i < u.length; i++)
{
temp[i] = u[i];
for (int j = 0; j < l.length; j++)
{
if (i != j) {
temp[j] = l[j];
}
}
f[k] = new String(temp);
k++;
}
return f;
}
}
You can do something like
```
import java.util.*;
public class MyClass {
public static void main(String args[]) {
String n=(args[0]);
HashSet<String>rs = new HashSet();
helper(rs,n,0,n.length()-1);
System.out.println(rs);
}
public static void helper(HashSet<String>rs,String res , int l, int n)
{
if(l>n)
return;
for(int i=l;i<=n;i++)
{
res=swap(res,i);
rs.add(res);
helper(rs,res,l+1,n);
res=swap(res,i);
}
}
public static String swap(String st,int i)
{
char c = st.charAt(i);
char ch[]=st.toCharArray();
if(Character.isUpperCase(c))
{
c=Character.toLowerCase(c);
}
else if(Character.isLowerCase(c))
{
c=Character.toUpperCase(c);
}
ch[i]=c;
return new String(ch);
}
}
```

Mix two strings in Java

I was wondering if it possible to mix two strings in java.
Suppose I have
11111
and
22222
What would be the best way to combine them to form?
1212121212
Assuming both strings are of equal length, you could simply write a loop to go over the characters and do what you want:
String s1, s2; /* input strings */
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s1.length(); i++) {
sb.append(s1.charAt(i));
sb.append(s2.charAt(i));
}
String result = sb.toString();
Here's an implementation that preserves the remainder of unequal length strings:
public static String mix(String a, String b) {
final int aLength = a.length();
final int bLength = b.length();
final int min = Math.min(aLength, bLength);
final StringBuilder sb = new StringBuilder(aLength + bLength);
for(int i = 0; i < min; i++) {
sb.append(a.charAt(i));
sb.append(b.charAt(i));
}
if (aLength > bLength) {
sb.append(a, bLength, aLength);
} else if (aLength < bLength) {
sb.append(b, aLength, bLength);
}
return sb.toString();
}
Yes - iterate the first string, and for each char in it, append to a builder the char in the same position from the second string (if it exists):
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str1.length(); i++) {
sb.append(str1.charAt(i));
if (str.length() > i) {
sb.append(str2.charAt(i));
}
}
return sb.toString();
I wonder if the example given is intentional, i.e they all have 1 char repeated. In that case it is much simpler. If they are not, then other answers are good.

Categories

Resources