2016-07-05 27 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,而是基地26的3個地方和基地10的3個地方。根本不清楚你想要做什麼。您需要向我們展示您編寫的代碼並解釋您不瞭解的內容。 –

+0

你看過嗎? http://stackoverflow.com/questions/15735079/convert-from-one-base-to-another-in-java –

+1

不是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(); 
} 

第三

這適用於您當前的「需求」。與開頭所提問題相比,這不僅僅是「由字母組成的左半部分」+「由數字組成的右半部分」。現在,這是「任何事情」,字母從A到Z滾動到A,而數字從0到9變爲0.當一個字母到達Z時,它被重置爲A,然後左側的數字/字母增加。

如果所有數字均遞增,則不會在左側添加新數字。你沒有提到你的問題,但我敢肯定,你可以從這裏想出解決辦法:

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。對於轉換,你需要保持一系列的基礎使用 - 我建議從單位/小端開始,只是使用一些容易迭代並能夠保持(小)整數的東西。從字母數字整數,從零開始。對於每個角色,請添加其值。對於一封信,保留不同字母的數量(字母大小,現在使用的拉丁字母表爲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 ['A's與2'''''怎麼不重要?'([Alex](http: //stackoverflow.com/a/38210171/3789665))) – greybeard

+0

謝謝指出。這是一個錯字。其實它是AAA010-AAA003 = 7。 –