Regex per calcolare la mano di poker diretta - Utilizzando il CODICE ASCII

StackOverflow https://stackoverflow.com/questions/3482151

  •  28-09-2019
  •  | 
  •  

Domanda

In un'altra domanda ho imparato come calcolare la mano di poker diretta usando regex (Qui).

Ora, per curiosità, la domanda è: posso usare regex per calcolare la stessa cosa, usando il CODICE ASCII?

Qualcosa di simile a:

espressione regolare:[C][C+1][C+2][C+3][C+4], essendo C il CODICE ASCII (o simile)

Partite: 45678, 23456

Non corrisponde: 45679 O 23459 (non in sequenza)

È stato utile?

Soluzione 4

RISOLTO!

http://jsfiddle.net/g48K9/3

ho risolto utilizzando la chiusura, in js.

String.prototype.isSequence = function () {
    If (this == "A2345") return true; // an exception
    return this.replace(/(\w)(\w)(\w)(\w)(\w)/, function (a, g1, g2, g3, g4, g5) {
        return    code(g1) == code(g2) -1 &&
                code(g2) == code(g3) -1 &&
                code(g3) == code(g4) -1 &&
                code(g4) == code(g5) -1;
    })
};

function code(card){
    switch(card){
        case "T": return 58;
        case "J": return 59;
        case "Q": return 60;
        case "K": return 61;
        case "A": return 62;
        default: return card.charCodeAt();
    }
}


test("23456");
test("23444");
test("789TJ");
test("TJQKA");
test("8JQKA");

function test(cards) {
    alert("cards " + cards + ": " + cards.isSequence())
}

Giusto per chiarire, codici ASCII:

codici ASCII:

2 = 50
3 = 51
4 = 52
5 = 53
6 = 54
7 = 55
8 = 56
9 = 57
T = 84 -> 58
J = 74 -> 59
Q = 81 -> 60
K = 75 -> 61
A = 65 -> 62

Altri suggerimenti

Il tuo problema principale sarà in realtà che non stai utilizzando codifiche ASCII consecutive per le tue mani, stai utilizzando numeri per le carte senza figure e caratteri non consecutivi e non ordinati per le carte con figure.

È necessario rilevare, all'inizio delle stringhe, 2345A, 23456, 34567, ..., 6789T, 789TJ, 89TJQ, 9TJQK E TJQKA.

Questi sono non codici ASCII consecutivi e, anche se lo fossero, incontreresti problemi poiché entrambi A2345 E TJQKA sono validi e non otterrai A essendo sia minore che maggiore degli altri caratteri nello stesso set di caratteri.

Se lo ha essere eseguito da una regex, quindi il seguente segmento regex:

(2345A|23456|34567|45678|56789|6789T|789TJ|89TJQ|9TJQK|TJQKA)

è probabilmente il più semplice e leggibile che otterrai.

Non c'è regex che farà quello che vuoi come le altre risposte hanno sottolineato, ma hai detto che vuoi imparare regex, quindi ecco un altro approccio meta-regex che può essere istruttivo .

Ecco un frammento Java che, data una stringa, programmaticamente generare il pattern che adattarsi a qualsiasi stringa di quella stringa di lunghezza 5.

    String seq = "ABCDEFGHIJKLMNOP";
    System.out.printf("^(%s)$",
        seq.replaceAll(
            "(?=(.{5}).).",
            "$1|"
        )
    );

L'uscita è ( come visto in ideone.com ):

^(ABCDE|BCDEF|CDEFG|DEFGH|EFGHI|FGHIJ|GHIJK|HIJKL|IJKLM|JKLMN|KLMNO|LMNOP)$

È possibile utilizzare questo per generare comodamente il modello di espressione regolare per abbinare mani di poker rettilinei, inizializzando seq a seconda dei casi.


Come funziona

