これを試してください:(編集でいくつかのバグを修正、編集2:テストは機能しますが、比較は失敗します)
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
class Ids {
Ids(char min,char max) {
this.min=min;
this.max=max;
n=max-min+1;
}
String inc(String s) {
if(print)
System.out.println("inc "+s);
String t="";
char c=s.charAt(s.length()-1);
char o=c==max?min:(char)(c+1);
boolean carry=o==min;
t+=o;
for(int i=s.length()-2;i>=0;i--) {
c=s.charAt(i);
if(carry) {
o=c==max?min:(char)(c+1);
carry=o==min;
} else o=c;
t+=o;
}
if(carry)
t+=min;
t=reverse(t);
if(print)
System.out.println("inc returns "+t);
int compare=s.compareTo(t);
if(compare!=-1)
System.out.println("compare fails: "+s+"<>"+t+" returns "+compare);
return t;
}
private static String reverse(String t) {
String t2="";
for(int i=0;i<t.length();i++)
t2+=t.charAt(t.length()-1-i);
return t2;
}
String dec(String s) {
if(print)
System.out.println("dec "+s);
String t="";
char c=s.charAt(s.length()-1);
if(c==min&&s.length()==1)
return null;
char o=c==min?max:(char)(c-1);
boolean borrow=o==max;
t+=o;
if(print)
System.out.println("last character, t="+t);
for(int i=s.length()-2;i>=0;i--) {
c=s.charAt(i);
if(print)
System.out.println("in loop, c="+c);
if(borrow) {
if(c==min) {
o=max;
borrow=true;
} else {
o=--c;
borrow=false;
}
// o=c==min?max:(char)(c-1);
// borrow=o==max;
} else o=c;
if(print)
System.out.println("in loop, adding: "+o);
t+=o;
if(print)
System.out.println("in loop, t="+t);
}
if(borrow)
t=t.substring(0,t.length()-1);
t=reverse(t);
if(print)
System.out.println("dec returns "+t);
int compare=s.compareTo(t);
if(compare!=1)
System.out.println("compare fails: "+s+"<>"+t+" returns "+compare);
return t;
}
void run(String s) {
String i=inc(s);
String d=dec(s);
System.out.println(d+"<"+s+"<"+i);
}
void run() {
print();
run("b");
run("c");
run("y");
run("z");
}
public static void main(String[] args) {
new Ids('a','z').run();
}
void print() {
System.out.println("min="+min+", max="+max+",range="+n);
}
static boolean print;
final char min,max;
final int n;
}
public class So12827926TestCase {
@Before public void setUp() throws Exception {
Ids.print=false;
}
@After public void tearDown() throws Exception {
Ids.print=false;
}
@Test public void testIncDecOnOneCharacter() {
for(char c=ids.min;c<ids.max;c++) {
String original=""+(char)(c);
String expected=""+(char)(c+1);
String actual=ids.inc(""+(char)c);
assertEquals(expected,actual);
String duplicate=ids.dec(expected);
assertEquals(original,duplicate);
}
}
@Test public void testDecIncOnOneCharacter() {
for(char c=(char)(ids.min+1);c<=ids.max;c++) {
String original=""+(char)(c);
String expected=""+(char)(c-1);
String actual=ids.dec(""+(char)c);
assertEquals(expected,actual);
String duplicate=ids.inc(expected);
assertEquals(original,duplicate);
}
}
@Test public void testIncDecEdgeCaseOnOneCharacter() {
String original=""+ids.max;
String expected=""+ids.min+ids.min;
String actual=ids.inc(original);
assertEquals(expected,actual);
String duplicate=ids.dec(expected);
assertEquals(original,duplicate);
}
@Test public void testIncEdgeCaseOnTwoCharacters() {
String original=""+ids.min+ids.min;
String expected=""+ids.min+(char)(ids.min+1);
String actual=ids.inc(original);
assertEquals(expected,actual);
}
@Test public void testDecIncEdgeCaseOnOneCharacter() {
String original=""+ids.min;
String expected=null;
String actual=ids.dec(original);
assertEquals(expected,actual);
if(expected!=null) {
String duplicate=ids.inc(expected);
assertEquals(original,duplicate);
}
}
@Test public void testIncDecEdgeCaseOnTwoCharacters() {
String original=""+ids.min+ids.max;
String expected=""+(char)(ids.min+1)+ids.min;
String actual=ids.inc(original);
assertEquals(expected,actual);
String duplicate=ids.dec(expected);
assertEquals(original,duplicate);
}
@Test public void testDecIncEdgeCaseOnTwoCharacters() {
String original=""+ids.max+ids.min;
String expected=""+(char)(ids.max-1)+ids.max;
String actual=ids.dec(original);
assertEquals(expected,actual);
String duplicate=ids.inc(expected);
assertEquals(original,duplicate);
}
@Test public void testIncDecEdgeCaseOnThreeCharacters() {
String original=""+ids.min+ids.max+ids.max;
String expected=""+(char)(ids.min+1)+ids.min+ids.min;
String actual=ids.inc(original);
assertEquals(expected,actual);
String duplicate=ids.dec(expected);
assertEquals(original,duplicate);
}
@Test public void testDecIncEdgeCaseOnThreeCharacters() {
String original=""+ids.max+ids.min+ids.min;
String expected=""+(char)(ids.max-1)+ids.max+ids.max;
String actual=ids.dec(original);
assertEquals(expected,actual);
String duplicate=ids.inc(expected);
assertEquals(original,duplicate);
}
@Test public void testDecIntForSomeEdgeCases() {
Ids ids=new Ids('a','z');
for(int i=0;i<originals.length;i++) {
String original=originals[i];
String expected=expecteds[i];
String actual=ids.dec(original);
assertEquals(expected,actual);
String duplicate=ids.inc(expected);
assertEquals(original,duplicate);
}
}
@Test public void testIncDecForSomeEdgeCases() {
Ids ids=new Ids('a','z');
for(int i=0;i<originals.length;i++) {
String original=expecteds[i];
String expected=originals[i];
String actual=ids.inc(original);
assertEquals(expected,actual);
String duplicate=ids.dec(expected);
assertEquals(original,duplicate);
}
}
@Test public void testInc() {
Ids ids=new Ids('a','z');
String start=""+ids.min,s=start;
for(int i=0;i<ids.n-1;i++)
s=ids.inc(s);
assertEquals(""+ids.max,s);
}
@Test public void testDec() {
Ids ids=new Ids('a','z');
String start=""+ids.max,s=start;
for(int i=0;i<ids.n-1;i++)
s=ids.dec(s);
assertEquals(""+ids.min,s);
}
Ids ids=new Ids('a','b');
// swap these, they will make more sense that way.
static final String[] originals=new String[]{"baa","caa","daa","xaa","yaa","zaa"};
static final String[] expecteds=new String[]{"azz","bzz","czz","wzz","xzz","yzz"};
}