Gambas-it

Gambas3 => Programmazione => Topic aperto da: Gianluigi - 19 Marzo 2018, 18:37:10

Titolo: [Risolto] Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 19 Marzo 2018, 18:37:10
Ho il problema di sottrarre da un vettore stringa tutti i nomi presenti in un altro vettore.
Ho pensato di operare così:
Codice: [Seleziona]
Public Sub Main()

  Dim sAlls As String[] = ["Mickey Mouse", "Donald Duck", "Minnie", "Daisy Duck", "Goofy", "Pluto", "Scrooge McDuck", "Huey", "Dewey", "Louie", "Chip", "Dale"]
  Dim sDonald As String[] = ["Donald Duck", "Daisy Duck", "Scrooge McDuck", "Huey", "Dewey", "Louie"]
  Dim s As String
  Dim i As Integer

  Print "Devo sottrarre questi nomi:"
  For Each s In sDonald
    Print s
  Next
  Print
  Print "A questi altri:"
  For Each s In sAlls
    Print s
  Next
  sAlls.Insert(sDonald)
  sAlls.Sort()
  For i = sAlls.Max To 0 Step -1
    If i > 0 Then
      If sAlls[i] = sAlls[i - 1] Then
        sAlls.Delete(i)
        sAlls.Delete(i - 1)
        Dec i
      Endif
    Endif
  Next
  Print
  Print "Sono rimasti questi:"
  For Each s In sAlls
    Print s
  Next

End
Qualcuno ha un'idea migliore?

 :ciao: :ciao:
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Top Fuel - 19 Marzo 2018, 23:53:43
Ci sto provando ma non mi riesce.
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 20 Marzo 2018, 01:42:16
 ???



Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 20 Marzo 2018, 03:19:56
Si potrebbe proporre una cosa così:   :-\

Codice: [Seleziona]
Public Sub Main()

  Dim sAlls As String[] = ["Mickey Mouse", "Donald Duck", "Minnie", "Daisy Duck", "Goofy", "Pluto", "Scrooge McDuck", "Huey", "Dewey", "Louie", "Chip", "Dale"]
  Dim sDonald As String[] = ["Donald Duck", "Daisy Duck", "Scrooge McDuck", "Huey", "Dewey", "Louie"]
  Dim s1, s2 As String

   s1 = sAlls.Join(Chr(0), Null)
 
   For Each s2 In sDonald
     s1 = Replace(s1, s2 & Chr(0), Null)
   Next

   sAlls = Split(s1, Chr(0))

   Print "Sono rimasti questi:\n"
   For Each s2 In sAlls
      Print s2
   Next

End
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 20 Marzo 2018, 11:49:25
Preferisco questa soluzione a quella da me proposta soprattutto perché agire sul contatore di For non mi convince e inoltre sfrutta in modo esemplare l'uso di Join (alter ego di Split).

Attenzione però, il piacere di vuott nell'iserire virtuosismi nel codice :P l'hanno spinto ad un uso non corretto di Replace, per evitare di usare il Null in Split inserisce un insidioso bug che possiamo verificare facendo finire i due vettori con la stessa voce.
Avremmo un confronto fra "voce" e "voce\x00" e così l'ultima non verrebbe eliminata.

Basta cambiare il codice così e credo che non dovrebbero esserci problemi:

Codice: [Seleziona]
Public Sub Main()

  Dim sAlls As String[] = ["Mickey Mouse", "Donald Duck", "Minnie", "Daisy Duck", "Goofy", "Pluto", "Scrooge McDuck", "Huey", "Dewey", "Louie", "Chip", "Dale"]
  Dim sDonald As String[] = ["Donald Duck", "Daisy Duck", "Scrooge McDuck", "Huey", "Dewey", "Louie", "Dale"]
  Dim s1, s2 As String

   s1 = sAlls.Join(Chr(0), Null)
 
   For Each s2 In sDonald
     s1 = Replace(s1, s2, Chr(0))
   Next
   
   sAlls = Split(s1, Chr(0), Null, True)

   Print "Sono rimasti questi:\n"
   For Each s2 In sAlls
      Print s2
   Next

End

 :ciao: :ciao:
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 20 Marzo 2018, 12:59:52
Al problema rilevato si può ovviare anche modificando questa linea:
Codice: [Seleziona]
s1 = sAlls.Join(Chr(0), Null)

come segue:
s1 = sAlls.Join(Chr(0), Null) & Chr(0)


Ad ogni modo la tua rettifica è perfetta e, a mio avviso, preferibile.


Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 23 Marzo 2018, 14:52:07
 :ciao:
Houston, we've had a problem,

se noi riceviamo i dati da una cartella che contiene file nascosti che hanno lo stesso nome dei file visibili il codice non funziona, vedi codice:

