Unique String Combinations

Unique string combinations

One option is to run the combn function in a lapply loop. You can define it as your own function

allCombs <- function(x) c(x, lapply(seq_along(x)[-1L], 
function(y) combn(x, y, paste0, collapse = "")),
recursive = TRUE)

allCombs(colors)
## [1] "Yellow" "Blue" "Red" "YellowBlue" "YellowRed" "BlueRed" "YellowBlueRed"

Explanation (per request)

Basically OP wants a vector of all possible combinations (not permutations) depending on the length of the input vector. Thus, we should run the combn function over k <- 1:length(x) and generate all combinations for every k.
So when k == 1, it's just the original vector, so we can skip that part and just concatenate the original vector using c. The rest of the generated combinations return a list of vectors with different lengths (in a descending order for obvious reasons), thus we need to use recursive = TRUE within the c function in order to mimic the behaviour of unlist and combine the results into a single vector.

Unique string combinations of consecutive integers

Here is a nested sapply approach

unlist(
sapply(
seq_along(vec),
function(k) {
sapply(
k:length(vec),
function(l) paste0(vec[k:l], collapse = "")
)
}
)
)

which produces

 [1] "0"          "01"         "012"        "0123"       "01234"     
[6] "012345" "0123456" "01234567" "012345678" "0123456789"
[11] "1" "12" "123" "1234" "12345"
[16] "123456" "1234567" "12345678" "123456789" "2"
[21] "23" "234" "2345" "23456" "234567"
[26] "2345678" "23456789" "3" "34" "345"
[31] "3456" "34567" "345678" "3456789" "4"
[36] "45" "456" "4567" "45678" "456789"
[41] "5" "56" "567" "5678" "56789"
[46] "6" "67" "678" "6789" "7"
[51] "78" "789" "8" "89" "9"

Another option is sapply + embed

unlist(
sapply(
seq_along(vec),
function(k) {
do.call(paste0, rev(data.frame(embed(vec, k))))
}
)
)

which gives

 [1] "0"          "1"          "2"          "3"          "4"
[6] "5" "6" "7" "8" "9"
[11] "01" "12" "23" "34" "45"
[16] "56" "67" "78" "89" "012"
[21] "123" "234" "345" "456" "567"
[26] "678" "789" "0123" "1234" "2345"
[31] "3456" "4567" "5678" "6789" "01234"
[36] "12345" "23456" "34567" "45678" "56789"
[41] "012345" "123456" "234567" "345678" "456789"
[46] "0123456" "1234567" "2345678" "3456789" "01234567"
[51] "12345678" "23456789" "012345678" "123456789" "0123456789"

Shortest unique combination of at least three characters for each string in list

You could do something like this:

import heapq

from collections import Counter
from operator import itemgetter

def combination(word, n, counts):
word_count = Counter(word)
elements = []
seen = set()
for i, c in enumerate(word[1:]):
if c not in seen:
elements.append((-1 * counts[c], word_count[c], i, c))
seen.add(c)
top = heapq.nlargest(n, elements)
characters = map(itemgetter(3), top)

return word[0] + ''.join(sorted(characters, key=lambda x: word.index(x)))

lst = ["apple", "pear", "banana", "xylophone", "bear", "banunu"]

counts = Counter(''.join(lst))

result = [combination(w, 2, counts) for w in lst]
print(result)

Output

['apl', 'per', 'ban', 'xyh', 'ber', 'bnu']

The idea is to create a tuple of the priority criterias representing each unique letter. So elements is a list containing tuples represeting:

  1. counts[c]: The overall count (as you want the rarest multiply by -1)
  2. word_count[c]: The specific count of the letter in the word
  3. i: represents the firs position of the letter
  4. c: the letter itself.

Once you create the list elements with:

elements = []
seen = set()
for i, c in enumerate(word[1:]):
if c not in seen:
elements.append((-1 * counts[c], word_count[c], i, c))
seen.add(c)

Note that as the characters must be unique we use a set (seen) to guarantee uniqueness. Finally you use heapq.nlargest to get the top n elements according to the above criterias.

Get all unique combinations from two strings c#

Let's split the initial task into smaller ones:

All 2 character fragments from given string:

