2016-07-05 7 views
-9

Мне нужно реализовать буквенно-цифровой алгоритм приращения, например, AAA001 должен стать AAA002 AAA999 должен стать AAB000 и так далее.Алфавитно-цифровой алгоритм приращения в JAVA

Все алфавиты в верхнем регистре и буквы от 0 до 9. Он может содержать алфавит или букву в любом положении в алфавитно-цифровой строке.

Есть некоторые правила, хотя, например, некоторые 000 или 666 не должны появляться в серии. Это можно сделать позже, но мне нужна базовая логика для реализации алгоритма.

Я вижу, что многие люди не понимали моего вопроса. Представьте себе номер пластины, который представляет собой не что иное, как буквенно-цифровую серию, которая может иметь некоторые исключенные символы, такие как BB6660 -> 666, тройной 6 между ними не допускается.

Она должна поддерживать различные форматы как-

@@@## 
    @#@@## 
    [email protected]#@@## 
    @@@@#### 
    ##@@#@ 

    @ means alphabet A-Z 
    # means numbers 0-9    

Примеры:

AFG99 + 1= AFH00 
    A2GF23 + 1 = A2GF24 
    1A9AU99 + 1 = 1A9AV00 
    AAZZ9999 + 1 = ABAA0000 
    11AA9Z + 1 = 11AB0A 

мне нужно какое-то математическое решение, так что я могу сделать математику и увеличить его легко без использования приращения символов.

Мне также нужен счетчик между двумя диапазонами, например, сколько точек отсчета между AAA003 и AA010?

AAA010 - AAA003 = 7 

Я был бы признателен за помощь ..

+1

Я думаю, вы имеете в виду значение после 'AAA999'' AAB000', а не 'AAZ000'. Кроме того, это не база 36, а 3 места базы 26 и 3 места базы 10. Не совсем ясно, что вы пытаетесь сделать. Вы должны показать нам код, который вы написали, и объяснить, что вы не понимаете. –

+0

Вы посмотрели на это? http://stackoverflow.com/questions/15735079/convert-from-one-base-to-another-in-java –

+1

isnt значение после AAA999 -> AAA99A в базе 36? – alexbt

ответ

2

Вот 3 решения: первые два несколько арифметических incrementations в то время как третий больше персонаж манипуляциями.

3 реализациях все проходят одни и те же модульные тесты:

assertEquals("1DDA01A", MyClass.increment("1DDA00Z")); 
assertEquals("1A9AV00", MyClass.increment("1A9AU99")); 
assertEquals("AFH00", MyClass.increment("AFG99")); 
assertEquals("A2GF24", MyClass.increment("A2GF23")); 
assertEquals("ABAA0000", MyClass.increment("AAZZ9999")); 
assertEquals("11AB0A", MyClass.increment("11AA9Z")); 

Первое:

public static String increment(String number) { 
    Pattern compile = Pattern.compile("^(.*?)([9Z]*)$"); 
    Matcher matcher = compile.matcher(number); 
    String left=""; 
    String right=""; 
    if(matcher.matches()){ 
     left = matcher.group(1); 
     right = matcher.group(2); 
    } 
    number = !left.isEmpty() ? Long.toString(Long.parseLong(left, 36) + 1,36):""; 
    number += right.replace("Z", "A").replace("9", "0"); 
    return number.toUpperCase(); 
} 

Второе:

public static String increment(String number) { 
    Pattern compile = Pattern.compile("^(.*?)([0-9]*|[A-Z]*)$"); 
    Matcher matcher = compile.matcher(number); 
    String remaining = number; 
    String currentGroup = ""; 
    String result = ""; 

    boolean continueToNext = true; 
     while (matcher.matches() && continueToNext) { 
     remaining = matcher.group(1); 
     currentGroup = matcher.group(2); 
     int currentGroupLength = currentGroup.length(); 
     int base = currentGroup.matches("[0-9]*") ? 10 : 36; 
     currentGroup = Long.toString(Long.parseLong("1" + currentGroup, base) + 1, base); // The "1" if just to ensure that "000" doesn't become 0 (and thus losing the original string length) 
     currentGroup = currentGroup.substring(currentGroup.length() - currentGroupLength, currentGroup.length()); 
     continueToNext = Long.valueOf(currentGroup, base) == 0; 
     if (base == 36) { 
      currentGroup = currentGroup.replace("0", "A"); 
     } 

     result = currentGroup + result; 
     matcher = compile.matcher(remaining); 
    } 

    result = remaining + result; 
    return result.toUpperCase(); 
} 

