Encuentre la palabra más larga del diccionario según las letras ofrecidas C#

programación


Hola a todos, por favor y necesito su ayuda.
Tengo tres cuadros de texto en el formulario de Windows:
– En tetxBox1.Text hay un diccionario con muchas palabras (las palabras más largas
tiene 12 letras)
– Siempre se ofrecen 12 letras en textBox2.Text
– En textBox3.Text, quiero que el resultado sea la palabra más larga de textBox1.
compuesto por cartas ofrecidas de textBox2

Por ejemplo:

En textBox1.Text tengo las siguientes palabras:

characters
character
charity
act
acter
acted
successfully
wind
succession
windy
successful
window
windows
success
excellent
excel
excellence
excellency

En textBox2.Text tengo las siguientes 12 letras ofrecidas:

euclsfcysuls

En textBox3.Text quiero como resultado la palabra más larga de textBox1.Text que las letras de textBox2.Text:

exitosamente

Les pido ayuda si es posible, alguna solución…
Espero que me hayas entendido, pido disculpas por mi inglés si no lo entendiste.
Gracias a todos de antemano.

https://i.postimg.cc/HnS59c2R/Capture.png[^]

Lo que he probado:

C#
static bool isSubSequence(String str1,
                                String str2)
        {
            int m = str1.Length, n = str2.Length;

            int j = 0; 

            for (int i = 0; i < n && j < m; i++)
            {
                if (str1[j] == str2[i])
                {
                    j++;
                }
            }
            return (j == m);
        }


static String findLongestString(List<String> dict,
                                            String str)
        {
            String result = "";
            int length = 0;
            foreach (String word in dict)
            {
                if (length < word.Length &&
                    isSubSequence(word, str))
                {
                    result = word;
                    length = word.Length;
                }
            }

            return result;
        }

private void btnfind_Click(object sender, EventArgs e)
        {
            String[] arr = textBox1.Lines;
            List<String> dict = new List<String>(arr);
            String str = textBox2.Text;
            textBox3.Text = (findLongestString(dict, str));
        }

Solución 1

Piensa en la tarea en lugar de en la solución: necesitas encontrar el conjunto más largo de palabras coincidentes que tengan letras en común. Así que empieza por hacer dos cosas: construye un mapa de caracteres (sólo hay 26 posibilidades, de la ‘A’ a la ‘Z’ inclusive) y cuéntalas tanto para tus “letras de verificación” como para tus palabras individuales.
Entonces su ejemplo “euclsfcysuls” se asigna a:

A 0
B 0
C 2
D 0
E 1
F 1
G 0
H 0
I 0
J 0
K 0
L 2
M 0
N 0
O 0
P 0
Q 0
R 0
S 3
T 0
U 2
V 0
W 0
X 0
Y 1
Z 0

Eso es trivial: pasar una sola palabra por una palabra contando las letras. Escriba un método para hacerlo y pruébelo a fondo.

Ahora es un problema más fácil: para cada palabra a verificar, encuentre cuántas coinciden comparando el número de letras: si la “palabra posible” tiene un número de letras mayor que la misma letra de la “palabra de verificación”, no es una coincidencia.

A medida que avanza, mantenga una palabra “más larga hasta ahora” y, cuando encuentre una posible coincidencia, compárela con la palabra “más larga hasta ahora” y actualícela según sea necesario.

Al final, tienes el partido más largo posible.

Solución 2

Mi sugerencia sería agrupar todas las letras de la cadena de destino en una colección de tuplas donde cada tupla contenga tanto una letra como el recuento del número total de apariciones de esa letra. Existe un método linq que puede hacer esto.

C#
string target = "euclsfcysuls";
//group all the letters into a collection of tuples char key and key count
IEnumerable<(char Key, int count)> resultCollection = target.GroupBy(c => c).Select(g => (g.Key, g.Count()));

Itere sobre la colección y agregue cada clave y número de letras a un diccionario. Ahora, para cada cadena en la colección de prueba, agrupe las letras de la misma manera que antes, pero esta vez repita los grupos de cadenas de prueba. No hay coincidencia si la letra clave no está presente en el diccionario de destino o si hay más repeticiones de una letra que en la cadena de destino. El código relevante es algo así.

C#
bool isSuccessful = true;
foreach (var (key, count) in testCollection)
{
    //there is no match if the key char is not present in the target dict or
    //there are more repetitions of a letter  than in the target string
    if (targetDict.ContainsKey(key) is false || targetDict[key] < count)
    {
        isSuccessful = false;
        break;
    }
}
if (isSuccessful)
{
    matchedList.Add(testString);
}

Ahora todas las coincidencias exitosas están en la lista de coincidencias. Ordene la lista por la longitud de las cadenas en orden descendente. El ganador es la primera entrada de la lista.

コメント

タイトルとURLをコピーしました