una switch reemplazar numero matriz llenar letras letra generar expresión convertir con como caracteres aleatorias java collections sequence guava alphabetical

switch - Generando una secuencia alfabética en Java



reemplazar caracteres en java (15)

Estoy buscando una manera de generar una secuencia alfabética:

A, B, C, ..., Z, AA, AB, AC, ..., ZZ.

¿Alguien puede sugerir una manera conveniente de hacer esto? ¿Qué estructuras de datos puedo utilizar?

Me gustaría los métodos que obtienen el siguiente código en la secuencia y luego restablecen la secuencia.


¿Por qué no crear la secuencia recursivamente?

Ejemplo (no probado):

public String createSequenceElement(int index) { String sequenceElement = ""; int first = index / 26; int second = index % 26; if (first < 1) { sequenceElement += (char) (''A'' + second); } else { sequenceElement += createSequenceElement(first) + (char) (''A'' + second); } return sequenceElement ; } public static void main(String[] args) { String sequence = ""; for (int i = 0; i < 100; i++) { if (i > 0) { sequence += ", "; } sequence += createSequenceElement(i); } System.out.println(sequence); }


Curiosamente, nadie ha proporcionado todavía una solución funcional basada en Java 8. Aquí hay una solución que utiliza jOOλ , que proporciona una funcionalidad como range() para los caracteres, foldLeft() y crossJoin() (descargo de responsabilidad, trabajo para la empresa que mantiene jOOλ):

int max = 3; List<String> alphabet = Seq .rangeClosed(''A'', ''Z'') .map(Object::toString) .toList(); Seq.rangeClosed(1, max) .flatMap(length -> Seq.rangeClosed(1, length - 1) .foldLeft(Seq.seq(alphabet), (s, i) -> s.crossJoin(Seq.seq(alphabet)) .map(t -> t.v1 + t.v2))) .forEach(System.out::println);

Esta solución no es realmente rápida ( por ejemplo, como esta ). Acabo de agregarlo para completar la información.


Estaba probando pero, el código es malo ...

Hice mi código, que funciona hasta 256 , pero puedes cambiarlo según las necesidades.

public static String IntToLetter(int Int) { if (Int<27){ return Character.toString((char)(Int+96)); } else { if (Int%26==0) { return IntToLetter((Int/26)-1)+IntToLetter((Int%26)+1); } else { return IntToLetter(Int/26)+IntToLetter(Int%26); } } }

EDITADO (método fijo):

public static String IntToLetter(int Int) { if (Int<27){ return Character.toString((char)(Int+96)); } else { if (Int%26==0) { return IntToLetter((Int/26)-1)+IntToLetter(((Int-1)%26+1)); } else { return IntToLetter(Int/26)+IntToLetter(Int%26); } } }

Probando mi código:

for (int i = 1;i<256;i++) { System.out.println("i="+i+" -> "+IntToLetter(i)); }

El resultado

