想象一下,我想从A迭代到Z.我们将使用Foreach
或For
循环。达到Z后,我想从AA到ZZ迭代,所以从AA开始,然后到AB,AC ...... AZ,BA,BC..BZ..ZA,ZB,ZZ。在这一点上,我们将移动到三个chars
,然后是4等,直到一个未定义的点。
因为我们没有为数组定义长度,所以我们不能使用嵌套的for
循环......所以
问题:如何做到这一点?
注意,没有给出代码,因为我们都知道如何在数组上foreach
和嵌套foreach
循环。
答案 0 :(得分:1)
你可以做这样的事情,它会给你无休止的模式输出(对不起,不完全是你的模式,但你明白该怎么做)
public static IEnumerable<string> Produce()
{
string seed = "A";
int i = 0;
while (true)
{
yield return String.Join("", Enumerable.Repeat(seed, i));
if (seed == "Z")
{
seed = "A";
i++;
}
else
{
seed = ((char)(seed[0]+1)).ToString();
}
}
}
而不是:
foreach (var s in Produce())
{
//Do something
}
编辑我希望使用此方法输出:
public static IEnumerable<string> Produce()
{
int i = 1;
while (true)
{
foreach(var c in produceAmount(i))
{
yield return c;
}
i++;
}
}
private static IEnumerable<string> produceAmount(int i)
{
var firstRow = Enumerable.Range('A', 'Z' - 'A'+1).Select(x => ((char)x).ToString());
if (i >= 1)
{
var second = produceAmount(i - 1);
foreach (var c in firstRow)
{
foreach (var s in second)
{
yield return c + s;
}
}
}
else
{
yield return "";
}
}
答案 1 :(得分:1)
这里有一些代码可以满足您的需求。以下是完整的解释,但总的来说,它利用了这样一个事实:一旦你完成了给定长度的所有字母,你就会做A,然后是整个序列,然后是B,然后是整个序列,等等。
private IEnumerable<string> EnumerateLetters()
{
int count = 1;
while (true)
{
foreach(var letters in EnumerateLetters(count))
{
yield return letters;
}
count++;
}
}
private IEnumerable<string> EnumerateLetters(int count)
{
if (count==0)
{
yield return String.Empty;
}
else
{
char letter = 'A';
while(letter<='Z')
{
foreach(var letters in EnumerateLetters(count-1))
{
yield return letter+letters;
}
letter++;
}
}
}
有两种方法。第一个是你调用的那个,它将生成一个无限的字母序列。第二个是递归魔术。
第一个很简单。它有一个我们在多少个字母的数量,用该计数调用第二个方法,然后枚举通过它们返回它们。一旦完成一个大小的全部操作,它就会增加计数和循环。
第二种方法是神奇的方法。它会计算生成的字符串中的字母数。如果计数为零,则返回一个空字符串并中断。
如果计数大于1,它将循环通过字母A到Z,并且对于每个字母,它将比它更短的序列附加到A.然后对于B,依此类推。
然后这将无限期地继续下去。
序列将无限期地继续产生。因为它使用递归,理论上如果你的字母字符串变得太长就会开始堆栈溢出,但是在字符串中每个字母的一个递归级别,你需要在你需要担心之前得到很长的字符串(而且我怀疑如果你在一个循环中走得那么远,你会先遇到其他问题。
另一个关键点(如果您不知道)是yield return使用延迟执行,因此它将根据需要生成序列中的每个新元素,因此它只会生成您要求的任意数量的项目。如果你迭代五次,它只会产生A-E,并且不会在任何时候考虑接下来的事情而浪费。
答案 2 :(得分:1)
另一个生成器(将1
添加到带radix == 26
的数字:A
代表0
,B代表1
,... {{1 } Z
}:
25
测试
// please, notice, that Generator() can potentially spawn ifinitely many items
private static IEnumerable<String> Generator() {
char[] data = new char[] { 'A' }; // number to start with - "A"
while (true) {
yield return new string(data);
// trying to add one
for (int i = data.Length - 1; i >= 0; --i)
if (data[i] == 'Z')
data[i] = 'A';
else {
data[i] = (char) (data[i] + 1);
break;
}
// have we exhausted N-length numbers?
if (data.All(item => item == 'A'))
data = Enumerable
.Repeat('A', data.Length + 1) // ... continue with N + 1-length numbers
.ToArray();
}
}
结果
// take first 1000 items:
foreach (var item in Generator().Take(1000))
Console.WriteLine(item);
答案 3 :(得分:1)
要走的路是使用简单的递归方法。 C#是一种使用生成器来表达想法的好语言:
GRANT CONNECT ON DATABASE YourDatabaseName TO Read_Only_User;
GRANT USAGE ON SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO Read_Only_User;
private static IEnumerable<string> EnumerateLetters(int length) {
for (int i = 1; i <= length; i++) {
foreach (var letters in EnumerateLettersExact(i)) {
yield return letters;
}
}
}
private static IEnumerable<string> EnumerateLettersExact(int length) {
if (length == 0) {
yield return "";
}
else {
for (char c = 'A'; c <= 'Z'; ++c) {
foreach (var letters in EnumerateLettersExact(length - 1)) {
yield return c + letters;
}
}
}
}
private static void Main(string[] args) {
foreach (var letters in EnumerateLetters(2)) {
Console.Write($"{letters} ");
}
}
生成连续的字母序列。参数决定了您要求序列的长度。
EnumerateLetters
负责递归生成序列。它可以是空的,也可以是一些字母与所有较短长度序列的串联。
答案 4 :(得分:0)
你的目标是从A到Z [A,...,Z]。 然后你要做多个for循环
例如:
PSEUDOCODE
foreach(in array){
first = declare first variable (array)
foreach(in array{
second =declare 2nd variable (array)
return first + second
}
}
答案 5 :(得分:0)
尝试以下方法。这是一种为给定数字生成适当字符串的方法。您可以为所需的迭代次数编写for循环。
string SingleEntry(int number)
{
char[] array = " ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToArray();
Stack<string> entry = new Stack<string>();
List<string> list = new List<string>();
int bas = 26;
int remainder = number, index = 0;
do
{
if ((remainder % bas) == 0)
{
index = bas;
remainder--;
}
else
index = remainder % bas;
entry.Push(array[index].ToString());
remainder = remainder / bas;
}
while (remainder != 0);
string s = "";
while (entry.Count > 0)
{
s += entry.Pop();
}
return s;
}