private static IEnumerable<string> SubStrings(string value, int length = 2) {
if (string.IsNullOrEmpty(value))
yield break;
else if (length <= 0)
yield break;

for (int i = 0; i < value.Length; ++i) {
StringBuilder sb = new StringBuilder(length);

for (int j = 0; j < length; ++j)
// modulo arithmetics to restart from the beginning e.g. "FOUR" -> "RF"
sb.Append(value[(i + j) % value.Length]);

yield return sb.ToString();
}
}

Now we want a cartesian join of SubStrings(string1) and SubStrings(string2) which we can implement with a help of SelectMany:

 SubStrings(string1)
.SelectMany(left => SubStrings(string2).Select(right => left + rigth));

Finally, let's add Distinct:

 using System.Linq;

...

string string1 = "FOUR";
string string2 = "FIVE";

var result = SubStrings(string1)
.SelectMany(left => SubStrings(string2).Select(right => left + right))
.Distinct();

Console.Write(string.Join(Environment.NewLine, result));

Outcome

FOFI
FOIV
FOVE
FOEF
OUFI
OUIV
OUVE
OUEF
URFI
URIV
URVE
UREF
RFFI
RFIV
RFVE
RFEF

For "OK" and "OK" we have

OKOK
OKKO
KOOK
KOKO

Edit: Linq (SelectMany, Distinct) is very convenient when we query data. If you want, however, to get rid of it you have to put something like this:

// For Distinct, since HashSet contains unique values only
HashSet<string> result = new HashSet<string>();

foreach (string left in SubStrings(string1))
foreach (string right in SubStrings(string2))
result.Add(left + right);

Console.Write(string.Join(Environment.NewLine, result));

Verify there is a combination of unique string

You can hash values by a separator like #, and then find that all uniques or not. Hash value for a Details is name + "#" + "email in the first case, and is name + "#" + age + "#" + email + "#" + location in the second case.
You can using Hashmap to find duplicates if there is any with the specified key (or hash) for each instance of Details.

Finding unique combinations of two strings in python

Just use zip and set to combine the two lists of strings and get unique combinations. I used a list comprehension to return combined strings:

>>> unique = [''.join(x)  for x in set(list(zip(StringA, StringB)))]
>>> unique
['TG', 'GT', 'KT', 'TK', 'KK']

Alternatively, if you simply want them in a set you can remove the list comprehension:

>>> unique = set(zip(StringA, StringB))
>>> unique
{('T', 'K'), ('T', 'G'), ('K', 'K'), ('K', 'T'), ('G', 'T')}

Javascript - Get all unique permutations of a string (special case)

Here is a recursive generator that yields the combinations:

function permutations(query) {

function* iterRecur(sliced) {
if (sliced.length == 1) return yield sliced;
for (const result of iterRecur(sliced.slice(1))) {
yield [sliced[0] + "-" + result[0], ...result.slice(1)];
yield [sliced[0], ...result];
}
}

const sliced = query.split(/ +/g);
return [...iterRecur(sliced)];
}

console.log(permutations("this is a test"));

How to generate unique string from number which lies in range of quantity of characters ' permutations in this string?

You could treat the number as a base 62 number, and fill in the string "digits" (base-62 bits) accordingly.

Let's see how we do this with the decimal number 1234 in different bases. note that division below is always integer division (fractional parts are chopped off).

Base 10 (decimal): 0-9

1234 / 10^3 = 1, 1234 mod 10^3 = 234
234 / 10^2 = 2, 234 mod 10^2 = 34
34 / 10^1 = 3, 34 mod 10^1 = 4
4 / 10^0 = 4, 4 mod 10^0 = 0
Thus we represent this number in base-10 as "1234"

Base 16 (hexadecimal): 0-9,a-f (where a=10, b=11, ...)

1234 / 16^2 = 4, 1234 mod 16^2 = 210
210 / 16^1 = d, 210 mod 16^1 = 2
2 / 16^0 = 2, 2 mod 16^0 = 0
Thus we represent this number in base-16 as "4d2"

This could extend to any base, including base-62: 0-9,a-z,A-Z

1234 / 62^1 = j, 1234 mod 62^1 = 56
56 / 62^0 = U, 56 mod 62^0 = 0
Thus we represent this number in base-62 as "jU"

I didn't bother doing leading 0's, but you could see that 1234 / 62^2 = 0, and 1234 mod 62^2 = 1234, so in base-62 you can have "000000jU".


Note that you could only do this for numbers in the range [0, 218340105584896), so it wouldn't be possible to represent 218340105584896.



Related Topics



Leave a reply



Submit