i=1 -> a i=2 -> b i=3 -> c i=4 -> d i=5 -> e i=6 -> f i=7 -> g i=8 -> h i=9 -> i i=10 -> j i=11 -> k i=12 -> l i=13 -> m i=14 -> n i=15 -> o i=16 -> p i=17 -> q i=18 -> r i=19 -> s i=20 -> t i=21 -> u i=22 -> v i=23 -> w i=24 -> x i=25 -> y i=26 -> z i=27 -> aa i=28 -> ab i=29 -> ac i=30 -> ad i=31 -> ae i=32 -> af i=33 -> ag i=34 -> ah i=35 -> ai i=36 -> aj i=37 -> ak i=38 -> al i=39 -> am i=40 -> an i=41 -> ao i=42 -> ap i=43 -> aq i=44 -> ar i=45 -> as i=46 -> at i=47 -> au i=48 -> av i=49 -> aw i=50 -> ax i=51 -> ay i=52 -> az i=53 -> ba i=54 -> bb i=55 -> bc i=56 -> bd i=57 -> be i=58 -> bf i=59 -> bg i=60 -> bh i=61 -> bi i=62 -> bj i=63 -> bk i=64 -> bl i=65 -> bm i=66 -> bn i=67 -> bo i=68 -> bp i=69 -> bq i=70 -> br i=71 -> bs i=72 -> bt i=73 -> bu i=74 -> bv i=75 -> bw i=76 -> bx i=77 -> by i=78 -> bz i=79 -> ca i=80 -> cb i=81 -> cc i=82 -> cd i=83 -> ce i=84 -> cf i=85 -> cg i=86 -> ch i=87 -> ci i=88 -> cj i=89 -> ck i=90 -> cl i=91 -> cm i=92 -> cn i=93 -> co i=94 -> cp i=95 -> cq i=96 -> cr i=97 -> cs i=98 -> ct i=99 -> cu i=100 -> cv i=101 -> cw i=102 -> cx i=103 -> cy i=104 -> cz i=105 -> da i=106 -> db i=107 -> dc i=108 -> dd i=109 -> de i=110 -> df i=111 -> dg i=112 -> dh i=113 -> di i=114 -> dj i=115 -> dk i=116 -> dl i=117 -> dm i=118 -> dn i=119 -> do i=120 -> dp i=121 -> dq i=122 -> dr i=123 -> ds i=124 -> dt i=125 -> du i=126 -> dv i=127 -> dw i=128 -> dx i=129 -> dy i=130 -> dz i=131 -> ea i=132 -> eb i=133 -> ec i=134 -> ed i=135 -> ee i=136 -> ef i=137 -> eg i=138 -> eh i=139 -> ei i=140 -> ej i=141 -> ek i=142 -> el i=143 -> em i=144 -> en i=145 -> eo i=146 -> ep i=147 -> eq i=148 -> er i=149 -> es i=150 -> et i=151 -> eu i=152 -> ev i=153 -> ew i=154 -> ex i=155 -> ey i=156 -> ez i=157 -> fa i=158 -> fb i=159 -> fc i=160 -> fd i=161 -> fe i=162 -> ff i=163 -> fg i=164 -> fh i=165 -> fi i=166 -> fj i=167 -> fk i=168 -> fl i=169 -> fm i=170 -> fn i=171 -> fo i=172 -> fp i=173 -> fq i=174 -> fr i=175 -> fs i=176 -> ft i=177 -> fu i=178 -> fv i=179 -> fw i=180 -> fx i=181 -> fy i=182 -> fz i=183 -> ga i=184 -> gb i=185 -> gc i=186 -> gd i=187 -> ge i=188 -> gf i=189 -> gg i=190 -> gh i=191 -> gi i=192 -> gj i=193 -> gk i=194 -> gl i=195 -> gm i=196 -> gn i=197 -> go i=198 -> gp i=199 -> gq i=200 -> gr i=201 -> gs i=202 -> gt i=203 -> gu i=204 -> gv i=205 -> gw i=206 -> gx i=207 -> gy i=208 -> gz i=209 -> ha i=210 -> hb i=211 -> hc i=212 -> hd i=213 -> he i=214 -> hf i=215 -> hg i=216 -> hh i=217 -> hi i=218 -> hj i=219 -> hk i=220 -> hl i=221 -> hm i=222 -> hn i=223 -> ho i=224 -> hp i=225 -> hq i=226 -> hr i=227 -> hs i=228 -> ht i=229 -> hu i=230 -> hv i=231 -> hw i=232 -> hx i=233 -> hy i=234 -> hz i=235 -> ia i=236 -> ib i=237 -> ic i=238 -> id i=239 -> ie i=240 -> if i=241 -> ig i=242 -> ih i=243 -> ii i=244 -> ij i=245 -> ik i=246 -> il i=247 -> im i=248 -> in i=249 -> io i=250 -> ip i=251 -> iq i=252 -> ir i=253 -> is i=254 -> it i=255 -> iu

Atentamente


Este método genera secuencia de caracteres alfa.

Si se llama con nulo, devuelve A. Cuando se llama con A, devuelve B.

La secuencia es como A, B, C ...... Z, AA, AB, AC ..... AZ, BA, BB, BC .... BZ, CA, CB, CC .... CZ , DA ...... ZA, ZB .... ZZ, AAA, AAB, AAC .... AAZ, ABA, ABB ... AZZ, BAA, BAB .... ZZZ

