如何通过所有可能性增加java String?

我需要将java中的String从“aaaaaaaa”增加到“aaaaaab”到“aaaaaac”,直到字母表,然后最终到“aaaaaaba”到“aaaaaabb”等。

有这个诀窍吗?

这不是一个“技巧”,但这适用于4字符串。 显然,对于更长的琴弦来说它会变得更加丑陋,但这个想法是一样的。

char array[] = new char[4]; for (char c0 = 'a'; c0 <= 'z'; c0++) { array[0] = c0; for (char c1 = 'a'; c1 <= 'z'; c1++) { array[1] = c1; for (char c2 = 'a'; c2 <= 'z'; c2++) { array[2] = c2; for (char c3 = 'a'; c3 <= 'z'; c3++) { array[3] = c3; String s = new String(array); System.out.println(s); } } } } 

你基本上实现了一个Base 26号码系统,带有前导“零”(“a”)。

你可以像将int转换为base-2或base-10字符串一样,但不是使用2或10,而是使用26而不是’0’作为基础,使用’a’。

在Java中,您可以轻松使用:

 public static String base26(int num) { if (num < 0) { throw new IllegalArgumentException("Only positive numbers are supported"); } StringBuilder s = new StringBuilder("aaaaaaa"); for (int pos = 6; pos >= 0 && num > 0 ; pos--) { char digit = (char) ('a' + num % 26); s.setCharAt(pos, digit); num = num / 26; } return s.toString(); } 

那么基本的想法是不存储String,而只是存储一些计数器(int一个int或一个long,取决于你的要求)并根据需要将它转换为String。 这样,您可以轻松地增加/减少/修改计数器,而无需解析和重新创建字符串。

下面的代码使用递归方法来获取下一个字符串(比方说,从“aaaa”到“aaab”等),而不需要生成所有以前的组合,所以它相当快,并且不限于给定的最大值字符串长度。

 public class StringInc { public static void main(String[] args) { System.out.println(next("aaa")); // Prints aab System.out.println(next("abcdzz")); // Prints abceaa System.out.println(next("zzz")); // Prints aaaa } public static String next(String s) { int length = s.length(); char c = s.charAt(length - 1); if(c == 'z') return length > 1 ? next(s.substring(0, length - 1)) + 'a' : "aa"; return s.substring(0, length - 1) + ++c; } } 

增加最后一个字符,如果它达到Z,则将其重置为A并移动到前一个字符。 重复,直到找到一个不是Z的字符。因为字符串是不可变的,我建议使用一个字符数组来避免分配很多很多新对象。

 public static void incrementString(char[] str) { for(int pos = str.length - 1; pos >= 0; pos--) { if(Character.toUpperCase(str[pos]) != 'Z') { str[pos]++; break; } else str[pos] = 'a'; } } 

你可以使用大整数的toString(radix)方法,如:

 import java.math.BigInteger; public class Strings { Strings(final int digits,final int radix) { this(digits,radix,BigInteger.ZERO); } Strings(final int digits,final int radix,final BigInteger number) { this.digits=digits; this.radix=radix; this.number=number; } void addOne() { number=number.add(BigInteger.ONE); } public String toString() { String s=number.toString(radix); while(s.length() 

如果你只想要最终结果,我必须同意@ saua的方法,但是如果你想要每个结果,这里有一个小的变化。

请注意,由于有26 ^ 8(或208827064576)个不同的可能字符串,我怀疑你想要它们。 也就是说,我的代码打印它们而不是只在String Builder中存储一个。 (但这并不重要。)

  public static void base26(int maxLength) { buildWord(maxLength, ""); } public static void buildWord(int remaining, String word) { if (remaining == 0) { System.out.println(word); } else { for (char letter = 'A'; letter <= 'Z'; ++letter) { buildWord(remaining-1, word + letter); } } } public static void main(String[] args) { base26(8); } 

我会创建一个字符数组并单独增加字符。 字符串在Java中是不可变的,因此每次更改都会在堆上创建一个新的位置,从而导致内存增长和增长。

使用字符数组,你不应该有这个问题……

有一个包含ascii值的字节数组,并且具有在进行结转时递增最右边数字的循环。

然后使用创建字符串

 public String(byte[] bytes, String charsetName) 

确保以US-ASCII或UTF-8的forms传递charset是明确的。

只是扩展示例,就实现而言,考虑将其放入类中……每次调用Class的String时,它都会返回下一个值:

 public class Permutator { private int permutation; private int permutations; private StringBuilder stringbuilder; public Permutator(final int LETTERS) { if (LETTERS < 1) { throw new IllegalArgumentException("Usage: Permutator( \"1 or Greater Required\" \)"); } this.permutation = 0; // MAGIC NUMBER : 26 = Number of Letters in the English Alphabet this.permutations = (int) Math.pow(26, LETTERS); this.stringbuilder = new StringBuilder(); for (int i = 0; i < LETTERS; ++i) { this.stringbuilder.append('a'); } } public String getCount() { return String.format("Permutation: %s of %s Permutations.", this.permutation, this.permutations); } public int getPermutation() { return this.permutation; } public int getPermutations() { return this.permutations; } private void permutate() { // TODO: Implement Utilising one of the Examples Posted. } public String toString() { this.permutate(); return this.stringbuilder.toString(); } } 

此代码适用于任何大小的字符串。

  public static String iterateAlphabetic(String input) { String output = input.toUpperCase(); char[] array = output.toCharArray(); boolean overflow = true; for(int itr=array.length-1; itr>=0; itr--) { if(overflow && array[itr]=='Z') { array[itr] = 'A'; overflow = true; continue; } if(overflow) { array[itr] = next(alphabeticUpper,array[itr]); overflow = false; continue; } break; } if(overflow) output = "A" + new String(array); else output = new String(array); if(output.length() < input.length()) output = StringUtil.padding(output, 'A', input.length()); return output; } public static String padding(String input, char pad, int width) { if (width < 0) throw new IllegalArgumentException("width must be > 0"); if (width < input.length()) return input; StringBuilder sb = new StringBuilder(); for(int i = 0;i < (width - input.length()); i++) { sb.append(pad); } sb.append(input); return sb.toString(); } 

在@cyberz的解决方案的基础上,以下代码是一个如何编写递归调用的示例,该调用可以由支持Tail Recursion的编译器进行优化。

代码是用Groovy编写的,因为它在JVM上运行,其语法非常类似于Java,它的编译器支持尾递归优化

 static String next(String input) { return doNext(input, "") } @TailRecursive @CompileStatic static String doNext(String input, String result) { if(!self) { return result } final String last = input[-1] final String nonLast = self.substring(0, input.size()-1) if('z' == last) { return doNext(nonLast, (nonLast ? 'a' : 'aa') + result) } return doNext('', nonLast + (((last as Character) + 1) as Character).toString() + result) } 

由于没有一个答案对我有用,我编写了自己的代码:

 /** * Increases the given String value by one. Examples (with min 'a' and max 'z'): 

* * - "aaa" -> "aab"
* - "aab" -> "aac"
* - "aaz" -> "aba"
* - "zzz" -> "aaaa"
* * @param s * @param min lowest char (a zero) * @param max highest char (eg a 9, in a decimal system) * @return increased String by 1 */ public static String incString(String s, char min, char max) { char last = s.charAt(s.length() - 1); if (++last > max) return s.length() > 1 ? incString(s.substring(0, s.length()-1), min, max) + min : "" + min + min; else return s.substring(0, s.length()-1) + last; }