Carácter más común en una cadena

Escriba una función que tome una cadena de caracteres alfabéticos como argumento de entrada y devuelva el carácter más común. Ignore los espacios en blanco, es decir, no cuente ningún espacio en blanco como un carácter. Tenga en cuenta que el uso de mayúsculas no importa aquí, es decir, que un carácter en minúscula es igual a un carácter en mayúscula. En caso de un empate entre ciertos personajes, se devuelve el último carácter que tenga más conteo.

Este es el código actualizado.

def most_common_character (input_str): input_str = input_str.lower() new_string = "".join(input_str.split()) print(new_string) length = len(new_string) print(length) count = 1 j = 0 higher_count = 0 return_character = "" for i in range(0, len(new_string)): character = new_string[i] while (length - 1): if (character == new_string[j + 1]): count += 1 j += 1 length -= 1 if (higher_count < count): higher_count = count return (character) #Main Program input_str = input("Enter a string: ") result = most_common_character(input_str) print(result) 

Lo anterior es mi código. Recibo un error de string index out of bound de string index out of bound cual no entiendo por qué. ¿También el código solo verifica la aparición del primer carácter? ¿Estoy confundido acerca de cómo proceder al siguiente carácter y tomar la cuenta máxima?

El error que recibo cuando ejecuto mi código:

 > Your answer is NOT CORRECT Your code was tested with different inputs. > For example when your function is called as shown below: > > most_common_character ('The cosmos is infinite') > > ############# Your function returns ############# e The returned variable type is: type 'str' > > ######### Correct return value should be ######## i The returned variable type is: type 'str' > > ####### Output of student print statements ###### thecosmosisinfinite 19 

En realidad su código es casi correcto. for i in range(0, len(new_string)) mover el count , j , length dentro de su for i in range(0, len(new_string)) porque necesita comenzar de nuevo en cada iteración y también si el count es mayor que el higher_count de higher_count , debe guardar ese carácter como return_character y devuélvalo en lugar del character que siempre es el último carácter de su cadena debido a character = new_string[i] .

No veo por qué has usado j+1 y while length-1 . Después de corregirlos, ahora cubre situaciones de empate también.

 def most_common_character (input_str): input_str = input_str.lower() new_string = "".join(input_str.split()) higher_count = 0 return_character = "" for i in range(0, len(new_string)): count = 0 length = len(new_string) j = 0 character = new_string[i] while length > 0: if (character == new_string[j]): count += 1 j += 1 length -= 1 if (higher_count <= count): higher_count = count return_character = character return (return_character) 

Puede utilizar un patrón de expresiones regulares para buscar todos los caracteres. \w coincide con cualquier carácter alfanumérico y el subrayado; esto es equivalente al conjunto [a-zA-Z0-9_] . El + después de [\w] significa hacer coincidir una o más repeticiones.

Finalmente, usa Counter para most_common(1) y most_common(1) para obtener el valor máximo. Vea abajo para el caso de un empate.

 from collections import Counter import re s = "Write a function that takes a string consisting of alphabetic characters as input argument and returns the most common character. Ignore white spaces ie Do not count any white space as a character. Note that capitalization does not matter here ie that a lower case character is equal to a upper case character. In case of a tie between certain characters return the last character that has the most count" >>> Counter(c.lower() for c in re.findall(r"\w", s)).most_common(1) [('t', 46)] 

En el caso de un empate, es un poco más complicado.

 def top_character(some_string): joined_characters = [c for c in re.findall(r"\w+", some_string.lower())] d = Counter(joined_characters) top_characters = [c for c, n in d.most_common() if n == max(d.values())] if len(top_characters) == 1: return top_characters[0] reversed_characters = joined_characters[::-1] for c in reversed_characters: if c in top_characters: return c >>> top_character(s) 't' >>> top_character('the the') 'e' 

En el caso de su código anterior y su frase “El cosmos es infinito”, puede ver que ‘i’ ocurre con más frecuencia que ‘e’ (la salida de su función):

 >>> Counter(c.lower() for c in "".join(re.findall(r"[\w]+", 'The cosmos is infinite'))).most_common(3) [('i', 4), ('s', 3), ('e', 2)] 

Puedes ver el problema en tu bloque de código:

 for i in range(0, len(new_string)): character = new_string[i] ... return (character) 

Estás iterando a través de una oración y asigna esa letra al carácter variable, que nunca se reasigna a otro lugar. Por lo tanto, el character variable siempre devolverá el último carácter de la cadena.

Si ignoramos el requisito de “empate”; collections.Counter() obras:

 from collections import Counter from itertools import chain def most_common_character(input_str): return Counter(chain(*input_str.casefold().split())).most_common(1)[0][0] 

Ejemplo:

 >>> most_common_character('The cosmos is infinite') 'i' >>> most_common_character('ab' * 3) 'a' 

Para devolver el último carácter que tenga la mayor cantidad de recuentos, podríamos usar collections.OrderedDict :

 from collections import Counter, OrderedDict from itertools import chain from operator import itemgetter class OrderedCounter(Counter, OrderedDict): pass def most_common_character(input_str): counter = OrderedCounter(chain(*input_str.casefold().split())) return max(reversed(counter.items()), key=itemgetter(1))[0] 

Ejemplo:

 >>> most_common_character('ab' * 3) 'b' 

Nota: esta solución asume que max() devuelve el primer carácter que tiene la mayor cantidad de recuento (y, por lo tanto, hay una llamada reversed() para obtener el último) y todos los caracteres son puntos de código únicos de Unicode. En general, es posible que desee utilizar \X expresión regular (compatible con el módulo regex ), para extraer “caracteres percibidos por el usuario” ( clúster de grafemas extendidos ) de la cadena Unicode.