/** * @param charSeqStr * @return */ public static String getNextAlphaCharSequence(String charSeqStr) { String nextCharSeqStr = null; char[] charSeqArr = null; boolean isResetAllChar = false; boolean isResetAfterIndex = false; Integer resetAfterIndex = 0; if (StringUtils.isBlank(charSeqStr)) { charSeqArr = new char[] { ''A'' }; } else { charSeqArr = charSeqStr.toCharArray(); Integer charSeqLen = charSeqArr.length; for (int index = charSeqLen - 1; index >= 0; index--) { char charAtIndex = charSeqArr[index]; if (Character.getNumericValue(charAtIndex) % 35 == 0) { if (index == 0) { charSeqArr = Arrays.copyOf(charSeqArr, charSeqLen + 1); isResetAllChar = true; } else { continue; } } else { char nextCharAtIndex = (char) (charAtIndex + 1); charSeqArr[index] = nextCharAtIndex; if (index + 1 < charSeqLen) { isResetAfterIndex = true; resetAfterIndex = index; } break; } } charSeqLen = charSeqArr.length; if (isResetAllChar) { for (int index = 0; index < charSeqLen; index++) { charSeqArr[index] = ''A''; } } else if (isResetAfterIndex) { for (int index = resetAfterIndex + 1; index < charSeqLen; index++) { charSeqArr[index] = ''A''; } } } nextCharSeqStr = String.valueOf(charSeqArr); return nextCharSeqStr; } public static void main(String args[]) { String nextAlphaSequence = null; for (int index = 0; index < 1000; index++) { nextAlphaSequence = getNextAlphaCharSequence(nextAlphaSequence); System.out.print(nextAlphaSequence + ","); } }


Esto creará la secuencia para el valor pasado.

/** * Method that returns batch names based on passed value * @param batchCount * @return String[] */ public static String[] getBatchNamesForExecutor(int batchCount) { // Batch names array String[] batchNames = new String[batchCount]; // Loop from 0 to batchCount required for(int index=0; index < batchCount; index++) { // Alphabet for current batch name int alphabet = index%26; // iteration count happened on all alphabets till now int iterations = index/26; // initializing array element to blank string batchNames[index] = ""; // Looping over the iterationIndex and creating batch alphabet prefix / prefixes for(int iterationIndex = 0; iterationIndex < iterations; iterationIndex+=26){ batchNames[index] += String.valueOf((char)(''A'' + (iterations-1) % 26 )); } // Adding last alphabet in batch name batchNames[index] += String.valueOf((char)(''A'' + alphabet % 26 )); } return batchNames; } public static void main(String[] args) { for(String s: getBatchNamesForExecutor(8)) { System.err.println(s); } System.exit(0); }


He creado una solución iterativa y recursiva a continuación. Encontrará un ejemplo siguiendo estas soluciones que muestra cómo generar un número n de elementos en una secuencia utilizando un iterador. Además, fui al golf de código con mi solución recursiva para la diversión.

Soluciones

Iterativo

public static String indexToColumnItr(int index, char[] alphabet) { if (index <= 0) throw new IndexOutOfBoundsException("index must be a positive number"); if (index <= alphabet.length) return Character.toString(alphabet[index - 1]); StringBuffer sb = new StringBuffer(); while (index > 0) { sb.insert(0, alphabet[--index % alphabet.length]); index /= alphabet.length; } return sb.toString(); }

Recursivo

public static String indexToColumnRec(int index, char[] alphabet) { if (index <= 0) throw new IndexOutOfBoundsException("index must be a positive number"); if (index <= alphabet.length) return Character.toString(alphabet[index - 1]); return indexToColumnRec(--index / alphabet.length, alphabet) + alphabet[index % alphabet.length]; }

Uso

public static final char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); indexToColumnItr(703, ALPHABET); // AAA

Ejemplo

El siguiente código produjo la siguiente secuencia de tamaño 52:

[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, AA, AB, AC, AD, AE, AF, AG, AH, AI, AJ, AK, AL, AM, AN, AO, AP, AQ, AR, AS, AT, AU, AV, AW, AX, AY, AZ]

Main.java

import java.util.Arrays; public class Main { public static void main(String[] args) { System.out.println(Arrays.toString(AlphaUtils.generateSequence(52))); } }

AlphaIterator.java

