110,546
社区成员
发帖
与我相关
我的任务
分享
有人开发个程序以产生一些“标号”,采用了多重循环,如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 多重循环
{
class Program
{
static void Main(string[] args)
{
int i, j, k;
string s = "ABCDE";
for (i = 0; i <3; ++i)
{
for (j = 0; j < 3; ++j)
{
for (k = 0; k < 2; ++k)
{
Console.WriteLine("{0}{1}{2}", s[i], s[j], k);
}
}
}
Console.ReadKey();
}
}
}
运行结果:
AA0
AA1
AB0
AB1
AC0
AC1
BA0
BA1
BB0
BB1
BC0
BC1
CA0
CA1
CB0
CB1
CC0
CC1
上面的每个标号只有三位,位数太少,标号数量不够用,问能否多产生几位?
这里面可能包含有两层含义:
1、多写几层循环当然可以,有无更简单的方法?
2、循环几次不确定,能否完成这样的循环?
其实,一层层的去嵌套循环确实不必要,下面就可简单地解决上面的问题:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 多重循环
{
class Program
{
static void Main(string[] args)
{
string s1 = "AB";
string s2 = "123";
string[] s = new string[] { s1, s1, s1, s2 };//可定义每一位可用的字符
mulLoop(s);
Console.ReadKey();
}
static void mulLoop(string[] s)
{
int[] mark = new int[s.Length];
int p = 0;
while (p>=0)
{
for (int i = 0; i < s.Length; ++i)
{
Console.Write(s[i][mark[i]]);
}
Console.WriteLine();
p = mark.Length - 1;
while (p >= 0)
{
++mark[p];
if (mark[p] < s[p].Length) break;
mark[p] = 0;
--p;
}
}
}
}
}
运行结果如下:
AAA1
AAA2
AAA3
AAB1
AAB2
AAB3
ABA1
ABA2
ABA3
ABB1
ABB2
ABB3
BAA1
BAA2
BAA3
BAB1
BAB2
BAB3
BBA1
BBA2
BBA3
BBB1
BBB2
BBB3
string s1 = "AB";
string s2 = "123";
string[] s = new string[] { s1, s1, s1, s2 };//可定义每一位可用的字符
用这样的模式实现了可变位数、可变每位字符集
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try
Dim num1 As Integer = Me.TextBox1.Text
Me.ListBox1.Items.Clear()
Dim ii As Integer
For ii = 1 To num1
Me.ListBox1.Items.Add(ii & "编号 = " & to26(ii, 6))
Next
Catch e1 As Exception
Dim mName As String
mName = System.Reflection.MethodBase.GetCurrentMethod().Name()
MsgBox("在" & Me.GetType.FullName & "的" & mName & "中出现错误:" & ControlChars.CrLf & ControlChars.CrLf & e1.Message, MsgBoxStyle.Exclamation)
End Try
End Sub
Public Function to26(ByVal num1 As Integer, ByVal len As Integer) As String
Dim A_n As Integer
A_n = Asc("A")
Dim v1 As Integer
Dim x As Integer
Dim y As Integer
Dim str_o As String = ""
v1 = num1
While v1 > 0
x = v1 \ 26
y = v1 Mod 26
Dim str1 As String
Dim s_n As Integer
If y = 0 Then
s_n = A_n - 1 + 26
str1 = Chr(s_n)
x = x - 1
Else
s_n = A_n - 1 + y
str1 = Chr(s_n)
End If
str_o = str1 & str_o
v1 = x
End While
str_o = str_o.PadLeft(len, " ")
Return str_o
End Function
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Try
Dim num1 As Integer = Me.TextBox2.Text
Me.TextBox3.Text = (to26(num1, 6))
Catch e1 As Exception
Dim mName As String
mName = System.Reflection.MethodBase.GetCurrentMethod().Name()
MsgBox("在" & Me.GetType.FullName & "的" & mName & "中出现错误:" & ControlChars.CrLf & ControlChars.CrLf & e1.Message, MsgBoxStyle.Exclamation)
End Try
End Sub
//假设dic中每个字符串没有重复字符
static string IntegerToSN(string[] dic, int num)
{
char[] result = new char[dic.Length];
for (int i = dic.Length - 1; i >= 0; i--)
{
result[i] = dic[i][num % dic[i].Length];
num /= dic[i].Length;
}
return new string(result);
}
static int SNToInteger(string[] dic, string sn)
{
int result = 0;
for (int i = 0; i < dic.Length; i++)
{
result *= dic[i].Length;
result += dic[i].IndexOf(sn[i]);
}
return result;
}
这种问题相当于进制转换,只不过每位的进制不一样
public static string[] GenerateLabels(int length)
{
if (length < 1 || length > 30)
throw new ArgumentOutOfRangeException();
List<string> list = new List<string>();
int count = (1 << (length + 1)) - 1;
for (int i = 0; i < count; i++)
{
if ((i % 4) != 3)
{
list.Add(Translate(i, length));
}
}
return list.ToArray();
}
private static string Translate(int number, int length)
{
StringBuilder text = new StringBuilder(length - 1);
for (int i = length; i > 1; i--)
{
text.Append((char)(65 + Math.Sign(number & (1 << i))));
}
text.Append((char)(49 + (number & 3)));
return text.ToString();
}
这段代码是按你第二个示例的逻辑写的,即其模式为[AB]*[123]。
原理很简单,用一个Int32来表示一个标号,通过Int32的每个位来描述一个字符,0表示A,1表示B。但由于标号最后一位有三个字符,因此需要有2位来表示。Int32一共32位,除去最高的符号位以外,最多可以生成30个字符长度的标号。
GenerateLables是入口函数,参数length表示生成标号的最大长度。
Translate是将Int32转换为相应的标号字符串。
以length=6运行得到如下结果
AAAAA1
AAAAA2
AAAAA3
AAAAB1
AAAAB2
AAAAB3
AAABA1
AAABA2
AAABA3
AAABB1
AAABB2
AAABB3
AABAA1
AABAA2
AABAA3
AABAB1
AABAB2
AABAB3
AABBA1
AABBA2
AABBA3
AABBB1
AABBB2
AABBB3
ABAAA1
ABAAA2
ABAAA3
ABAAB1
ABAAB2
ABAAB3
ABABA1
ABABA2
ABABA3
ABABB1
ABABB2
ABABB3
ABBAA1
ABBAA2
ABBAA3
ABBAB1
ABBAB2
ABBAB3
ABBBA1
ABBBA2
ABBBA3
ABBBB1
ABBBB2
ABBBB3
BAAAA1
BAAAA2
BAAAA3
BAAAB1
BAAAB2
BAAAB3
BAABA1
BAABA2
BAABA3
BAABB1
BAABB2
BAABB3
BABAA1
BABAA2
BABAA3
BABAB1
BABAB2
BABAB3
BABBA1
BABBA2
BABBA3
BABBB1
BABBB2
BABBB3
BBAAA1
BBAAA2
BBAAA3
BBAAB1
BBAAB2
BBAAB3
BBABA1
BBABA2
BBABA3
BBABB1
BBABB2
BBABB3
BBBAA1
BBBAA2
BBBAA3
BBBAB1
BBBAB2
BBBAB3
BBBBA1
BBBBA2
BBBBA3
BBBBB1
BBBBB2
BBBBB3
最后要说一点,因为只有A和B两个字符,程序相对来说简单点,如果有更多的字符就会复杂一些,你可以自己试着去改。