繁体   English   中英

文字旋转排列

[英]Text spinning permutations

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

我的文字:

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

结果应为6(3x2)

我想对不限数量的嵌套单词进行排列。

我怎样才能做到这一点? 我尝试将文本平展为{abc|cde|fgh} {cde|fg} ,然后执行3x2 ,但是我如何才能对此文本展平,对此我有问题,有人可以帮助我吗?

我想用php或javascript做到这一点。

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

递归方法

递归方法采用字符串,并返回将其置换的方式的数目。

基本案例

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

因为它不嵌套在任何括号中,所以它不太了解那个倒数第二个管道符号的嵌套位置。

因此,您应该对字符串进行初始扫描,然后根据“ |”将其分成子字符串 不在括号内的符号,然后将这些子字符串的小计加在一起。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM