【问题标题】:Text spinning permutations文本旋转排列
【发布时间】:2012-07-25 05:12:32
【问题描述】:

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

我的文字:

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

结果应该是 6 (3x2)

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

我该怎么做?我尝试将文本平展为 {abc|cde|fgh} {cde|fg},然后只执行 3x2,但我如何才能平展此文字,我对此有疑问,谁能帮助我?

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

【问题讨论】:

标签: php javascript spinner permutation spinning


【解决方案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 }”之类的字符串上失败。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 2021-05-11
    • 2013-05-18
    • 2012-06-13
    相关资源
    最近更新 更多