文字旋转排列

时间:2012-07-25 05:12:32

标签: php javascript spinner permutation spinning

我想获得旋转文本的排列数量:

我的文字:

{abc|{cde|fgh}} aaa {cde|fg}.

结果应 6(3x2)

我希望获得无限数量嵌套单词的排列。

我该怎么做?我试图将文字展平到{abc|cde|fgh} {cde|fg},然后只做 3x2 ,但我如何解决这个问题,我对此有疑问,有人可以帮助我吗?

我想在php或javascript中执行此操作。

1 个答案:

答案 0 :(得分:1)

首先想到的解决方案是创建一个递归方法。

递归方法

递归方法接受一个字符串,并返回置换它的方法的数量。

基本案例

基本情况:如果字符串中没有“{”和“}”,则返回“|”的数字字符串中的符号加1。

,否则

找到第一个'{'的位置,称之为Pos1。

找到它对应的'}',称之为Pos2。

现在形成3个子串[0到Pos1),(Pos1到Pos2),(Pos2到End)

小心识别Pos1和Pos2不包含在子串中,因此我们丢失了两个括号。

返回产品/每个子串的递归总和。

这是演示上述算法的C#代码:

static void Main(string[] args)
{

    string test1 ="{abc|{cde|fgh}} aaa {cde|fg}.";

    int numWays = getNumWaysRecursive(test1);

    Console.WriteLine("NumWays: " + numWays);
    Console.ReadLine();
}

private static int getNumWaysRecursive( string s )
{
    if (s == null) return 1;
    if (s == "") return 1;

    int firstBracePos = s.IndexOf('{');

    if (firstBracePos == -1) //Base case, no braces.
    {
        int pipeCount = 0;

        for (int i = 1; i < s.Length - 1; i++)
        {
            if (s[i] == '|')
            {
                if (pipeCount == -1)
                {
                    pipeCount = 0;
                }
                pipeCount++;
            }
        }

        return pipeCount + 1;
    }

    //Non-Base case:
    // find the first Left Brace
    // find the right brace it corresponds with

    int numOfNests = 0;
    int pos = firstBracePos + 1;

    while (pos < s.Length)
    {
        if (s[pos] == '}')
        {
            numOfNests--;
            if (numOfNests == -1)
            {
                break;
            }
        }

        else if (s[pos] == '{')
        {
            numOfNests++;
        }

        pos++;
    }

    //Get rid of those braces, and recurse on the three parts:
    // 1. the part before the braces.
    // 2. the part between the braces.
    // 3. the part after the braces.

    string firstPart; 
    if (firstBracePos == 0)
    {
        firstPart = "";
    }
    else
    {
        firstPart = s.Substring(0, firstBracePos);
    }

    string secondPart = s.Substring(firstBracePos + 1, pos - firstBracePos - 1);
    string lastPart = s.Substring(pos + 1 );

    int sum1 = getNumWaysRecursive(firstPart); 
    int sum2 = getNumWaysRecursive(secondPart);
    int sum3 = getNumWaysRecursive(lastPart);

    bool strng1HasPipes = (firstPart.IndexOf('|') != -1);

    int sum = 1;

    if ( strng1HasPipes )
    {
        sum += sum1 - 1;
        sum += sum2;
    }
    else
    {
        sum *= sum2;
    }

    if (sum3 == 0)
    {
        ;
    }
    else
    {
        sum *= sum3;
    }

    return sum;
}

不幸的是,这并没有完全掌握整个情况。

它在“{abc | {cde | fgh}} aaa {cde | fg} eee | {abc | bbb}等字符串上失败。”

因为它并不完全理解倒数第二个管道符号的嵌套位置,因为它没有嵌套在任何大括号内。

所以你应该对字符串进行初始扫描并将其分解为基于'|'的子字符串不在大括号内的符号,然后将这些子串的小计添加在一起。