代码:
public char[] numbers = new char[] { '3', '4', '5' };
public char[] letters = new char[] { 'X', 'T', 'M', 'W', 'Y', 'L' };
//Generate a String with only 2 of the above letters and the rest filled
//with the numbers the characters shouldn't be always next to one another
我看了一些其他解决方案: var random = new Random();
for (int i=0; i<50; i++)
{
var result = new string(
Enumerable.Repeat(chars, 8)
.Select(s => s[random.Next(s.Length)])
.ToArray());
}
但它们只是生成随机字符串而不是来自较小的字符集,也不会限制字母数量与数字的数量。
示例: 的 有效
X333Y453
X3L45453
XL333333
4L333X333
333L45L3
无效
5533Y453
333L45453
XL33L333
只能有2个字符,因为总共有8个字符,所以应该有6个数字
答案 0 :(得分:2)
感觉有两组需要与特定规则合并:
近似代码:
IEnumerable<char> PickRandom(char[] source, int count)
{
return Enumerable.Repeat(1, count)
.Select(s => source[random.Next(source.Length)]);
}
var randomLetters = PickRandom(letters, 2);
var randomNumbers = PickRandom(numbers, 6);
int lettersGroup1 = random.Next(2);
int group1 = random.Next(6);
int group2 = random.Next(6 - group1);
var result = randomNumbers.Take(group1)
.Concat(randomLetters.Take(lettersGroup1))
.Concat(randomNumbers.Skip(group1).Take(group2))
.Concat(randomLetters.Skip(lettersGroup1))
.Concat(randomNumbers.Skip(group1 + group2));
var stringResult = String.Join("", result);
注意:LINQ中的代码是严格的练习,肯定有更多可读/有效的方法来构建字符串。
答案 1 :(得分:2)
只需几个辅助方法:
public static class CombinatoricsHelper {
private static readonly Random random = new Random();
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> enumerable) {
List<T> list = enumerable.ToList();
int position = list.Count;
while (position > 0) {
int selectedIndex = random.Next(position);
yield return list[selectedIndex];
position -= 1;
list[selectedIndex] = list[position];
}
}
public static IEnumerable<T> TakeRandom<T>(this IEnumerable<T> enumerable, int count) {
List<T> list = enumerable.ToList();
int remaining = count;
while (remaining > 0) {
yield return list[random.Next(list.Count)];
remaining -= 1;
}
}
}
你的阵列:
public char[] numbers = new char[] { '3', '4', '5' };
public char[] letters = new char[] { 'X', 'T', 'M', 'W', 'Y', 'L' };
这变得非常简单:
return new string(letters
.TakeRandom(2)
.Concat(numbers.TakeRandom(6))
.Shuffle()
.ToArray()
);
示例输出:
3X44334L 335W555Y LX443355 53T3Y333 W443W534 M5444W44 3553T33Y X4443W45 433M533Y 54L445M4 55X5W444 543443XX
尽管我的答案使用了比其他答案更多的代码,但我推荐它,因为感兴趣的实际算法部分(你如何创建字符串)与可以稍微掩饰的实现细节分开({ {1}}和Shuffle
)。也就是说,一旦有人理解TakeRandom
和Shuffle
做了什么,不仅可以重用它们,而且可以使代码的其余部分更加清晰。
作为证明我的断言的一个例子,我在这里的原始答案并不允许2个选定的字母是相同的字母。因为我将高级算法与算法的逻辑部分的实现分开,所以我通过简单地将TakeRandom
更改为letters.Shuffle().Take(2) ...
来解决这个问题。现在你可以看到使用函数的强大功能(即使它们看起来有些大而且有些笨拙),而不仅仅是编写一个完全只做一件事的原始实现。
注意:我的letters.TakeRandom(2) ...
方法是伪装的Fisher-Yates shuffle。
对那些寻求大量随机性的友好警告
请考虑Wikipedia Fisher-Yates Shuffle page, section:
中的这句话许多编程语言和/或库提供的内置伪随机数生成器通常只有32位内部状态,这意味着它只能生成232个不同的数字序列。如果使用这样的发电机来洗牌一副52张扑克牌,它只会产生52张牌中的一小部分! ≈2 225.6 可能的排列。内部状态小于226位的发生器不可能产生52张牌的所有可能的排列。
所以请注意。如果要在运行32位RNG时调整超过12项,或者在运行32位RNG时超过20项,则需要交换比内置.Net Shuffle
更重的随机数生成器。 64位RNG,并且在一定程度上可靠地获得所有可能结果的相对平等机会(参见图表&#34; PRNG种子的大小和可以达到每个排列的最大列表&#34;在上述文章的右侧)。例如,考虑使用System.Security.Cryptography.RNGCryptoServiceProvider,但仍然要注意它可以提供多少熵!除非你真的知道自己在做什么,否则不要用它来洗牌。
答案 2 :(得分:0)
var random = new Random();
for (int i=0; i<50; i++){
var resultLetters = new string(
Enumerable.Repeat(chars, 2)
.Select(s => letters[random.Next(letters.Length)]));
}
将从可用池中选择两个字母。你可以用数字做同样的事情(但是5次)。如果你想让订单是随机的,你可以通过最后改组数组来做到这一点(Collections.shuffle将洗牌一个Collection)。
答案 3 :(得分:0)
如果您喜欢,这是一行解决方案
CREATE OR REPLACE PROCEDURE POPULATETARGET IS
TYPE KEYS_T IS TABLE OF SOMETABLE.KEY%TYPE;
L_KEYS KEYS_T;
V_DAY NUMBER;
SRC_CODE_FETCH VARCHAR2(200);
V_SRC_CODE VARCHAR2 (4000);
RC SYS_REFCURSOR;
BEGIN
V_DAY := 20150826;
SRC_CODE_FETCH := 'SELECT SRC_CODE FROM SOURCE';
OPEN RC FOR SRC_CODE_FETCH;
LOOP
FETCH RC INTO V_SRC_CODE;
EXIT WHEN RC%NOTFOUND;
EXECUTE IMMEDIATE V_SRC_CODE BULK COLLECT INTO L_KEYS USING V_DAY;
FORALL x IN L_KEYS.FIRST..L_KEYS.LAST
INSERT INTO TARGET VALUES L_KEYS(x);
END LOOP;
CLOSE RC;
END;
答案 4 :(得分:0)
这是我的解决方案。它首先生成一个包含6个数字的字符串,然后将随机字母插入随机索引两次。这样,您应该为所有可能的输出均匀分配。
关于C#Random
类的一个重要注意事项是,您不应该为每个生成的字符串重新实例化它,否则您将使用相同的种子并且每次都获得相同的输出。
public string GenerateString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 6; i++)
{
sb.Append(numbers[random.Next(numbers.Length)]);
}
int letterIndex = random.Next(6);
sb.Insert(letterIndex, letters[random.Next(letters.Length)]);
letterIndex = random.Next(7);
sb.Insert(letterIndex, letters[random.Next(letters.Length)]);
return sb.ToString();
}