Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Ayuda con algoritmo para buscar capitulos faltantes en una lista (https://www.clubdelphi.com/foros/showthread.php?t=96116)

JoAnCa 19-02-2023 19:51:21

Ayuda con algoritmo para buscar capitulos faltantes en una lista
 
Hola a todos
Pues dado un listado de archivos de novelas, necesito saber cuales capitulos faltan.


- En una carpeta estan los archivos, que cada uno corresponde a un capitulo de la novela
- El nombre del archivo (novela) puede tener una de estas nomenclaturas:

## - Nombre de la nonvela
Nombre de la nonvela - ##


donde ##, es el numero del capitulo.


El objetivo es recorrer todos esos archivos y comprobar que todos los capitulos esten consecutivos hasta el final, que el ultimo capitulo seria el total de archivos en la carpeta.


Si faltara algun capitulo, lo guardo en una variable para mostrala despues.


Alguna idea de como realizar este proceso?

JoAnCa 19-02-2023 23:13:33

Como saber los numeros faltantes en una lista consecutiva
 
Pues la forma de obtener los numeros de capitulos ya la tengo, en una cadena los almaceno separados por comas.

Lo que necesito saber es, de esa lista de numeros consecutivos ordenada, cuales son los numeros que faltan

escafandra 19-02-2023 23:27:26

Quizás una forma simple sea guardar los números de capitulo que encuentras en la carpeta en un TList y aplicar un Short (de menor a mayor). Luego los recorres, si el número de capitulo no coincide con el indice + 1, ese te falta. Puedes hacer algo simlilar con un TStringList y CustomSort.


Saludos.

JoAnCa 20-02-2023 00:14:55

Cita:

Empezado por escafandra (Mensaje 550445)
Quizás una forma simple sea guardar los números de capitulo que encuentras en la carpeta en un TList y aplicar un Short (de menor a mayor). Luego los recorres, si el número de capitulo no coincide con el indice + 1, ese te falta. Puedes hacer algo simlilar con un TStringList y CustomSort.

Saludos.


Pues estuve analizando esa forma y para el 1 faltante funciona, pero cuando hay mas, o cuando hayan varios faltantes consecutivos, no funciona, pues los capitulos se desfasan con respecto al indice, es decir:
1 - 1
2 - 2
3 - 4
4 - 5
5 - 8
6 - 9

Ahi me devuelve bien el 3, pero despues se desfasan y no puedo tomar como referencia el index. O quizas es que no entendi bien la idea

Neftali [Germán.Estévez] 20-02-2023 09:02:36

Cita:

Empezado por JoAnCa (Mensaje 550441)
Alguna idea de como realizar este proceso?

Recorre los ficheros del directorio, analizando ambos formatos guarda los números en una Lista (TStringList o TList<integer>).
Una vez los tengas en la lista, recorre la lista de capítulos y almacena en otra (TStringList o TList<integer> aquellos que te faltan).

Tal vez me estoy perdiendo algo, pero lo veo como un proceso sencillo.
Tal vez algo de código ayude a entender lo que me estoy perdiendo... :o

bucanero 20-02-2023 09:59:13

hola a todos!!

una alternativa puede ser utilizar las clases TArray<inteteger> o Tdictionary<integer, ....> en donde en este caso puede obtener un indice a los capitulos.

Mira si estos códigos te pueden servir:

Código:

/// ----
/// Metodo 1: con la clase TArray
/// ----
function BuscarHuecosCapitulos(Files:TStringDynArray):Tarray<Integer>;
var
  fileName: string;
  Capitulos: TArray<Integer>;
  Capitulo, j:integer;
begin
  result := [];

  /// Genera un array con los numeros de capitulos
  for fileName in Files do
    Capitulos := Capitulos + [GetFileNumCapitulo(fileName)];

  /// los ordena
  TArray.sort<Integer>(Capitulos);

  //y se recorre el array desde el primer capitulo hasta el ultimo capitulo buscando los huecos
  Capitulo := 1;
  j := 0; /// la variable J es la posicion en el array de los capitulos
  repeat
    if Capitulo < Capitulos[j] then
      result := result + [Capitulo]
    else
      inc(j);
    Inc(Capitulo);
  until j > High(Capitulos);
end;

Código:

/// ----
/// Metodo 2: con la clase TDictionary
/// ----
function BuscarHuecosCapitulos(Files:TStringDynArray):Tarray<Integer>;
var
  fileName: string;
  Capitulos: TDictionary<Integer, boolean>; /// el tipo boolean se puede sustituir por cualquier otro tipo, no se va a usar en este caso
  capitulo, UltimoCapitulo: integer;
begin

  result := [];

  Capitulos := TDictionary<Integer, BOOLean>.create;

  // en este caso se debe de obtener también el ultimo capitulo que se ha encontrado
  UltimoCapitulo := 0;
  for fileName in Files do begin
    capitulo := GetFileNumCapitulo(fileName);
    Capitulos.AddOrSetValue(capitulo, True);
    if capitulo > UltimoCapitulo then
      UltimoCapitulo := capitulo;
  end;

  for capitulo := 1 to UltimoCapitulo do
    if not Capitulos.ContainsKey(capitulo) then
      Result := result + [capitulo];

  Capitulos.free;
end;

y la forma de uso

Código Delphi [-]
uses
  IOUtils, system.Generics.collections;

...
procedure BuscarCapitulos;
var
  Dir, fileName: string;
  Files: TStringDynArray;
  i: integer;
  faltan: TArray;
begin
  Dir := 'C:\A\libros\uno\';
  Files := TDirectory.GetFiles(Dir);

  // aqui se obtine un listado con los capitulos que faltarian
  faltan := BuscarHuecosCapitulos(Files);
  for i := 0 to High(faltan) do
    memo1.lines.Add(format('falta el capituno #%d', [faltan[i]]));
end;

mamcx 20-02-2023 16:01:56

Una manera simple es solo generar una lista de inicio..fin y marcar solo si encontró:

//pseudocodigo
Código PHP:

found:Vec<Bool> = 1..10

for i in 1..10:
   
current id_archivo
   
if current:
     
found[i] = true 


JoAnCa 22-02-2023 00:44:13

Gracias a todos por sus respuestas


Probare los metodos de Bucanero a ver que tal resulta


El metodo de mamcx, visto rapidamente, me parece que sucede lo mismo que con el metodo de escafandra

JoAnCa 22-02-2023 03:12:18

Pues con el 2do metodo de bucanero (me gustó mas porque me recuerda a python), me funciono bastante bien


Lo que me queda es optimizar un poco el metodo de extraer el numero de capitulo, ya que cuando el capitulo esta delante no hay problema, pero cuando esta al final, se complica cuando el nombre de la novela contiene numeros.
Por ejemplo:

1- Enemigo intimo 1 - 25 (1 es la temporada y 25 el capitulo)
2- 100 años de soledad - 11 (100 es parte del nombre y 11 el capitulo)

Se me volvio un poco complicado ...


La franja horaria es GMT +2. Ahora son las 22:45:19.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi