English 中文(简体)
生成所有字体
原标题:Algorithm to generate all variants of a word

我谨以以下例子解释我的问题。

assume the word: abc a has variants: ä, à
b has no variants.
c has variants: ç

可能的话是:

abc
äbc
àbc
abç
äbç
àbç

现在,我正在研究一种算法,该算法将所有字数的字数与字母字数混在一起。

最佳回答

我建议你重新解决这一问题。 这里,你们开始用 Java法:

static Map<Character, char[]> variants = new HashMap<Character, char[]>() {{
    put( a , new char[] { ä ,  à });
    put( b , new char[] {        });
    put( c , new char[] {  ç     });
}}; 

public static Set<String> variation(String str) {

    Set<String> result = new HashSet<String>();

    if (str.isEmpty()) {
        result.add("");
        return result;
    }

    char c = str.charAt(0);
    for (String tailVariant : variation(str.substring(1))) {
        result.add(c + tailVariant);
        for (char variant : variants.get(c))
            result.add(variant + tailVariant);
    }

    return result;
}

测试:

public static void main(String[] args) {
    for (String str : variation("abc"))
        System.out.println(str);
}

<<>Output>:

abc
àbç
äbc
àbc
äbç
abç
问题回答

快速破灭的沙丘解决办法:

def word_variants(variants):
  print_variants("", 1, variants);

def print_variants(word, i, variants):
  if i > len(variants):
    print word
  else:
    for variant in variants[i]:
      print_variants(word + variant, i + 1, variants)

variants = dict()
variants[1] = [ a0 ,  a1 ,  a2 ]
variants[2] = [ b0 ]
variants[3] = [ c0 ,  c1 ]

word_variants(variants)

共同部分:

string[] letterEquiv = { "aäà", "b", "cç", "d", "eèé" };

// Here we make a dictionary where the key is the "base" letter and the value is an array of alternatives
var lookup = letterEquiv
    .Select(p => p.ToCharArray())
    .SelectMany(p => p, (p, q) => new { key = q, values = p }).ToDictionary(p => p.key, p => p.values);

A recursive variation written in C#.

List<string> resultsRecursive = new List<string>();

// I m using an anonymous method that "closes" around resultsRecursive and lookup. You could make it a standard method that accepts as a parameter the two.
// Recursive anonymous methods must be declared in this way in C#. Nothing to see.
Action<string, int, char[]> recursive = null;
recursive = (str, ix, str2) =>
{
    // In the first loop str2 is null, so we create the place where the string will be built.
    if (str2 == null)
    {
        str2 = new char[str.Length];
    }

    // The possible variations for the current character 
    var equivs = lookup[str[ix]];

    // For each variation
    foreach (var eq in equivs)
    {
        // We save the current variation for the current character
        str2[ix] = eq;

        // If we haven t reached the end of the string
        if (ix < str.Length - 1)
        {
            // We recurse, increasing the index
            recursive(str, ix + 1, str2);
        }
        else
        {
            // We save the string
            resultsRecursive.Add(new string(str2));
        }
    }
};

// We launch our function
recursive("abcdeabcde", 0, null);

// The results are in resultsRecursive

A non-recursive version

List<string> resultsNonRecursive = new List<string>();

// I m using an anonymous method that "closes" around resultsNonRecursive and lookup. You could make it a standard method that accepts as a parameter the two.
Action<string> nonRecursive = (str) =>
{
    // We will have two arrays, of the same length of the string. One will contain
    // the possible variations for that letter, the other will contain the "current"
    // "chosen" variation of that letter
    char[][] equivs = new char[str.Length][];
    int[] ixes = new int[str.Length];

    for (int i = 0; i < ixes.Length; i++)
    {
        // We start with index -1 so that the first increase will bring it to 0
        equivs[i] = lookup[str[i]];
        ixes[i] = -1;
    }

    // The current "workin" index of the original string
    int ix = 0;

    // The place where the string will be built.
    char[] str2 = new char[str.Length];

    // The loop will break when we will have to increment the letter with index -1
    while (ix >= 0)
    {
        // We select the next possible variation for the current character
        ixes[ix]++;

        // If we have exausted the possible variations of the current character
        if (ixes[ix] == equivs[ix].Length)
        {
            // Reset the current character to -1
            ixes[ix] = -1;

            // And loop back to the previous character
            ix--;

            continue;
        }

        // We save the current variation for the current character
        str2[ix] = equivs[ix][ixes[ix]];

        // If we are setting the last character of the string, then the string
        // is complete
        if (ix == str.Length - 1)
        {
            // And we save it
            resultsNonRecursive.Add(new string(str2));
        }
        else
        {
            // Otherwise we have to do everything for the next character 
            ix++;
        }
    }
};

// We launch our function
nonRecursive("abcdeabcde");

// The results are in resultsNonRecursive

两者都作了大量评论。





相关问题
How to add/merge several Big O s into one

If I have an algorithm which is comprised of (let s say) three sub-algorithms, all with different O() characteristics, e.g.: algorithm A: O(n) algorithm B: O(log(n)) algorithm C: O(n log(n)) How do ...

Grokking Timsort

There s a (relatively) new sort on the block called Timsort. It s been used as Python s list.sort, and is now going to be the new Array.sort in Java 7. There s some documentation and a tiny Wikipedia ...

Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Enumerating All Minimal Directed Cycles Of A Directed Graph

I have a directed graph and my problem is to enumerate all the minimal (cycles that cannot be constructed as the union of other cycles) directed cycles of this graph. This is different from what the ...

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签