Мне это нравится:
git diff --name-status <SHA1> <SHA1>^
Это не большая часть "приема", но это работает на строки с 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);
}
}
}
}
Вы в основном реализуете Основа, которую 26 систем счисления с продвижением "обнуляют" ("a").
Вы делаете это тот же способ, которым Вы преобразовываете интервал в основу 2 или основываете 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();
}
основная идея затем не состоит в том, чтобы сохранить Строку, но просто некоторый счетчик (интервал интервал или длинное, в зависимости от Ваших требований) и преобразовать его в Строку по мере необходимости. Таким образом, можно легко увеличить/уменьшить/изменить счетчик, не имея необходимость анализировать и воссоздавать Строку.
Увеличьте последний знак, и если он достигает 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 большого целого числа (основание) метод как:
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()<digits)
s='0'+s;
return s;
}
public char convert(final char c) {
if('0'<=c&&c<='9')
return (char)('a'+(c-'0'));
else if('a'<=c&&c<='p')
return (char)(c+10);
else throw new RuntimeException("more logic required for radix: "+radix);
}
public char convertInverse(final char c) {
if('a'<=c&&c<='j')
return (char)('0'+(c-'a'));
else if('k'<=c&&c<='z')
return (char)(c-10);
else throw new RuntimeException("more logic required for radix: "+radix);
}
void testFix() {
for(int i=0;i<radix;i++)
if(convert(convertInverse((char)('a'+i)))!='a'+i)
throw new RuntimeException("testFix fails for "+i);
}
public String toMyString() {
String s=toString(),t="";
for(int i=0;i<s.length();i++)
t+=convert(s.charAt(i));
return t;
}
public static void main(String[] arguments) {
Strings strings=new Strings(8,26);
strings.testFix();
System.out.println(strings.number.toString()+' '+strings+' '+strings.toMyString());
for(int i=0;i<Math.pow(strings.radix,3);i++)
try {
strings.addOne();
if(Math.abs(i-i/strings.radix*strings.radix)<2)
System.out.println(strings.number.toString()+' '+strings+' '+strings.toMyString());
} catch(Exception e) {
System.out.println(""+i+' '+strings+" failed!");
}
}
final int digits,radix;
BigInteger number;
}
Я создал бы символьный массив и увеличил бы символы индивидуально. Строки неизменны в Java, таким образом, каждое изменение создало бы новое место на "куче", приводящей к росту памяти и росту.
С символьным массивом, у Вас не должно быть той проблемы...
Я должен был бы согласиться с подходом @saua, если бы Вы только хотели конечный результат, но здесь являетесь небольшой вариацией на него в случае, Вы хотите каждый результат.
Примечание, что, так как существует 26^8 (или 208827064576) различные возможные строки, я сомневаюсь, что Вы хотите их всех. Тем не менее мой код печатает их вместо того, чтобы хранить только один в Строковом Разработчике. (Не то, чтобы это действительно имеет значение, все же.)
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);
}
Имейте массив байта, которые содержат значения ASCII и имеют цикл, который увеличивает крайнюю правую цифру, в то время как выполнение несет верхние мячи.
Затем создают строку с помощью
public String(byte[] bytes, String charsetName)
, Удостоверяются, что Вы передаете в наборе символов как US-ASCII или UTF-8, чтобы быть однозначными.
Просто подробно останавливание на примерах, относительно Реализации, рассматривает помещение этого в Класс... Каждый раз, когда Вы называете toString Класса, он возвратил бы следующее значение:
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();
}
}
Следующий код использует рекурсивный метод для получения следующей строки (скажем, от "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;
}
}