Увеличьте значение от AAA до ZZZ с циклическим вращением

Я должен кодировать метод, которые увеличивают строковое значение от 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();
    }

Я знаю, что эта часть кода довольно грязна и не очень эффективна, но я не знаю, как сделать это правильно.

Как защищается этот отрывок? (это будет только работать на plaform окон),

Как я могу оптимизировать - это и сделать это более читаемым?

Спасибо за Ваши комментарии

10
задан fxkim 15 June 2010 в 16:31
поделиться

3 ответа

Подумайте об этом математически: ваши строки (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();
}
19
ответ дан 3 December 2019 в 15:21
поделиться

Я думаю, что проще разобрать его до целого числа, сделать инкремент, а затем отформатировать результат как строку. Обратите внимание, что если вам нужно просто итерировать числа для создания диапазона комбинаций, то инкремент/разбор вам не нужен. Вы можете просто выполнить цикл 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];
}
1
ответ дан 3 December 2019 в 15:21
поделиться

Возможно, я что-то упускаю, но я думаю, что это достаточно тривиальное решение работает, и не только для трехзначных чисел; любое число произвольной длины с основанием 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);
}
11
ответ дан 3 December 2019 в 15:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: