我需要编写一个方法,通过循环旋转将字符串值从AAA递增到ZZZ(ZZZ之后的下一个值为AAA)
这是我的代码:
public static string IncrementValue(string value) {
if (string.IsNullOrEmpty(value) || value.Length != 3) {
string msg = string.Format("Incorrect value ('{0}' is not between AAA and ZZZ)", value);
throw new ApplicationException(msg);
}
if (value == "ZZZ") {
return "AAA";
}
char pos1 = value[0];
char pos2 = value[1];
char pos3 = value[2];
bool incrementPos2 = false;
bool incrementPos1 = false;
if (pos3 == 'Z') {
pos3 = 'A';
incrementPos2 = true;
} else {
pos3++;
}
if (incrementPos2 && pos2 == 'Z') {
pos2 = 'A';
incrementPos1 = true;
} else {
if (incrementPos2) {
if (pos2 == 'Z') {
pos2 = 'A';
incrementPos1 = true;
}
pos2++;
}
}
if (incrementPos1) {
pos1++;
}
return pos1.ToString() + pos2.ToString() + pos3.ToString();
}
我知道这段代码很脏而且效率不高但我不知道如何正确地做到这一点。
如何保护此代码段? (这只会在Windows平台上运行)
我如何优化它并使其更具可读性?
感谢您的评论
答案 0 :(得分:19)
以数学方式思考:你的字符串(AAA,AAB,......)的行为就像自然数字(000,001,...),除了基数为26而不是基数为10。
所以,你可以使用相同的原则。这是一些代码:
// iterate cyclicly from 0 to 26^3 - 1
int incrementValue(int i) {
// a verbose way of writing "return (i + 1) % 26^3"
i++;
if (i == 26*26*26) i = 0;
return i;
}
// convert 0 to AAA, 1 to AAB, ...
string formatValue(int i) {
var result = new StringBuilder();
result.Insert(0, (char)('A' + (i % 26)));
i /= 26;
result.Insert(0, (char)('A' + (i % 26)));
i /= 26;
result.Insert(0, (char)('A' + (i % 26)));
return result.ToString();
}
答案 1 :(得分:11)
也许我错过了一些东西,但我认为这个相当简单的解决方案有效,而不仅仅是三位数字;任何仲裁长度基数26都可以递增。根据问题,它将从ZZZZ包装到AAAA,而不是从ZZZZ“正确”递增到AAAAA。
// Increment a base 26 number (composed of "digits" A..Z), wrapping around
// from ZZZ... to AAA...
string increment(string str) {
char[] digits = str.ToCharArray();
for (int i = str.length - 1; i >= 0; --i) {
if (digits[i] == 'Z') {
digits[i] = 'A';
} else {
digits[i] += 1;
break;
}
}
return new string(digits);
}
答案 2 :(得分:1)
我认为将它解析为整数更容易,执行增量,然后将结果格式化为字符串。请注意,如果您只需要迭代数字以生成组合范围,那么您实际上不需要增量/解析。您可以在整数范围内使用for
循环,并使用format方法将整数转换为字符串。
public static string IncrementValue(string value) {
if (string.IsNullOrEmpty(value) || value.Length != 3) {
string msg = string.Format("Incorrect value ('{0}' is not between AAA and ZZZ)", value);
throw new ApplicationException(msg);
}
if (value == "ZZZ") {
return "AAA";
}
int thisValue = Parse( value );
thisValue = (thisValue + 1) % 17576; // 26 * 26 * 26
return Format( thisValue );
}
private static int Parse( string value )
{
int result = 0;
foreach (var c in value)
{
result += ('Z' - c); // might need to cast to int?
}
return result;
}
private static string[] Alphabet = new string[] { 'A', 'B', ... };
private static string Format( int value )
{
int digit0 = value % 26;
int digit1 = (value / 26) % 26;
int digit2 = value / 676;
return Alphabet[digit2] + Alphabet[digit1] + Alphabet[digit0];
}
答案 3 :(得分:-1)
在'C'中,我写了以下内容,完全按照要求进行,即给定AA将增加到AB。鉴于ZZZ将增加到AAA(周期)。
main(int argc, char **argv)
{
int i;
char *s = argv[1];
for(i=strlen(s)-1; i >= 0; i--) {
if(++s[i] > 'Z')
s[i] = 'A';
else
break;
}
printf("%s\n",s);
}
答案 4 :(得分:-1)
import java.util.*;
import java.io.*;
public class abc{
public static void main (String arg[])throws Exception{
int i;
String s;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("...");\\just for get length of vector example 3 for aaa to zzz
i= Integer.parseInt(br.readLine());
char[] guess = new char[i];
Arrays.fill(guess, 'a');
do {
System.out.println("Current guess: " + new String(guess));
int n = guess.length - 1;
while (n >= 0) {
guess[n]++;
if (guess[n] > 'z') {
if (n > 0) {
guess[n] = 'a';
}
n--;
}
else {
break;
}
}
}
while (guess[0] <= 'z');
}