Третий:

Это работает с вашими текущими «требованиями». По сравнению с тем, что задается в начале, это не просто «левая часть, состоящая из буквы» + «правая часть, состоящая из цифр». Теперь это «все идет», а буквы перекатываются от А до Я в А, а цифры от 0 до 9 до 0. Когда буква достигает Z, она сбрасывается до А, затем цифра/буква слева от нее увеличивается.

Если все номера увеличиваются, то он не добавляет новую цифру слева. Вы не говоря уже о том, что в вашем вопросе, но я уверен, что вы можете понять это отсюда:

public static String increment(String number) { 
    char[] cars = number.toUpperCase().toCharArray(); 
    for (int i = cars.length - 1; i >= 0; i--) { 
     if (cars[i] == 'Z') { 
      cars[i] = 'A'; 
     } else if (cars[i] == '9') { 
      cars[i] = '0'; 
     } else { 
      cars[i]++; 
      break; 
     } 
    } 
    return String.valueOf(cars); 
} 

Что касается «подсчета», ваш пример не является достаточным, чтобы понять логику. Он считает только цифры? как насчет писем? Это следует за baseXx?

Как может AA010-AAA003 = 7, 3 A против 2 A не важно? Я чувствую, что это скорее на вас, чтобы понять, каковы ваши требования (например, домашнее задание ..)

Технически это отвечает на вопрос, поскольку он был спрошен первоначально (со многими изменениями на этом пути).

+0

Спасибо, я должен проверить это. –

+0

Не нужно вставлять 'integerValue'. – shmosel

+0

@shmosel, спасибо, я изменил integerValue от Integer до int. – alexbt

0

[doing] math and increment [alphanumerics] without using character increment можно разложить на более простые проблемы: рассмотрите свои «буквенно-цифровые» целые числа, закодированные смешанной базой. Это оставит преобразование из буквенно-цифровых к целому числу, (math) операций (увеличение, отсчета между: разностью/вычитанием) на целых числах и преобразованием из целого числа до буквенно-цифровой.
Для целое число, посмотрите на LongAdder. Для конверсий вам нужно сохранить последовательность оснований для использования - я рекомендую начинать с единицы/на маленьком конце и просто использовать что-то легко повторяемое и способное хранить (маленькие) целые числа. Переход от alphanumeric к integer, начало с нуля. Для каждого символа добавьте его значение. Для буквы держите количество разных букв (размер алфавита, 26 с латинским алфавитом, как используется сейчас) в качестве базы для использования для этого места, для цифры количество разных цифр (обычно десять). Если следующий символ следует, умножьте эту базу и повторите.
Преобразование из целых к алфавитно- будет обычный divide&remainder (с использованием база, как хранится) - с уловом: как вы справляетесь с кэрри из наиболее значимых позиции?

There are some rules though, like some 000 or 666 should not come in a series. That can be done later on и убьет math.

+0

То, что вы предлагаете, отчасти верно. Я знаю, что это сложно, поэтому я в конечном итоге прошу о решении. –

+0

Можете ли вы определить и описать детали, которые не являются истиной, помимо того, что они представляют собой неопределенные выражения? он, рассмотрите предложения по улучшению вашего «вопроса» (например, «как может AA010-AAA003 = 7, 3 [' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' //stackoverflow.com/a/38210171/3789665))) – greybeard

+0

Спасибо, что указали это. Это была опечатка. На самом деле это AAA010-AAA003 = 7. –