2014-06-20 15 views
7

Sto scrivendo una serie di test per un risolutore Palindrome. Mi sono imbattuto il palindromo interessante in ebraico:Come posso rilevare un palindromo in ebraico?

טעם לפת תפל מעט

Che è un palindromo, ma la lettera Mem ha sia una forma regolare (מ) e una "forma finale" (ם), come appare come l'ultima lettera in una parola. Ma a parte l'hardcoding che "0x5de => 0x5dd" nel mio programma, non ero in grado di capire un modo per fare affidamento su Unicode, Python o una libreria che avrebbe trattato i due come lo stesso. Le cose che ho provato:

Tutte hanno restituito la stessa stringa. Altre lettere ebraiche che causerebbero questo problema (nel caso in cui qualcuno lo cerchi più tardi) sarebbero Kaf, Nun, Peh e Tsadeh. No, non sono un madrelingua dell'ebraico.

+0

Queste sono le sole 5 lettere che avrebbero questo problema? – Dannnno

+0

Perché stai facendo questo? Sono solo curioso –

+0

Sono un istruttore di programmazione, cercando di fare un esercizio che ha una soluzione semplice (è una parola un palindromo?), Una soluzione intermedia (è questa frase inglese un palindromo?), E una soluzione impegnativa (è questo insieme arbitrario di "lettere" un palindromo?). – heptadecagram

risposta

1

Ecco una soluzione brutta che funziona per il tuo problema attuale:

import unicodedata 

def make_map(ss): 
    return [unicodedata.name(s).split(' ')[-1] for s in ss] 

def is_palindrome(ss): 
    return make_map(ss) == make_map(reversed(ss)) 

Questa si basa sulla formattazione dei nomi dei personaggi ebraici nella tabella di ricerca di Python, però, quindi potrebbe non generalizzare perfettamente.

In particolare, si dispone:

In [29]: unicodedata.name(s[2]) 
Out[29]: 'HEBREW LETTER FINAL MEM' 
... 
In [31]: unicodedata.name(s[-3]) 
Out[31]: 'HEBREW LETTER MEM' 

Quindi, escludendo tutti, ma l'ultima parola ti dà:

In [35]: [unicodedata.name(s_).split(" ")[-1] for s_ in s] 
Out[35]: ['TET', 'AYIN', 'MEM', 'SPACE', 'LAMED', 'PE', 'TAV', 'SPACE', 'TAV', 'PE', 'LAMED', 'SPACE', 'MEM', 'AYIN', 'TET'] 

con lo stesso in senso inverso. Unicode è un grande mondo, quindi, quindi non sono sicuro che non sia possibile costruire un esempio che lo superi.

+0

Questo è un approccio interessante, ma non riuscirà sulle lettere con gli accenti, considerandoli tutti uguali: "alfabeto latino A CON GRAVE", "alfabeto latino E CON GRAVE". – heptadecagram

+0

In questo caso, potresti ignorare "FINAL", che è l'unica differenza nei nomi dei caratteri ... –

+0

@heptadecagram Penso che sia probabile che tu possa sempre trovare qualche carattere Unicode con un nome strano che rompa un particolare approccio. Ci sono [molti caratteri Unicode] (http://www.unicode.org/Public/6.3.0/ucd/NamesList.txt), e se devi gestire tutto da "CEDILLA" a "DUE PUNTI A DESTRA MARCHIO DI QUOTAZIONE "a" VULGAR FRAZIONE TRE QUARTI "a" LATINA PICCOLA LETTERA O CON OGONEK E MACRON "a" PERSONA DESK "a .... ecc. Penso che tu sia SOL. –

2

si può fare una risposta un po 'più "rigorosa" (uno che è meno probabile che dare falsi positivi e falsi negativi), con un po' più di lavoro. Nota che la risposta di Patrick Collin potrebbe fallire abbinando molti personaggi non correlati perché condividono l'ultima parola nel loro nome dati unicode.

Una cosa che puoi fare è un approccio più rigoroso a convertire lettere finali:

import unicodedata 

# Note the added accents 
phrase = 'טעם̀ לפת תפל מ̀עט' 

def convert_final_characters(phrase): 
    for character in phrase: 
     try: 
      name = unicodedata.name(character) 
     except ValueError: 
      yield character 
      continue 

     if "HEBREW" in name and " FINAL" in name: 
      try: 
       yield unicodedata.lookup(name.replace(" FINAL", "")) 
      except KeyError: 
       # Fails for HEBREW LETTER WIDE FINAL MEM "ﬦ", 
       # which has no non-final counterpart 
       # 
       # No failure if you first normalize to 
       # HEBREW LETTER FINAL MEM "ם" 
       yield character 
     else: 
      yield character 

phrase = "".join(convert_final_characters(phrase)) 
phrase 
#>>> 'טעמ̀ לפת תפל מ̀עט' 

questo sembra solo per i caratteri ebraici dove "FINALE" possono essere rimossi, e lo fa.


È quindi possibile convertire anche grafemi utilizzando the "new" regex module on PyPI.

import regex 

# "\X" matches graphemes 
graphemes = regex.findall("\X", phrase) 
graphemes 
#>>> ['ט', 'ע', 'מ̀', ' ', 'ל', 'פ', 'ת', ' ', 'ת', 'פ', 'ל', ' ', 'מ̀', 'ע', 'ט'] 

graphemes == graphemes[::-1] 
#>>> True 

Questo tratta di accenti e altri caratteri combinati.

Problemi correlati