import java.util.Iterator; public class AlphaIterator implements Iterator<String> { private int maxIndex; private int index; private char[] alphabet; public AlphaIterator() { this(Integer.MAX_VALUE); } public AlphaIterator(int maxIndex) { this(maxIndex, "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()); } public AlphaIterator(char[] alphabet) { this(Integer.MAX_VALUE, alphabet); } public AlphaIterator(int maxIndex, char[] alphabet) { this.maxIndex = maxIndex; this.alphabet = alphabet; this.index = 1; } @Override public boolean hasNext() { return this.index < this.maxIndex; } @Override public String next() { return AlphaUtils.indexToColumnItr(this.index++, this.alphabet); } }

AlphaUtils.java

public class AlphaUtils { // Iterative public static String indexToColumnItr(int index, char[] alphabet) { if (index <= 0) throw new IndexOutOfBoundsException("index must be a positive number"); if (index <= alphabet.length) return Character.toString(alphabet[index - 1]); StringBuffer sb = new StringBuffer(); while (index > 0) { sb.insert(0, alphabet[--index % alphabet.length]); index /= alphabet.length; } return sb.toString(); } // Recursive public static String indexToColumnRec(int index, char[] alphabet) { if (index <= 0) throw new IndexOutOfBoundsException("index must be a positive number"); if (index <= alphabet.length) return Character.toString(alphabet[index - 1]); return indexToColumnRec(--index / alphabet.length, alphabet) + alphabet[index % alphabet.length]; } public static String[] generateSequence(int size) { String[] sequence = new String[size]; int i = 0; for (AlphaIterator it = new AlphaIterator(size); it.hasNext();) { sequence[i++] = it.next(); } return sequence; } }

Código Golf (89 bytes) :-)

String f(int i,char[]a){int l=a.length;return i<=0?"?":i<=l?""+a[i-1]:f(--i/l,a)+a[i%l];}


Mi versión implementa Iterator y mantiene un contador int. Los valores del contador se traducen a la cadena correspondiente:

import com.google.common.collect.AbstractIterator; class Sequence extends AbstractIterator<String> { private int now; private static char[] vs; static { vs = new char[''Z'' - ''A'' + 1]; for(char i=''A''; i<=''Z'';i++) vs[i - ''A''] = i; } private StringBuilder alpha(int i){ assert i > 0; char r = vs[--i % vs.length]; int n = i / vs.length; return n == 0 ? new StringBuilder().append(r) : alpha(n).append(r); } @Override protected String computeNext() { return alpha(++now).toString(); } }

Llame a next () en el iterador para usarlo.

Sequence sequence = new Sequence(); for(int i=0;i<100;i++){ System.out.print(sequence.next() + " "); }

ABCDEFGHIJKLMNOPQRSTU VWXYZ AA AB AC AD AE

Una implementación con mejor rendimiento para secuencias más grandes reutiliza el prefijo común:

class SequencePrefix extends AbstractIterator<String> { private int now = -1; private String prefix = ""; private static char[] vs; static { vs = new char[''Z'' - ''A'' + 1]; for(char i=''A''; i<=''Z'';i++) vs[i - ''A''] = i; } private String fixPrefix(String prefix){ if(prefix.length() == 0) return Character.toString(vs[0]); int last = prefix.length() - 1; char next = (char) (prefix.charAt(last) + 1); String sprefix = prefix.substring(0, last); return next - vs[0] == vs.length ? fixPrefix(sprefix) + vs[0] : sprefix + next; } @Override protected String computeNext() { if(++now == vs.length) prefix = fixPrefix(prefix); now %= vs.length; return new StringBuilder().append(prefix).append(vs[now]).toString(); } }

Obtendrá un rendimiento aún mejor si reescribe este algoritmo básico con una implementación que funcione con matrices. (String.charAt, String.substring y StringBuffer tienen cierta sobrecarga).


No estoy familiarizado con la programación funcional en Java, pero supongo que podría hacer algo equivalente a este código en Haskell:

- crear una lista ["A" .. "Z"]

uca = mapa (: []) [''A'' .. ''Z'']

- producto cartesiano de dos listas de cadenas, ++ concatena dos cadenas

cp lst1 lst2 =

[x ++ y | x <- lst1, y <- lst2]

- Lo siguiente da la lista requerida de cuerdas.

uca ++ cp uca uca


Solo porque me gusta el código corto ... inspirado por la respuesta de Thomas Jung :

static String asLetters(long value) { int codePoint = (int) (''A'' + --value % 26); long higher = value / 26; String letter = new String(Character.toChars(codePoint)); return higher == 0 ? letter : asLetters(higher).concat(letter); }

Comienza con 1 → a hasta Long.MAX_VALUECRPXNLSKVLJFHG . Use ''a'' lugar de ''A'' para las letras minúsculas.


Sugeriría un iterador que devuelva el siguiente valor.

El iterador debe poder crear la cadena para devolver, según los contadores internos. Para tu ejemplo sería suficiente con dos contadores. Uno para el primer carácter de la cadena y otro para el segundo carácter.

Cada contador podría corresponder al índice en " ABCDEFGHIJKLMNOPQRSTUVWXYZ" . Cuando haya devuelto una cadena, actualice el contador de la última posición. Si cae "sobre el borde", reinícielo para que apunte a "A" e incremente el siguiente contador. Cuando ese contador llegue a lo grande, deje que el iterador indique que no hay más elementos o reinícielo para que apunte a "" según lo que necesite.

Tenga en cuenta que al tener la primera posición en blanco, puede usar trim() en la cadena para deshacerse de los espacios que den "A" para la primera respuesta.


Una función recursiva de una línea para generar la cadena a partir de un entero:

static String str(int i) { return i < 0 ? "" : str((i / 26) - 1) + (char)(65 + i % 26); }

Ejemplo de uso:

public static void main(String[] args) { for (int i = 0; i < 27*27; ++i) { System.out.println(i + " -> " + str(i)); } }

Salida:

0 -> A 1 -> B 2 -> C [...] 24 -> Y 25 -> Z 26 -> AA 27 -> AB [...] 700 -> ZY 701 -> ZZ 702 -> AAA 703 -> AAB [...] 727 -> AAZ 728 -> ABA


tomar ''A''to''Z'' como 26radix. Ejemplo (C ++)

vector<string> generateSequenceBySize(int N) { if(N<1) return vector<string>(); int base = 26; vector<string> seqs; for(int i=0;i<pow(base,N);i++) { int value = i; string tmp(N,''A''); for (int j=0;j<N;j++) { tmp[N-1-j] = ''A''+value%base; value = value/base; } seqs.push_back(tmp); } return seqs; } vector<string> generateSequence() { //http://.com/questions/8710719/generating-an-alphabetic-sequence-in-java //A, B, C, ..., Z, AA, AB, AC, ..., ZZ. vector<string> seqs; for (int i=1;i<=2;i++) { vector<string> subSeq = generateSequenceBySize(i); seqs.insert(seqs.end(),subSeq.begin(),subSeq.end()); } return seqs; }


Combiné las propiedades Hexavigesimal # Bijective base-26 y la numeración Bijective # Propiedades de los números bijective base-k para hacer esto:

import static java.lang.Math.*; private static String getString(int n) { char[] buf = new char[(int) floor(log(25 * (n + 1)) / log(26))]; for (int i = buf.length - 1; i >= 0; i--) { n--; buf[i] = (char) (''A'' + n % 26); n /= 26; } return new String(buf); }

Con la ayuda de Wolfram Alpha . Sin embargo, tal vez hubiera sido más simple usar la implementación en el primer enlace.


public class SeqGen { public static void main(String[] args) { //This is the configurable param int seqWidth = 3; Double charSetSize = 26d; // The size of the array will be 26 ^ seqWidth. ie: if 2 chars wide, 26 // * 26. 3 chars, 26 * 26 * 26 Double total = Math.pow(charSetSize, (new Integer(seqWidth)).doubleValue()); StringBuilder[] sbArr = new StringBuilder[total.intValue()]; // Initializing the Array for(int j = 0; j <total; j++){ sbArr[j] = new StringBuilder(); } char ch = ''A''; // Iterating over the entire length for the ''char width'' number of times. // TODO: Can these iterations be reduced? for(int k = seqWidth; k >0; k--){ // Iterating and adding each char to the entire array. for(int l = 1; l <=total; l++){ sbArr[l-1].append(ch); if((l % (Math.pow(charSetSize, k-1d))) == 0){ ch++; if(ch > ''Z''){ ch = ''A''; } } } } //Use the stringbuilder array. for (StringBuilder builder : sbArr) { System.out.println(builder.toString()); } } }

Consulte el example y modifíquelo según sus requisitos.


char ch; String str1 = ""; String str2 = ""; for (ch = ''A''; ch <= ''Z''; ch++) { str1 += ch; for (int i = 0; i < 26; i++) { char upper = (char) (''A'' + i); str2 = str2 + ch + upper + " "; } } System.out.println(str1 + ", " + str2);