Necesito encontrar una secuencia en otra secuencia grande, por ejemplo, {1,3,2,3}
está presente en {1,3,2,3,4,3}
y {5,1,3,2,3}
. ¿Hay alguna forma de hacerlo rápidamente con IEnumerable
o con algo más?Encontrar una subsecuencia en la secuencia más larga
Respuesta
Puede probar algo como esto para comenzar. Una vez que haya convertido esta lista en una cadena, se puede encontrar la secuencia utilizando la subcadena:
if (String.Join(",", numericList.ConvertAll<string>(x => x.ToString()).ToArray())
{
//get sequence
}
Este método se encuentra una subsecuencia dentro de una secuencia original, de cualquier tipo que pueda ser comparado a través de Equals()
:
public static bool ContainsSubequence<T>(this IEnumerable<T> parent, IEnumerable<T> target)
{
bool foundOneMatch = false;
using (IEnumerator<T> parentEnum = parent.GetEnumerator())
{
using (IEnumerator<T> targetEnum = target.GetEnumerator())
{
// Get the first target instance; empty sequences are trivially contained
if (!targetEnum.MoveNext())
return true;
while (parentEnum.MoveNext())
{
if (targetEnum.Current.Equals(parentEnum.Current))
{
// Match, so move the target enum forward
foundOneMatch = true;
if (!targetEnum.MoveNext())
{
// We went through the entire target, so we have a match
return true;
}
}
else if (foundOneMatch)
{
return false;
}
}
return false;
}
}
}
se puede utilizar la siguiente manera:
bool match = new[] {1, 2, 3}.ContainsSubsequence(new[] {1, 2}); // match == true
match = new[] {1, 2, 3}.ContainsSubsequence(new[] {1, 3}); // match == false
Nota que asume la secuencia diana no tiene null
elementos.
actualización: Gracias por la upvotes, todo el mundo, pero en realidad hay un fallo en el código anterior! Si se encuentra una coincidencia parcial, pero luego no se convierte en una coincidencia completa, el proceso es finalizó, en lugar de restablecer (que obviamente está incorrecto cuando se aplica a algo como {1, 2, 1, 2, 3}.ContainsSubsequence({1, 2, 3})
).
El código anterior funciona muy bien para la definición más común de subsecuencia (es decir, contigüidad no es necesaria) pero para manejar el restablecimiento (que la mayoría IEnumerators
no admite) la secuencia objetivo debe enumerarse por adelantado. Esto nos lleva al siguiente código:
public static bool ContainsSubequence<T>(this IEnumerable<T> parent, IEnumerable<T> target)
{
bool foundOneMatch = false;
var enumeratedTarget = target.ToList();
int enumPos = 0;
using (IEnumerator<T> parentEnum = parent.GetEnumerator())
{
while (parentEnum.MoveNext())
{
if (enumeratedTarget[enumPos].Equals(parentEnum.Current))
{
// Match, so move the target enum forward
foundOneMatch = true;
if (enumPos == enumeratedTarget.Count - 1)
{
// We went through the entire target, so we have a match
return true;
}
enumPos++;
}
else if (foundOneMatch)
{
foundOneMatch = false;
enumPos = 0;
if (enumeratedTarget[enumPos].Equals(parentEnum.Current))
{
foundOneMatch = true;
enumPos++;
}
}
}
return false;
}
}
Este código no tiene virus, pero no va a funcionar bien para las grandes secuencias (o infinito).
¿Cometió un error en su ejemplo? ¿Cómo es 1, 3 una secuencia en 1, 2, 3? Ambos números existen, pero no en secuencia. Parece que su método determina si existen números, sin importar el orden o la secuencia. –
@James Como menciono al final, permite subsecuencias no contiguas (por ejemplo, '{1, 2, 3} .ContainsSubequence ({2, 1, 3}) == falso'.) Como también Mencione al final que esa condición se impone fácilmente, en caso de ser necesario. Por lo general, cuando se habla de subsecuencias, la contigüidad es * no * requerida (consulte, por ejemplo, el problema de subsecuencia común más largo). – dlev
No debe permitir las subsecuencias no contiguas. – user906763
similares a @ dlev, pero éste también se encarga de {1,1,1,2}.ContainsSubsequence({1,1,2})
public static bool ContainsSubsequence<T>(this IEnumerable<T> parent, IEnumerable<T> target)
{
var pattern = target.ToArray();
var source = new LinkedList<T>();
foreach (var element in parent)
{
source.AddLast(element);
if(source.Count == pattern.Length)
{
if(source.SequenceEqual(pattern))
return true;
source.RemoveFirst();
}
}
return false;
}
+1 Melikes the brevity, metakes, methanks ... –
Una sutileza importante en esta implementación es que solo enumera una vez sobre cada colección transferida, lo que hace que el método sea internamente coherente si se invoca con colecciones cuyo orden de enumeración no es determinista También tenga en cuenta que podría utilizarse una cola
Esto funciona para mí
var a1 = new List<int> { 1, 2, 3, 4, 5 };
var a2 = new List<int> { 2, 3, 4 };
int index = -1;
bool res = a2.All(
x => index != -1 ? (++index == a1.IndexOf(x)) : ((index = a1.IndexOf(x)) != -1)
);
Su solución parece ser la más elegante pero intente con 'a1 = new List
Esta función comprueba si la lista parent
contiene Lista target
el uso de algunos de LINQ:
public static bool ContainsSequence<T>(this List<T> parent, List<T> target)
{
for (int fromElement = parent.IndexOf(target.First());
(fromElement != -1) && (fromElement <= parent.Count - target.Count);
fromElement = parent.FindIndex(fromElement + 1, p => p.Equals(target.First())))
{
var comparedSequence = parent.Skip(fromElement).Take(target.Count);
if (comparedSequence.SequenceEqual(target)) return true;
}
return false;
}
Si está manejando serializables simples tipos, se puede hacer eso con bastante facilidad si convierte las matrices de cadena:
public static bool ContainsList<T>(this List<T> containingList, List<T> containedList)
{
string strContaining = "," + string.Join(",", containingList) + ",";
string strContained = "," + string.Join(",", containedList) + ",";
return strContaining.Contains(strContained);
}
Tenga en cuenta que es un método de extensión, por lo que serán capaces de llamar así:
if (bigList.ContainsList(smallList))
{
...
}
- 1. La subsecuencia más larga común
- 2. Encontrar la secuencia repetitiva más larga en una cadena
- 3. La subsecuencia común más larga para múltiples secuencias
- 4. Encuentra más larga secuencia
- 5. Diferencia de datos basada en SQL: subsecuencia común más larga
- 6. biblioteca de algoritmos de subsecuencia común más larga eficiente?
- 7. Algoritmo para encontrar lenth de secuencia más larga de espacios en blanco en una cadena dada
- 8. Encontrar la subsecuencia con la suma más grande de elementos en una matriz
- 9. Contando la ocurrencia más larga de secuencia repetida en Python
- 10. ¿Cómo encontrar la palabra más larga en la lista?
- 11. Explicar el algoritmo para resolver el problema de la 'subsecuencia creciente más larga'
- 12. ¿Cómo puedo encontrar la cadena más larga en Python?
- 13. subsecuencia más largo que el primero aumenta y luego disminuye
- 14. Cómo encontrar la subcadena común más larga usando C++
- 15. SQL: encontrar la brecha de fecha más larga
- 16. ¿Cómo encontrar la subcadena común más larga usando árboles?
- 17. ¿Cómo encontrar una subsecuencia creciente de números con suma máxima?
- 18. cómo encontrar la cadena más larga en una cadena [] usando LINQ
- 19. Encontrar el campo con la longitud más larga en una columna
- 20. ¿Cómo puedo encontrar la suma máxima de una subsecuencia usando la programación dinámica?
- 21. Ruta simple más larga
- 22. línea más larga en vim?
- 23. Encontrar la calle más cercana dada una ubicación de latitud larga
- 24. PHP más corta/cadena más larga en la gama
- 25. ¿Obtener una stacktrace más larga de FastMM?
- 26. Cadena más larga en numpy object_ array
- 27. Dijkstra para la ruta más larga en un DAG
- 28. Ruby palabra más larga en matriz
- 29. Encontrar la subcadena común más larga en un gran conjunto de datos
- 30. ¿Cómo encontrar la ruta más larga en un gráfico cíclico entre dos nodos?
es la secuencia en una int array, o solo una cadena delimitada por comas? –
De hecho, es una lista que se puede convertir a una matriz. –
user906763
¿Desea simplemente verificar si una subsecuencia está en una secuencia y devolver verdadero/falso? – BoltClock