Codice: [Seleziona]
Public Sub Main()

  Dim sAlls As String[] = ["Mickey Mouse", ".Mickey Mouse", "Donald Duck", ".Donald Duck", "Minnie", "Daisy Duck", "Goofy", ".Goofy", "Pluto", "Scrooge McDuck", "Huey", ".Huey", "Dewey", ".Dewey", "Louie", "Chip", "Dale"]
  Dim sDonald As String[] = ["Donald Duck", "Daisy Duck", "Scrooge McDuck", "Huey", "Dewey", "Louie"]
  Dim s1, s2 As String

   s1 = sAlls.Join("|", Null)
 
   For Each s2 In sDonald
     s1 = Replace(s1, s2, "|")
   Next
   
   sAlls = Split(s1, "|", Null, True)

   Print "Sono rimasti questi:\n"
   For Each s2 In sAlls
      Print s2
   Next

End

 :-\  :ciao:
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 23 Marzo 2018, 16:38:17
Houston, we've had a problem,


Puoi atterrare, allora, sul "Mare tranquillitatis" della Luna:

Codice: [Seleziona]
Public Sub Main()

  Dim sAlls As String[] = ["Mickey Mouse", ".Mickey Mouse", "Donald Duck", ".Donald Duck", "Minnie", "Daisy Duck", "Goofy", ".Goofy", "Pluto", "Scrooge McDuck", "Huey", ".Huey", "Dewey", ".Dewey", "Louie", "Chip", "Dale"]
  Dim sDonald As String[] = ["Donald Duck", "Daisy Duck", "Scrooge McDuck", "Huey", "Dewey", "Louie", "Dale"]
  Dim s1, s2 As String

   s1 = sAlls.Join(Chr(0), Null)

   For Each s2 In sDonald
     s1 = Replace(s1, s2, Chr(0))
   Next
   
   s1 = Replace(s1, ".\x00", Null)

   sAlls = Split(s1, Chr(0), Null, True)
   
   Print "Sono rimasti questi:\n"
   For Each s2 In sAlls
      Print s2
   Next

End
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 23 Marzo 2018, 17:01:28
Puoi atterrare, allora, sul "Mare tranquillitatis" della Luna:

 ???
Dovrebbero rimanere questi:
Codice: [Seleziona]
.Dewey
.Donald Duck
.Goofy
.Huey
.Mickey Mouse
Chip
Goofy
Mickey Mouse
Minnie
Pluto

e invece rimangono questi:
Codice: [Seleziona]
Mickey Mouse
.Mickey Mouse
Minnie
Goofy
.Goofy
Pluto
Chip

 :-\
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 23 Marzo 2018, 17:04:23
Ah, quindi quelli preceduti dal puntino non vanno elimnati, nonostante si riferiscano al medesimo personaggio. !?
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 23 Marzo 2018, 17:09:26
Ah, quindi quelli preceduti dal puntino non vanno elimnati, nonostante si riferiscano al medesimo personaggio. !?

Si e no vanno eliminati solo quelli del secondo vettore, trattandosi appunto di Operare una sottrazione fra due vettori stringa   :-X

Mi spiego meglio: se nel secondo vettore ci fosse ad esempio ".Donald Duck" andrebbe eliminato anche lui malgrado il puntino, ora è più chiaro spero
 :ciao: :ciao:
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 23 Marzo 2018, 17:25:57
Mi spiego meglio: se nel secondo vettore ci fosse ad esempio ".Donald Duck" andrebbe eliminato anche lui malgrado il puntino, ora è più chiaro spero


Uhmmm.... allora poniamo - a titolo esemplificativo - nel secondo vettore di tipo String i signori Donaldo Ducco e Uèi  :D preceduti entrambi  dal puntino:

Codice: [Seleziona]
Public Sub Main()

  Dim sAlls As String[] = ["Mickey Mouse", ".Mickey Mouse", "Donald Duck", ".Donald Duck", "Minnie", "Daisy Duck", "Goofy", ".Goofy", "Pluto", "Scrooge McDuck", "Huey", ".Huey", "Dewey", ".Dewey", "Louie", "Chip", "Dale"]
  Dim sDonald As String[] = ["Donald Duck", "Daisy Duck", ".Huey", "Scrooge McDuck", ".Donald Duck", "Huey", "Dewey", "Louie", "Dale"]
  Dim s As String
   
   For Each s In sDonald
     sAlls.Remove(sAlls.Find(s, gb.Binary, 0), 1)
   Next


   Print "Sono rimasti questi:\n"
   For Each s In sAlls
      Print s
   Next

End

