C# 他对内存分配进行了中介,包括字符串连接,并最终得到了更通用、更快的解决方案
为了做到这一点,我需要做出一些艰难的设计决定。我所说的一般函数的签名如下所示C# 他对内存分配进行了中介,包括字符串连接,并最终得到了更通用、更快的解决方案,c#,regex,algorithm,out-of-memory,C#,Regex,Algorithm,Out Of Memory,为了做到这一点,我需要做出一些艰难的设计决定。我所说的一般函数的签名如下所示 public static IEnumerable<T[]> RepeatingPermutations<T>(this T[] set, int N) 有趣的是,我最近回答了一个有关组合的问题,并意识到算法基本相同 话虽如此,功能如下: public static IEnumerable<T[]> RepeatingPermutations<T>(this T[] s
public static IEnumerable<T[]> RepeatingPermutations<T>(this T[] set, int N)
有趣的是,我最近回答了一个有关组合的问题,并意识到算法基本相同
话虽如此,功能如下:
public static IEnumerable<T[]> RepeatingPermutations<T>(this T[] set, int N)
{
var result = new T[N];
var indices = new int[N];
for (int pos = 0, index = 0; ;)
{
for (; pos < N; pos++, index = 0)
{
indices[pos] = index;
result[pos] = set[index];
}
yield return result;
do
{
if (pos == 0) yield break;
index = indices[--pos] + 1;
}
while (index >= set.Length);
}
}
在哪里
A-来自@juharr的LINQ函数B1-带字符串的my函数
B2-带char[]的my函数 正如我们所看到的,在内存方面,这两个字符串函数是可比较的。在性能方面,LINQ函数只慢了约2倍,这是一个非常好的结果 正如在这种情况下所预期的那样,非分配函数的性能明显优于两者 更新:根据评论中的要求,以下是上述函数的示例用法(请注意,它们是扩展方法,必须放在您选择的静态类中): 但是,请记住我所做的设计选择,因此如果在调试器中展开
charPermutations
,您将看到一个相同的值(最后一个排列)。使用上面调用char[]
的整个结果应该是这样的
public static IEnumerable<string> RepeatingPermutations(this string set, int N)
{
return set.ToCharArray().RepeatingPermutations(N).Select(p => new string(p));
}
from e1 in set
from e2 in set
...
from eN in set
select new [] { e1, e2, .., eN }
var charPermutationList = charSet.RepeatingPermutations(3)
.Select(p => (char[])p.Clone()).ToList();
实际上,除了上述两种方法之外,还有一种很好的扩展方法:
public static IEnumerable<T[]> Clone<T>(this IEnumerable<T[]> source)
{
return source.Select(item => (T[])item.Clone());
}
等待您正在尝试对字母表中的所有字母进行排列?假设每个排列的长度为6。。。这是165765600个不同的对象。(在计算器中键入
26P6
)。对于长度为5的排列,这是7893600(在计算器中键入26P5
)。是的,这正是我目前正在做的。我知道字母表中所有字母的6个字母排列会变得非常庞大,所以我正在尝试找出最聪明的方法。如果你将代码改为使用IEnumerable而不是列表,那么就不需要同时在内存中进行所有排列,你可能想查看Eric Lippert的博客帖子。是的,当时我可以用正则表达式过滤它们,但是使用q.SelectMany(x=>source,(x,y)=>x+y)代码>是我知道如何生成置换的唯一方法。你能帮我想一想如何做到这一点吗?@Shard我才11年级,而且我绝对不是什么超级酷的数学人,所以我不确定我能帮上什么忙。很抱歉:(这也适用于字母吗?你能解释一下你的代码吗?特别是getPermutation方法。是的,这将为任何输入字符串生成置换。我只是在这里使用了一个数字字符串作为示例。我正在更新代码,并提供更多解释。谢谢!因为我修改了代码,以使用我使用al的示例。)phabet,但我似乎无法让它工作。我的字符串输入是一个字母表,然后我告诉我的代码生成例如3个字母的单词,它创建例如aaa、aab、aac…等等。所以在每个步骤中都使用整个字母表。我在我的帖子中添加了一张图片,以演示我想要的更好。使用您编辑的代码,这是否意味着例如aaab
不可能?回答很好。特别是在算法和性能分析部分。;)+1您还可以添加一个如何调用char[]函数的示例吗?@Ian很高兴见到您:)谢谢!从过去的好时光开始,数据结构、算法和性能一直是我最喜欢的领域:)@IvanStoev哈哈。。。这里也是……)祝贺你获得了赏金!;)@伊恩·洛尔。是的,我开始学习是因为我对学习更多感兴趣。毕竟我在11年级:)
public IEnumerable<string> getPermutation(string input, string regexp)
{
Stack<string> left = new Stack<string>();
Stack<string> acc = new Stack<string>();
left.Push(input);
acc.Push("");
// generate all permutations that match regexp
while (left.Count > 0)
{
string c = left.Pop();
string r = acc.Pop();
if(r.Length==input.Length)
{
yield return r;
}
else
{
for(int i=0;i<c.Length;i++)
{
string p = r + c[i];
if (Regex.IsMatch(p,regexp)) // continue if we have a potential match
{
left.Push(c.Substring(0, i) + c.Substring(i + 1));
acc.Push(p);
}
}
}
}
}
foreach(var a in getPermutation("123456789", "^3$|^32$|^321"))
{
if(Regex.IsMatch(a, "32145.67"))
{
// found match
}
}
public static IEnumerable<T[]> RepeatingPermutations<T>(this T[] set, int N)
public static IEnumerable<string> RepeatingPermutations(this string set, int N)
{
return set.ToCharArray().RepeatingPermutations(N).Select(p => new string(p));
}
from e1 in set
from e2 in set
...
from eN in set
select new [] { e1, e2, .., eN }
public static IEnumerable<T[]> RepeatingPermutations<T>(this T[] set, int N)
{
var result = new T[N];
var indices = new int[N];
for (int pos = 0, index = 0; ;)
{
for (; pos < N; pos++, index = 0)
{
indices[pos] = index;
result[pos] = set[index];
}
yield return result;
do
{
if (pos == 0) yield break;
index = indices[--pos] + 1;
}
while (index >= set.Length);
}
}
A : N=2 Count= 676 Time=00:00:00.0000467 Memory= 29K
B1: N=2 Count= 676 Time=00:00:00.0000263 Memory= 16K
B2: N=2 Count= 676 Time=00:00:00.0000189 Memory= 8K
A : N=3 Count= 17,576 Time=00:00:00.0010107 Memory= 657K
B1: N=3 Count= 17,576 Time=00:00:00.0003673 Memory= 344K
B2: N=3 Count= 17,576 Time=00:00:00.0001415 Memory= 8K
A : N=4 Count= 456,976 Time=00:00:00.0184445 Memory= 2,472K
B1: N=4 Count= 456,976 Time=00:00:00.0096189 Memory= 2,520K
B2: N=4 Count= 456,976 Time=00:00:00.0033624 Memory= 8K
A : N=5 Count= 11,881,376 Time=00:00:00.4281349 Memory= 397K
B1: N=5 Count= 11,881,376 Time=00:00:00.2482835 Memory= 4,042K
B2: N=5 Count= 11,881,376 Time=00:00:00.0887759 Memory= 8K
A : N=6 Count= 308,915,776 Time=00:00:11.2697326 Memory= 1,688K
B1: N=6 Count= 308,915,776 Time=00:00:06.5638404 Memory= 1,024K
B2: N=6 Count= 308,915,776 Time=00:00:02.2674431 Memory= 8K
var charSet = Enumerable.Range('A', 'Z' - 'A' + 1).Select(c => (char)c).ToArray();
var charPermutations = charSet.RepeatingPermutations(3);
var stringSet = new string(charset);
var stringPermutations = stringSet.RepeatingPermutations(3);
var charPermutationList = charSet.RepeatingPermutations(3)
.Select(p => (char[])p.Clone()).ToList();
public static IEnumerable<T[]> Clone<T>(this IEnumerable<T[]> source)
{
return source.Select(item => (T[])item.Clone());
}
var charPermutationList = charSet.RepeatingPermutations(3).Clone().ToList();