. metacarattere href="http://www.regular-expressions.info/dot.html" rel="nofollow noreferrer"> corrisponde "qualsiasi" carattere (separatori di linea può essere un'eccezione a seconda sulla modalità siamo in).

Il {5} è un esatto ripetizione identificatore. partite .{5} esattamente 5 ..

(?=…) IS href="http://www.regular-expressions.info/lookaround.html" rel="nofollow noreferrer"> positivo lookahead ; afferma che un dato modello può essere abbinato, ma poiché è solo un'affermazione, in realtà non fa (cioè consumano) partita dalla stringa di input.

Semplicemente (…) è un cattura gruppo. Esso crea un backreference che è possibile utilizzare forse più tardi nel modello, o in sostituzione, o comunque si vede in forma.

Lo schema si ripete qui per comodità:

     match one char
        at a time
           |
(?=(.{5}).).
\_________/
 must be able to see 6 chars ahead
 (capture the first 5)

Il modello funziona corrispondenza uno . carattere alla volta. Prima di quel personaggio è abbinato, però, affermare (?=…) che possiamo vedere un totale di 6 personaggi a venire (.{5})., catturando (…) nel gruppo 1, la prima .{5}. Per ognuna di queste partite, sostituiamo con $1|, che è, ciò che è stato catturato dal gruppo 1, seguito dal metacarattere alternanza.

Consideriamo che cosa accade quando si applica ad un String seq = "ABCDEFG"; più breve. Il denota la nostra posizione corrente.

=== INPUT ===                                    === OUTPUT ===

 A B C D E F G                                   ABCDE|BCDEFG
↑
We can assert (?=(.{5}).), matching ABCDEF
in the lookahead. ABCDE is captured.
We now match A, and replace with ABCDE|

 A B C D E F G                                   ABCDE|BCDEF|CDEFG
  ↑
We can assert (?=(.{5}).), matching BCDEFG
in the lookahead. BCDEF is captured.
We now match B, and replace with BCDEF|

 A B C D E F G                                   ABCDE|BCDEF|CDEFG
    ↑
Can't assert (?=(.{5}).), skip forward

 A B C D E F G                                   ABCDE|BCDEF|CDEFG
      ↑
Can't assert (?=(.{5}).), skip forward

 A B C D E F G                                   ABCDE|BCDEF|CDEFG
        ↑
Can't assert (?=(.{5}).), skip forward

       :
       :

 A B C D E F G                                   ABCDE|BCDEF|CDEFG
              ↑
Can't assert (?=(.{5}).), and we are at
the end of the string, so we're done.

Così otteniamo ABCDE|BCDEF|CDEFG, che sono tutte le stringhe di lunghezza 5 di seq.

Bibliografia

  

Qualcosa come regex: [C][C+1][C+2][C+3][C+4], essendo C il codice ASCII (o come questo)

Non si può fare qualcosa di anche lontanamente vicino a questo nella maggior parte dei sapori regex. Questo non è semplicemente il tipo di modelli che regex è stato progettato per.

Non c'è regex tradizionale che succintly nessun due caratteri consecutivi che differiscono da x nel loro codifica ASCII.


Per scopi didattici ...

Qui si va ( Vedi anche su ideone.com ):

    String alpha = "ABCDEFGHIJKLMN";
    String p = alpha.replaceAll(".(?=(.))", "$0(?=$1|\\$)|") + "$";

    System.out.println(p);
    // A(?=B|$)|B(?=C|$)|C(?=D|$)|D(?=E|$)|E(?=F|$)|F(?=G|$)|G(?=H|$)|
    // H(?=I|$)|I(?=J|$)|J(?=K|$)|K(?=L|$)|L(?=M|$)|M(?=N|$)|N$

    String p5 = String.format("(?:%s){5}", p);

    String[] tests = {
        "ABCDE",    // true
        "JKLMN",    // true
        "AAAAA",    // false
        "ABCDEFGH", // false
        "ABCD",     // false
        "ACEGI",    // false
        "FGHIJ",    // true
    };
    for (String test : tests) {
        System.out.printf("[%s] : %s%n",
            test,
            test.matches(p5)
        );
    }

Questo utilizza la tecnica meta-regexing per generare un modello. Che assicura modello che ogni carattere è seguito dal carattere destra (o la fine della stringa), utilizzando lookahead . Questo modello è quindi meta-regexed da abbinare più volte 5 volte.

È possibile sostituire alpha con la sequenza di poker, se necessario.

Si noti che si tratta di un ASSOLUTAMENTE impraticabile soluzione. E 'molto più leggibile per esempio basta controllare se alpha.contains(test) && (test.length() == 5).

Domande correlate

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top