我有一个旋转的文字:{T1 {M1 | {A1 | B1} | M2} F1 | {X1 | X2}}
我的问题是:如何在C#中找到所有排列? T1M1F1 T1M2F1 T1A1F1 T1B1F1 X1 X2
有什么建议吗?
编辑: 谢谢你的帮助,但M1,A1,..是例子
用可能给出的词语: {我的名字是詹姆斯维克,我是这个{论坛|网站|网站}的{会员|用户|访客},我很喜欢我是管理员,我是这个{论坛|网站|网站}的{主管|管理员|主持人},我很喜欢它。
我的名字是詹姆斯·维克,我是这个{论坛|网站|网站}的{会员|用户|访客},我喜欢它 => 3 * 3 => 9种排列
我是管理员,我是这个{论坛|网站|网站}的{主管|管理员|主持人},我很喜欢 => 3 * 3 => 9种排列
结果:18种排列
答案 0 :(得分:1)
生成可旋转字符串的所有permuatuons的方法
我已经实现了一个简单的方法来解决这个问题。 它需要一个包含可纺文本字符串的ArrayList参数。 我用它来生成多个可旋转字符串的所有排列。
它附带了支持可选块的额外功能,其中包含“[]”括号。
等式.: 如果ArrayList中有一个字符串对象,其内容为: {A | {B1 | B2} [B可选]}
它用所有排列填充数组列表,“提取” 调用方法后的内容: 一个 B1 B1 B可选 B2 B2 B可选
您还可以传递多个字符串作为参数,以便为所有字符串生成排列: 例如。: 输入: ArraList有两个字符串 {A1 | A2} {B1 | B2} 调用后的内容: A1 A2 B1 B2
此实现的工作原理是始终在第一个可旋转部分中找到最内部的括号对,然后将其提取出来。我这样做,直到删除所有特殊的{},[]字符。
private void ExtractVersions(ArrayList list)
{
ArrayList IndicesToRemove = new ArrayList();
for (int i = 0; i < list.Count; i++)
{
string s = list[i].ToString();
int firstIndexOfCurlyClosing = s.IndexOf('}');
int firstIndexOfBracketClosing = s.IndexOf(']');
if ((firstIndexOfCurlyClosing > -1) || (firstIndexOfBracketClosing > -1))
{
char type = ' ';
int endi = -1;
int starti = -1;
if ((firstIndexOfBracketClosing == -1) && (firstIndexOfCurlyClosing > -1))
{ // Only Curly
endi = firstIndexOfCurlyClosing;
type = '{';
}
else
{
if ((firstIndexOfBracketClosing > -1) && (firstIndexOfCurlyClosing == -1))
{ // Only bracket
endi = firstIndexOfBracketClosing;
type = '[';
}
else
{
// Both
endi = Math.Min(firstIndexOfBracketClosing, firstIndexOfCurlyClosing);
type = s[endi];
if (type == ']')
{
type = '[';
}
else
{
type = '{';
}
}
}
starti = s.Substring(0, endi).LastIndexOf(type);
if (starti == -1)
{
throw new Exception("Brackets are not valid.");
}
// start index, end index and type found. -> make changes
if (type == '[')
{
// Add two new lines, one with the optional part, one without it
list.Add(s.Remove(starti, endi - starti+1));
list.Add(s.Remove(starti, 1).Remove(endi-1, 1));
IndicesToRemove.Add(i);
}
else
if (type == '{')
{
// Add as many new lines as many alternatives there are. This must be an in most bracket.
string alternatives = s.Substring(starti + 1, endi - starti - 1);
foreach(string alt in alternatives.Split('|'))
{
list.Add(s.Remove(starti,endi-starti+1).Insert(starti,alt));
}
IndicesToRemove.Add(i);
}
} // End of if( >-1 && >-1)
} // End of for loop
for (int i = IndicesToRemove.Count-1; i >= 0; i--)
{
list.RemoveAt((int)IndicesToRemove[i]);
}
}
我希望我能帮到你。 也许它不是最简单和最好的实现,但它适用于我。请反馈,投票!
答案 1 :(得分:0)
在我看来,你应该这样做:
所有嵌套的选择列表,即{}之间的“应该被展平”到单个选项列表。就像在你的例子中一样:
{M1 | {A1 | B1} | M2} - &gt; {M1 | A1 | B1 | M2}
使用递归生成所有可能的组合。例如,从空数组开始,首先放置T1,因为它是唯一的选项。然后从嵌套列表{M1 | A1 | B1 | M2}中选择每个元素依次将它放在下一个位置然后最终F1。重复,直到所有可能性都用尽。
这只是一个粗略的暗示,你需要填写其余的细节。