Ovviamente questo brevissimo e semplicissimo codice può ben sostituire la mia precedente soluzione:
http://www.gambas-it.org/smf/index.php?topic=6191.msg43402#msg43402
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 23 Marzo 2018, 17:42:18
Moooolto bene, avevo visto questo suggerimento sulla ML fatto da Jussi credo ma non ne avevo ben capito la portata.
Molte grazie per avermelo fatto capire  :ok:  :-*

Oltretutto credo che l'uso di Find non dovrebbe creare la famosa 'quadraticità', o come caspita si dice, tanto paventata in tutti gli interventi sui vettori anche da parte di Minisini.
Credo che 0^2 si crei, ma non ne sono sicuro, quando si confrontano due voci dello stesso vettore tipo voce[n] = voce[n - 1], Find essendo interno a Gambas senz'altro non lo fa.
 :ciao: :ciao:

P.S: Chissà se qualche anima pia  :angel: che ben conosce il C vorrà indagare su come lavora Find?
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 23 Marzo 2018, 17:56:05
...Find essendo interno a Gambas senz'altro non lo fa.

...perché osservi la "superficie", il grazioso volto di Gambas; bisognerebbe vedere il codice sorgente, scritto in C, del Metodo .Find( ), nativo di Gambas, per verificare come avvengono in quelle "profondità" le comparazioni.
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 23 Marzo 2018, 17:57:21
...Find essendo interno a Gambas senz'altro non lo fa.

...perché osservi la "superficie", il grazioso volto di Gambas; bisognerebbe vedere il codice sorgente, scritto in C, del Metodo .Find( ), nativo di Gambas, per verificare come avvengono in quelle "profondità" le comparazioni.

Qualcuno mi legge nel pensiero, aiuto  :evil:
Intendo; guarda l'orario del tuo post e della mia ultima modifica sul post precedente.
 :D
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 23 Marzo 2018, 17:58:33
Comunque sia, va da sé che l'ultima mia soluzione con due soli Metodi nativi, è migliore delle altre precedenti ipotesi !
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 23 Marzo 2018, 18:05:27
Comunque sia, va da sé che l'ultima mia soluzione con due soli Metodi nativi, è migliore delle altre precedenti ipotesi !
Concordo perfettamente con te, e se volessi dare pure un'occhiata al codice di Find...  :)
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 23 Marzo 2018, 18:06:01
P.S: Chissà se qualche anima pia  :angel: che ben conosce il C vorrà indagare su come lavora Find?

« Dio si sottrae alla "competizione" con l'Uomo, ricacciandolo nell'illusione e nella miseria della possibilità della "Scelta", del "Libero Arbitrio": della capacità di "ri-nunciare" al Tutto »
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 23 Marzo 2018, 18:09:28
P.S: Chissà se qualche anima pia  :angel: che ben conosce il C vorrà indagare su come lavora Find?

« Dio si sottrae alla "competizione" con l'Uomo, ricacciandolo nell'illusione e nella miseria della possibilità della "Scelta", del "Libero Arbitrio": della capacità di "ri-nunciare" al Tutto »

Anche se non ho ben capito, sospetto che voglia dire "arrangiati"  ;D
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 23 Marzo 2018, 18:20:40
Va comunque detto che anche il Metodo ".Remove( )" opera certamente una re-allocazione dinamica della memoria, precedentemente riservata, dato che vengono  di fatto ridotti gli elementi costituenti l'array.
E' altresì vero che questa riduzione della quantità di memoria non determina necessariamente l'allocazione di ulteriore porzione di memoria altrove (ossia presso altro indirizzo di memoria), potendosi senz'altro sovrascrivere i vecchi dati con i nuovi.
Inoltre, neppure una riallocazione della memoria "in aggiunta" (mediante il Metodo ".Push( )") determina necessariamente l'allocazione di ulteriore porzione di memoria altrove. Lo stesso Boege aveva posto questa sistuazione come eventuale.

Come possiamo vedere dai risultati ritornati da questo esempio in C:
Codice: [Seleziona]
#include <stdio.h>
#include <stdlib.h>


