0

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

我的文字:

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

结果应为6 (3x2)

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

我怎样才能做到这一点?我试图将文本扁平化{abc|cde|fgh} {cde|fg},然后只做3x2,但是我如何扁平化这个文本,我有这个问题,有人可以帮助我吗?

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

4

1 回答 1

0

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

递归方法

递归方法接受一个字符串,并返回排列它的方式数。

基本情况

基本情况:如果字符串中没有'{'和'}',则返回'|'的个数 字符串中的符号加 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 }”之类的字符串上失败。

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

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

于 2012-07-25T05:30:52.707 回答