【问题标题】:Finding all possible permutations of the characters in a set of strings using recursion使用递归查找一组字符串中所有可能的字符排列
【发布时间】:2016-04-06 07:49:10
【问题描述】:

我有这组(希腊)字符串:

ἸἼΙἹἽ, ῇηἤήῃὴῆἡἠἢᾖἥἣῄἦᾗᾐἧᾔᾑ, σ , οὸόὀὄὅὂ, ὺὖυῦύὐὑὔΰϋὕὗὓὒῢ

我想找出这 5 个字符串中所有可能的字符排列。例如,Ἰῇσοὺ、Ἰῇσοὖ、Ἰῇσου等。我知道它应该涉及递归,因为字符串的数量不固定,但我是初学者,我完全被递归吓傻了。

我在 Python 中执行了以下操作,它确实为我提供了每个字符串中字符的所有组合。但我需要'ἸἼΙἹἽ'始终排在第一位,'ῇηἤήῃὴῆἡἠἢᾖἥἣῄἦᾗᾐἧᾔᾑ'第二,'σς'第三,等等。

# -*- coding: utf-8 -*-

def Gen( wd, pos, chars ):
    if pos < len( chars ):
        for c in chars:
            for l in c:
                Gen( wd + l, pos + 1, chars )
    else:
        print wd

chars = [ u'ἸἼΙἹἽ', u'ῇηἤήῃὴῆἡἠἢᾖἥἣῄἦᾗᾐἧᾔᾑ', u'σς', u'οὸόὀὄὅὂ', u'ὺὖυῦύὐὑὔΰϋὕὗὓὒῢ' ]

Gen( "", 0, chars )

感谢大家的帮助。我的头脑完全被炸毁了。递归!以下是我最终在 Python 中所做的事情:

# -*- coding: utf-8 -*-

s = [ u'ἸἼΙἹἽ', u'ῇηἤήῃὴῆἡἠἢᾖἥἣῄἦᾗᾐἧᾔᾑ', u'σς', u'οὸόὀὄὅὂ', u'ὺὖυῦύὐὑὔΰϋὕὗὓὒῢ' ]

results = []

def recur( wd, strings ):
    index = 0
    if index < len( strings ):
        for c in strings[ index ]:
            recur( wd + c, strings[ index + 1: ] )
    else:
        results.append( wd )

def main():
    recur( '', s )
    for r in results:
        print r.encode( 'utf-8' )

main()

【问题讨论】:

  • 用笔和纸算出算法。
  • Ἰῇσοὺ, Ἰῇσοὖ, Ἰῇσου, ... 对于每个 u,然后每个 o 对于每个 u。然后每个 o 和 u 的每个 sigma ......等等。但我不知道如何使用递归进行编码。
  • 你永远必须使用递归。您可以从所有唯一字符的数组开始使用 for/while 循环。
  • 是的,但字符串的数量不固定。在这种情况下,我有 5 个字符串,但通常用户将确定字符串的数量......以及每个字符串的内容。

标签: recursion permutation


【解决方案1】:

您创建一个 char 数组,其中包含您要使用的字符串 char str[] = "ABC";

然后你得到字符串 int n = strlen(str); 的长度,最后你排列。

您创建了一个新函数,该函数将包含输入字符串、字符串的起始索引和字符串的结束索引。 检查起始索引 (int s) 是否等于结束索引 (int e) 如果是,这意味着你已经完成了,如果不是,你进入一个循环,你从 start (s) 到 end (e),交换值,递归,再次交换到回溯。

C++ 中的一个例子:

#include <stdio.h>
#include <string.h>

void swap(char *i, char *j)
{
    char temp;
    temp = *i;
    *i = *j;
    *j = temp;
}

void permutate(char *str, int start, int end)
{
    int i;
    if (start == end)
        printf("%s\n", str);
    else
    {
        for (i = start; i <= end; i++)
        {
            swap((str + start), (str + i));
            permutate(str, start + 1, end);
            swap((str + start), (str + i)); //backtrack
        }
    }
}

int main()
{
    char str[] = "ABC";
    int n = strlen(str);
    permutate(str, 0, n - 1);
    return 0;
}

我对 Python 不是很熟悉,但我发现了一些对您的情况可能有所帮助的东西:

def comb(first_str, second_str):
if not first_str:
    yield second_str
    return
if not second_str:
    yield first_str
    return

for result in comb(first_str[1:], second_str):
    yield first_str[0] + result
for result in comb(first_str, second_str[1:]):
    yield second_str[0] + result

>>> for result in comb("ἸἼΙἹἽ", "ῇηἤήῃὴῆἡἠἢᾖἥἣῄἦᾗᾐἧᾔᾑ"):
print(result)

【讨论】:

    【解决方案2】:

    只需写下五个嵌套循环。在伪代码中,

    for a in "ἸἼΙἹἽ"
      for b in "ῇηἤήῃὴῆἡἠἢᾖἥἣῄἦᾗᾐἧᾔᾑ"
        for c in "σς"
          for d in "οὸόὀὄὅὂ"
            for e in "ὺὖυῦύὐὑὔΰϋὕὗὓὒῢ"
               emit [a,b,c,d,e]
    

    用递归对这五个循环进行编码,因此它适用于任意数量的输入字符串,同样是伪代码,

    g(list-of-strings) =
       | case list-of-strings
       | of  empty --> end-of-processing
       | of  (first-string AND rest-of-strings) --> 
                for each ch in first-string 
                   DO g(rest-of-strings)
    

    现在你只需要弄清楚在哪里保存每个当前first-string 的字符ch 以及如何在end-of-processing 处将它们全部组合起来(基本上,你的两个选项是全局累加器或参数到函数调用)。

    【讨论】:

      猜你喜欢
      • 2015-06-18
      • 2021-08-12
      • 2016-01-27
      • 2017-01-18
      • 2018-02-25
      • 2011-11-22
      • 2014-05-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多