int main() {

/* Allochiamo dinamicamente 4 byte di memoria */
char *c = malloc(sizeof(char) * 4);
printf("%p\n", c);

/* Reallochiamo la memoria "aggiungendo" 2 byte */
c = realloc(c, sizeof(char) * 6);
printf("%p\n", c);

/* Liberiamo la memoria precedentemente riservata, affinché possa essere eventualmente sovrascritta da altri futuri dati */
free(c);

      return (0);

}
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 23 Marzo 2018, 18:40:50
Interessante, però se non ho capito male, a me Tobias aveva detto dell'altro...
Ho trovato la discussione  (https://lists.gambas-basic.org/pipermail/user/2009-August/025666.html)cui accennavo prima e Minisini qui suggerisce l'uso di una collezione...
Ecco come si scrive quadratica 0(n^2) !
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 23 Marzo 2018, 18:43:51
a me Tobias aveva detto dell'altro...
Se non erro, tu utilizzavi due Oggetti di tipo Array.
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 23 Marzo 2018, 18:46:49
a me Tobias aveva detto dell'altro...
Se non erro, tu utilizzavi due Oggetti di tipo Array.

Si hai ragione ma era solo un esempio che raggruppava due funzioni in una sola era per compattare ma giustamente l'avevo capito solo io  ;D
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 23 Marzo 2018, 18:49:43
...come sai, due Oggetti = 2 quantità di memoria = 2 indirizzi di memoria.  :-X
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 23 Marzo 2018, 18:56:19
Forse il punto è questo:
Minisini chiede a Jussi "Why do you have duplicates inside your array?"
È al momento di caricare l'array che andrebbero evitati i doppioni!
Quindi dovremmo usare find per evitare di introdurre i doppioni, è questo il significato?
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 23 Marzo 2018, 18:59:49
Minisini chiede a Jussi "Why do you have duplicates inside your array?"


...in che senso Minisini gli domandava perché lui avesse dei doppioni nell'array ?   ???
In quale array ? Quello di partenza ?
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 23 Marzo 2018, 19:07:53
Minisini chiede a Jussi "Why do you have duplicates inside your array?"


...in che senso Minisini gli domandava perché lui avesse dei doppioni nell'array ?   ???
In quale array ? Quello di partenza ?

Ah non lo so, io ho fatto un'ipotesi, dimmelo tu diversamente, puoi seguire la discussione risalendo a ritroso e/o in avanti con i collegamenti in basso.
 :-\  :-\ (molti dubbi)
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: vuott - 23 Marzo 2018, 19:14:56
...io gli avrei risposto: " Ma a te che te frega se c'ho i doppioni ? "

(https://media.giphy.com/media/ocjsRS7PS6VDq/giphy.gif)


...e poi i doppioni delle figurine Panini si possono sempre cambiare con gli amici.   ;D
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 23 Marzo 2018, 19:24:30
...io gli avrei risposto: " Ma a te che te frega se c'ho i doppioni ? "
...
:rotfl:
Scherzi a parte, hai visto questo (https://lists.gambas-basic.org/pipermail/user/2009-August/025661.html) suggerimento? Sembra il tuo iniziale un po modificato ... la storia si ripete sempre uguale  :D

Comunque non è da sottovalutare la ricerca  preventiva tipo quella suggerita:
Codice: [Seleziona]
IF MyArray.Find("YourString") = -1 THEN MyArray.Add("YourString")

 :ciao:

P.S: laddove sia possibile naturalmente...
Titolo: Re:Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 23 Marzo 2018, 23:28:38
Comunque sia qui il discorso è diverso rispetto a quello della discussione che ho indicato.
Li stanno parlando di doppioni in una matrice e può avere una sua logica l'impedirne preventivamente il loro formarsi controllando, come detto, che il dato non sia già stato incamerato.
Diverso invece il discorso che stiamo facendo qui dove abbiamo già due elenchi e uno va sottratto all'altro; con la tua ultima dimostrazione (http://www.gambas-it.org/smf/index.php?topic=6191.msg43428#msg43428) nettamente migliore delle altre.
Direi che possiamo apporre un bel risolto  :D
Titolo: Re:[Risolto] Operare una sottrazione fra due vettori stringa.
Inserito da: Gianluigi - 24 Marzo 2018, 15:23:26
Propongo questa variazione per evitare lo out of bound dovuto al ritorno di -1 da parte di Find in caso di mancato riscontro:
Codice: [Seleziona]
Public Sub Main()

  Dim sAlls As String[] = ["Mickey Mouse", ".Mickey Mouse", "Donald Duck", ".Donald Duck", "Minnie", "Daisy Duck", "Goofy", ".Goofy", "Pluto", "Scrooge McDuck", "Huey", ".Huey", "Dewey", ".Dewey", "Louie", "Chip", "Dale"]
  Dim sDonald As String[] = ["Donald Duck", "Daisy Duck", ".Huey", "Scrooge McDuck", ".Donald Duck", "Huey", "Dewey", "Louie", "Dale", "Pippo"]
  Dim s As String, i As Integer

   For Each s In sDonald
     '' Impedisce lo out of bound quando find non trova riscontro.
     i = sAlls.Find(s, gb.Binary, 0)
     If i >= 0 Then sAlls.Remove(i, 1)
   Next

   Print "Sono rimasti questi:\n"
   For Each s In sAlls
      Print s
   Next

End

Nota: "Pippo" è presente solo nel secondo vettore

 :ciao: :ciao: