Public Class Form1
Dim stringa As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
OpenFileDialog1.Filter = "Files HTML|*.html"
OpenFileDialog1.FileName = ""
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
TextBox1.Text = OpenFileDialog1.FileName
Dim stringa As String = OpenFileDialog1.FileName
TextBox1.Text = splitPath(stringa)
TextBox2.Text = splitFileName(stringa)
End If
End Sub
Private Function splitFileName(s As String) As String
Return s.Substring(s.LastIndexOf("\") + 1, s.Length - 1 - s.LastIndexOf("\"))
End Function
Private Function splitPath(s As String) As String
Return s.Substring(0, s.LastIndexOf("\") + 1)
End Function
End Class
Miei appunti liberi, senza pretesa di dire necessariamente sempre cose giuste o sensate, durante l'apprendimento e la pratica della programmazione
JavascriptProva
domenica 22 luglio 2018
Ripasso di OpenFileDialog
venerdì 20 luglio 2018
Apertura di un file HTML per la lettura del codice in VB.NET
Ripassiamo l'apertura dei files (in VB6 era completamente diversa, e in VB.NET, pur avendola usata, l'ho dimenticata da un pezzo.
Devo aprire un file html per mostrarne il codice.
Presto fatto:
Devo aprire un file html per mostrarne il codice.
Presto fatto:
Imports System.IO
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim sr As New StreamReader("C:\users\antonello\documents\prova.html")
Dim line As String = sr.ReadToEnd()
TextBox1.Text = line
End Sub
End Class
Ed ecco il codice nella TextBox:
<html> <body bgcolor=green> <div style="background-color:red;color:white">Ciao bestia</div> </body>
mercoledì 18 luglio 2018
Individuare la posizione di tutti gli spazi di una stringa (ma va bene per qualunque altro carattere o sottostringa)
Una piccola sfida propostami da mio figlio: individuare tutte le parole una per una in una stringa. Per cominciare, ho provato a individuare la posizione degli spazi fra le parole.
Intanto, deve usare una richTextBox, se ricordo bene... e poi... vedremo.
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim pos As Integer = -1
Dim start As Integer = 1
Dim stringa As String = "gongolo mammolo cucciolo eolo dotto pisolo brontolo"
Dim stringhetta As String = " "
While pos <> 0
If pos <> -1 Then Debug.Print(pos)
pos = InStr(start, stringa, stringhetta)
start = pos + 1
End While
End Sub
End Class
Risultato:
8 16 25 30 36 43Ma non è ancora raggiunto lo scopo: vuole che la parola venga colorata durante la digitazione se viene riconosciuta come una particolare parola.
Intanto, deve usare una richTextBox, se ricordo bene... e poi... vedremo.
domenica 24 giugno 2018
Immagine spostabile su video
Creare un controllo immagine in vb, come si fa?
C'è la picturebox.
Studiamola...
La proprietà SizeMode impostata su AutoSize mi sembra la scelta migliore.
Ora devo studiare come renderla mobile. Iniziamo quindi a studiarne le coordinate.
Il principio per rendere mobile un'immagine parte dalla conoscenza delle coordinate del puntatore. Come si conoscono in VB?
Ecco: ho realizzato abbastanza agevolmente una PictureBox spostabile con il puntatore del mouse (ed eventualmente con il dito su tablet)
C'è la picturebox.
Studiamola...
La proprietà SizeMode impostata su AutoSize mi sembra la scelta migliore.
Ora devo studiare come renderla mobile. Iniziamo quindi a studiarne le coordinate.
Il principio per rendere mobile un'immagine parte dalla conoscenza delle coordinate del puntatore. Come si conoscono in VB?
Ecco: ho realizzato abbastanza agevolmente una PictureBox spostabile con il puntatore del mouse (ed eventualmente con il dito su tablet)
Public Class Form1
Dim initX, initY As Integer
Dim deltaX, deltaY As Integer
Dim pressed As Boolean = False
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
initX = e.X
initY = e.Y
pressed = True
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
If pressed Then
deltaX = e.X - initX
deltaY = e.Y - initY
PictureBox1.Left += deltaX
PictureBox1.Top += deltaY
End If
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
pressed = False
End Sub
End Class
domenica 17 giugno 2018
Tabelle hash: risoluzione delle collisioni con linked list in Visual Basic .NET
Ora la gestione con le liste concatenate può presentare lo stesso ordine di problemi.
Salvo il codice precedente:
E ora provo...
Ci vuole sempre una funzione Hash, che può essere anche quella che ho già usato:
Ora dobbiamo gestire però la creazione di liste concatenate per poter piazzare anche questo valore.
Dovrebbe cominciare dalla funzione createItem...
Se il nodo è già occupato va creato un altro nodo e impostato come "prossimo" del primo.
Ecco trovata la soluzione:
Ora creo intenzionalmente altri elementi il cui risultato della funzione hashFunction sia 317 e vediamo...
Dopo qualche incazzatura, trovo la fonte dell'errore.
Salvo il codice precedente:
Public Class Form1
Dim nodeArray(366) As Nodo
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
createItem("abc")
createItem("fds")
createItem("ghr")
createItem("uyj")
createItem("jhk")
createItem("fgh")
elenca()
End Sub
Sub createItem(stringa As String)
Dim hf As Integer = hashFunction(stringa)
If nodeArray(hf) Is Nothing Then
nodeArray(hf) = New Nodo
nodeArray(hf).valore = stringa
nodeArray(hf).prossimo = Nothing
Else
Do
hf = hf + 1
If hf > UBound(nodeArray) Then Exit Do
If nodeArray(hf) Is Nothing Then
nodeArray(hf) = New Nodo
nodeArray(hf).valore = stringa
nodeArray(hf).prossimo = Nothing
Exit Do
End If
Loop
End If
End Sub
Sub elenca()
For n = 0 To UBound(nodeArray)
If nodeArray(n) Is Nothing Then
Debug.Print(n & "---")
Else
Debug.Print(n & "---" & nodeArray(n).valore)
End If
Next
End Sub
Function hashFunction(stringa As String) As Integer
Dim asciValue As Integer = 0
For n = 1 To Len(stringa)
asciValue += Asc(Mid(stringa, n, 1))
Next
Return asciValue
End Function
End Class
Class Nodo
Public valore As String
Public prossimo As Nodo
End Class
E ora provo...
Ci vuole sempre una funzione Hash, che può essere anche quella che ho già usato:
Function hashFunction(stringa As String) As Integer
Dim asciValue As Integer = 0
For n = 1 To Len(stringa)
asciValue += Asc(Mid(stringa, n, 1))
Next
Return asciValue
End Function
End Class
In base a questa, ora, devo modificare questa:
Sub createItem(stringa As String)
Dim hf As Integer = hashFunction(stringa)
If nodeArray(hf) Is Nothing Then
nodeArray(hf) = New Nodo
nodeArray(hf).valore = stringa
nodeArray(hf).prossimo = Nothing
Else
Do
hf = hf + 1
If hf > UBound(nodeArray) Then Exit Do
If nodeArray(hf) Is Nothing Then
nodeArray(hf) = New Nodo
nodeArray(hf).valore = stringa
nodeArray(hf).prossimo = Nothing
Exit Do
End If
Loop
End If
End Sub
In base alla funzione hashFunction, dovrei piazzare il valore nel nodo adeguato:
Sub createItem(stringa As String)
Dim hf As Integer = hashFunction(stringa)
If nodeArray(hf) Is Nothing Then
nodeArray(hf) = New Nodo
nodeArray(hf).valore = stringa
nodeArray(hf).prossimo = Nothing
End If
End Sub
Sub elenca()
For n = 0 To UBound(nodeArray)
If nodeArray(n) Is Nothing Then
Debug.Print(n & "---")
Else
Debug.Print(n & "---" & nodeArray(n).valore)
End If
Next
End Sub
Tutto come prima: vediamo cosa succede.
294---abc 309---fgh 317---fds 321---ghr 344---uyjConfrontando con il codice:
createItem("abc")
createItem("fds")
createItem("ghr")
createItem("uyj")
createItem("jhk")
createItem("fgh")
Anche qui c'è la stessa collisione: la funzione hashFunction restituisce 317 per "fds" e per "jhk", che però trovando il posto già occupato non viene inserita nella tabella.
Ora dobbiamo gestire però la creazione di liste concatenate per poter piazzare anche questo valore.
Dovrebbe cominciare dalla funzione createItem...
Se il nodo è già occupato va creato un altro nodo e impostato come "prossimo" del primo.
Ecco trovata la soluzione:
Public Class Form1
Dim nodeArray(366) As Nodo
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
createItem("abc")
createItem("fds")
createItem("ghr")
createItem("uyj")
createItem("jhk")
createItem("fgh")
elenca()
End Sub
Sub createItem(stringa As String)
Dim hf As Integer = hashFunction(stringa)
Dim tail As Nodo, temp As Nodo
'se il nodo base non è istanziato, si istanzia e gli si dà il valore.
If nodeArray(hf) Is Nothing Then
nodeArray(hf) = New Nodo
nodeArray(hf).valore = stringa
nodeArray(hf).prossimo = Nothing
Else
'se il nodo base è istanziato, si dà al nodo base istanziato il nome tail (in quanto è la coda della fila)
tail = nodeArray(hf)
Do
'se non esiste un nodo prossimo al nodo tail... si istanzia un nuovo nodo chiamato temp...
If tail.prossimo Is Nothing Then
temp = New Nodo
'e gli si danno i valori.
temp.valore = stringa
temp.prossimo = Nothing
'si pone questo nodo temp appena istanziato come prossimo rispetto al nodo tail
tail.prossimo = temp
'si dà a questo nuovo nodo il nome di tail.
tail = temp
Exit Do
Else
'se invece esiste il nodo prossimo, allora questo diventerà il nuovo tail.
tail.prossimo = tail
End If
Loop
End If
End Sub
Sub elenca()
For n = 0 To UBound(nodeArray)
'se il nodo non è istanziato si scriverà solo il numero
If nodeArray(n) Is Nothing Then
Debug.Print(n & "---")
Else
'se il nodo è istanziato, si scriverà il valore
Debug.Print(n & "---" & nodeArray(n).valore)
'e bisogna cercare se ci sono altri nodi nella linked list
Dim tail As Nodo
tail = nodeArray(n)
Do
If Not tail.prossimo Is Nothing Then
tail = tail.prossimo
Debug.Print(n & "---" & tail.valore)
Else
Exit Do
End If
Loop
End If
Next
End Sub
Function hashFunction(stringa As String) As Integer
Dim asciValue As Integer = 0
For n = 1 To Len(stringa)
asciValue += Asc(Mid(stringa, n, 1))
Next
Return asciValue
End Function
End Class
Class Nodo
Public valore As String
Public prossimo As Nodo
End Class
Ed ecco i due valori che erano entrati in collisione, rappresentati su un'unica colonna con gli altri (non ho voluto cimentarmi per una rappresentazione migliore)
294---abc
309---fgh
317---fds
317---jhk
321---ghr
344---uyj
Confronto:
createItem("abc")
createItem("fds")
createItem("ghr")
createItem("uyj")
createItem("jhk")
createItem("fgh")
Perfetto! I due elementi appaiono con lo stesso numero in quanto sono parte di una lista concatenata.Ora creo intenzionalmente altri elementi il cui risultato della funzione hashFunction sia 317 e vediamo...
createItem("abc")
createItem("fds")
createItem("ghr")
createItem("uyj")
createItem("jhk")
createItem("fgh")
createItem("ddu")
createItem("dax")
createItem("uce")
E scopro che il programma si blocca.Dopo qualche incazzatura, trovo la fonte dell'errore.
Sub createItem(stringa As String)
Dim hf As Integer = hashFunction(stringa)
Dim tail As Nodo, temp As Nodo
temp = New Nodo
temp.valore = stringa
temp.prossimo = Nothing
'se il nodo base non è istanziato, si istanzia e gli si dà il valore.
If nodeArray(hf) Is Nothing Then
nodeArray(hf) = temp
Else
'se il nodo base è istanziato, si dà al nodo base istanziato il nome tail (in quanto è la coda della fila)
tail = nodeArray(hf)
Do
'se non esiste un nodo prossimo al nodo tail... si istanzia un nuovo nodo chiamato temp...
If tail.prossimo Is Nothing Then
tail.prossimo = temp
Exit Do
Else
'se invece esiste il nodo prossimo, allora questo diventerà il nuovo tail.
tail.prossimo = tail
End If
Loop
End If
End Sub
Una volta che il programma vede che un nodo è stato già istanziato, deve ripetere il ciclo usando questo come nodo tail, ma tail.prossimo = tail non attribuisce il nome tail al prossimo nodo, ma fa diventare il nodo successivo uguale a quello che attualmente è tail.
Correggendo l'errore, il problema si risolve (ho impostato come oggetto iniziale sub Main credendo erroneamente che il pfoblema stesse nel caricamento del form ma va bene lo stesso).
Module Module1
Dim nodeArray(366) As Nodo
Sub main()
createItem("abc")
createItem("fds")
createItem("ghr")
createItem("uyj")
createItem("jhk")
createItem("fgh")
createItem("ddu")
createItem("dax")
createItem("uce")
elenca()
End Sub
Sub createItem(stringa As String)
Dim hf As Integer = hashFunction(stringa)
Dim tail As Nodo, temp As Nodo
temp = New Nodo
temp.valore = stringa
temp.prossimo = Nothing
'se il nodo base non è istanziato, si istanzia e gli si dà il valore.
If nodeArray(hf) Is Nothing Then
nodeArray(hf) = temp
Else
'se il nodo base è istanziato, si dà al nodo base istanziato il nome tail (in quanto è la coda della fila)
tail = nodeArray(hf)
Do
'se non esiste un nodo prossimo al nodo tail... si istanzia un nuovo nodo chiamato temp...
If tail.prossimo Is Nothing Then
tail.prossimo = temp
Exit Do
Else
'se invece esiste il nodo prossimo, allora questo diventerà il nuovo tail.
tail = tail.prossimo
End If
Loop
End If
End Sub
Sub elenca()
For n = 0 To UBound(nodeArray)
'se il nodo non è istanziato si scriverà solo il numero
If nodeArray(n) Is Nothing Then
Debug.Print(n & "---")
Else
'se il nodo è istanziato, si scriverà il valore
Debug.Print(n & "---" & nodeArray(n).valore)
'e bisogna cercare se ci sono altri nodi nella linked list
Dim tail As Nodo
tail = nodeArray(n)
Do
If Not tail.prossimo Is Nothing Then
tail = tail.prossimo
Debug.Print(n & "---" & tail.valore)
Else
Exit Do
End If
Loop
End If
Next
End Sub
Function hashFunction(stringa As String) As Integer
Dim asciValue As Integer = 0
For n = 1 To Len(stringa)
asciValue += Asc(Mid(stringa, n, 1))
Next
Return asciValue
End Function
Class Nodo
Public valore As String
Public prossimo As Nodo
End Class
End Module
Vediamo:
294---abc
309---fgh
317---fds
317---jhk
317---ddu
317---dax
317---uce
321---ghr
344---uyj
Mi sembra perfetto! Tutti quelli marcati in rosso fanno parte della linked list creata per risolvere il problema della collisione!
venerdì 15 giugno 2018
Creazione di una tabella hash elementare in VB con gestione della collisione per mezzo della tecnica "Open addressing"
Bene.
Proseguendo nello studio delle tabelle hash e delle liste concatenate, due cose fondamentali mi servono: una funzione che converta una stringa in un numero, ossia la funzione hash, e poi la creazioni di nodi.
Rivediamo la prima.
Mi serve una funzione per trasformare i caratteri nei loro codici ASCII e poi farne la somma.
Questa l'ho già vista prima ma ora la ripasso.
Come parametro, ci sarà una stringa.
Ad ogni elemento della matrice devo far corrispondere un carattere della stringa.
Adesso devo calcolare il valore ASCII dei caratteri e sommarli insieme:
Ma non si può fare a meno della matrice?
Facciamo un calcolo abbreviato.
Vorrei trovare un nome più consono alla funzione:
Ora, in previsione dell'uso di liste concatenate come mezzo per superare le collisioni, dovrei inserire questi valori trovati in una serie di "nodi".
Creiamo la classe Nodo.
Come conciliare la funzione che ho trovato prima con i nodi?
Avrei una matrice di nodi, che però non dovrebbero essere istanziati tutti, bensì solo quelli utilizzati.
Ad esempio, per un asciSum di 294 dovrei istanziare l'elemento 294 dell'array di nodi.
Facciamo una lista di 500 nodi, ossia una matrice di 500 variabili nodo (non istanziate), e una variabile che servirà da index ogni volta che si creerà un nuovo valore.
Ora creo la funzione che crea un nuovo item:
Ecco scritto il tutto:
Ecco: le stringhe da porre nella tabella erano queste:
Proviamo con il metodo Open Addressing.
Innanzitutto bisogna vedere come individuare una collisione.
Con questo accorgimento, jhk non dovrebbe sostituire fds.
Ora, individuata la collisione, dove andiamo a mettere quel jhk che la funzione hash ha reso uguale al fds?
Dobbiamo scorrere avanti nella lista fino a trovare uno "slot" vuoto.
Innanzitutto è più comodo modificare così la funzione createItem:
Proviamo.
Ecco una migliore gestione che evita al ciclo Do... Loop di andare avanti superando i limiti della matrice nodeArray:
Confronto con le stringhe da "disporre" nel codice:
Ora se io voglio ritrovare il punto in cui si trova la stringa "jhk", come faccio?
Tramite la funzione hash (hashFunction) trovo immediatamente la "locazione" 317. A questo punto faccio un confronto che non mi dà la corrispondenza, in quanto in quella "locazione" io ci trovo "fds". Così con un ciclo "while" scorro le locazioni successive fino a quando il confronto darà esito positivo.
Molto più economico che cercare "jhk" su tutta la matrice nodeArray di sana pianta a cominciare dal primo fino a quando avrò trovato la stringa!
Proseguendo nello studio delle tabelle hash e delle liste concatenate, due cose fondamentali mi servono: una funzione che converta una stringa in un numero, ossia la funzione hash, e poi la creazioni di nodi.
Rivediamo la prima.
Mi serve una funzione per trasformare i caratteri nei loro codici ASCII e poi farne la somma.
Questa l'ho già vista prima ma ora la ripasso.
Come parametro, ci sarà una stringa.
Sub converti(stringa As String)
End Sub
Quindi predispongo una matrice dinamica:
Sub converti(stringa As String)
Dim caratteri() As Char
End Sub
Ridimensiono la matrice di caratteri alla lunghezza della stringa (-1 perché la matrice comincia con 0):
Sub converti(stringa As String)
Dim caratteri() As Char
ReDim caratteri(Len(stringa) - 1)
End Sub
Ora ho una matrice di caratteri di lunghezza uguale a quella della stringa.Ad ogni elemento della matrice devo far corrispondere un carattere della stringa.
Sub converti(stringa As String)
Dim caratteri() As Char
ReDim caratteri(Len(stringa) - 1)
For n = 0 To Len(stringa) - 1
caratteri(n) = Mid(stringa, n, 1)
Next
End Sub
Come prova, scrivo nella finestra di Debug i singoli valori della matrice caratteri():
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
converti("ciao")
End Sub
Sub converti(stringa As String)
Dim caratteri() As Char
ReDim caratteri(Len(stringa) - 1)
For n = 1 To Len(stringa)
caratteri(n - 1) = Mid(stringa, n, 1)
Next
For n = 0 To UBound(caratteri)
Debug.Print(caratteri(n))
Next
End Sub
e vediamo cosa ne viene fuori, per vedere se abbiamo fatto tutta la procedura corretta:
c i a oBene.
Adesso devo calcolare il valore ASCII dei caratteri e sommarli insieme:
Sub converti(stringa As String)
Dim asciValue As Integer = 0
Dim caratteri() As Char
ReDim caratteri(Len(stringa) - 1)
For n = 1 To Len(stringa)
caratteri(n - 1) = Mid(stringa, n, 1)
Next
For n = 0 To UBound(caratteri)
asciValue += Asc(caratteri(n))
Next
Debug.Print(asciValue)
End Sub
Ho predisposto un valore asciValue pari a zero che, ripassando tutti i caratteri della matrice convertiti nel loro valore ASCII vi vengono sommati:
c i a o 412
Ma non si può fare a meno della matrice?
Facciamo un calcolo abbreviato.
Sub converti(stringa As String)
Dim asciValue As Integer = 0
For n = 1 To Len(stringa)
asciValue += Asc(Mid(stringa, n, 1))
Debug.Print(Mid(stringa, n, 1))
Next
Debug.Print(asciValue)
End Sub
c i a o 412Considerando che abbiamo come input una stringa e come output vogliamo sapere il valore della somma dei codici ASCII dei suoi caratteri (possiamo evitare di stampare tutti i caratteri, cosa che ci serviva solo per verificare che avevamo fatto tutto bene), trasformiamo la Sub in una Function:
Function converti(stringa As String) As Integer
Dim asciValue As Integer = 0
For n = 1 To Len(stringa)
asciValue += Asc(Mid(stringa, n, 1))
Next
Return asciValue
End Function
E verifichiamola:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Debug.Print(converti("abc"))
End Sub
Function converti(stringa As String) As Integer
Dim asciValue As Integer = 0
For n = 1 To Len(stringa)
asciValue += Asc(Mid(stringa, n, 1))
Next
Return asciValue
End Function
End Class
294...che corrisponde alla somma dei codici ASCII di a,b,c.
Vorrei trovare un nome più consono alla funzione:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Debug.Print(asciiSum("abc"))
End Sub
Function asciiSum(stringa As String) As Integer
Dim asciValue As Integer = 0
For n = 1 To Len(stringa)
asciValue += Asc(Mid(stringa, n, 1))
Next
Return asciValue
End Function
End Class
Ora, in previsione dell'uso di liste concatenate come mezzo per superare le collisioni, dovrei inserire questi valori trovati in una serie di "nodi".
Creiamo la classe Nodo.
Class Nodo
Public valore As Integer
Public prossimo As Nodo
End Class
La proprietà valore è quella che ospita i valori asciiSum, ossia quelli ottenuti con la funzione hash. La proprietà prossimo dovrebbe indicare il nodo successivamente concatenato nell'eventualità ce ne fosse bisogno.
Come conciliare la funzione che ho trovato prima con i nodi?
Avrei una matrice di nodi, che però non dovrebbero essere istanziati tutti, bensì solo quelli utilizzati.
Ad esempio, per un asciSum di 294 dovrei istanziare l'elemento 294 dell'array di nodi.
Facciamo una lista di 500 nodi, ossia una matrice di 500 variabili nodo (non istanziate), e una variabile che servirà da index ogni volta che si creerà un nuovo valore.
Dim nodeArray(500) As Integer
Dim hashFunction As Integer
Mi sta venendo l'idea di chiamare la funzione, anziché asciValue, hashFunction, a sottolineare la funzione più generale di funzione hash.
Ora creo la funzione che crea un nuovo item:
Sub createItem(stringa As String)
End Sub
Ecco scritto il tutto:
Public Class Form1
Dim nodeArray(366) As Nodo
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
createItem("abc")
createItem("fds")
createItem("ghr")
createItem("uyj")
createItem("jhk")
createItem("fgh")
elenca()
End Sub
Sub createItem(stringa As String)
nodeArray(hashFunction(stringa)) = New Nodo
nodeArray(hashFunction(stringa)).valore = stringa
nodeArray(hashFunction(stringa)).prossimo = Nothing
End Sub
Sub elenca()
For n = 0 To UBound(nodeArray)
If nodeArray(n) Is Nothing Then
Debug.Print(n & "---")
Else
Debug.Print(n & "---" & nodeArray(n).valore)
End If
Next
End Sub
Function hashFunction(stringa As String) As Integer
Dim asciValue As Integer = 0
For n = 1 To Len(stringa)
asciValue += Asc(Mid(stringa, n, 1))
Next
Return asciValue
End Function
End Class
Class Nodo
Public valore As String
Public prossimo As Nodo
End Class
Ed ecco l'output:
0--- 1--- 2--- 3--- 4--- 5--- 6--- 7--- 8--- 9--- 10--- 11--- 12--- 13--- 14--- 15--- 16--- 17--- 18--- 19--- 20--- 21--- 22--- 23--- 24--- 25--- 26--- 27--- 28--- 29--- 30--- 31--- 32--- 33--- 34--- 35--- 36--- 37--- 38--- 39--- 40--- 41--- 42--- 43--- 44--- 45--- 46--- 47--- 48--- 49--- 50--- 51--- 52--- 53--- 54--- 55--- 56--- 57--- 58--- 59--- 60--- 61--- 62--- 63--- 64--- 65--- 66--- 67--- 68--- 69--- 70--- 71--- 72--- 73--- 74--- 75--- 76--- 77--- 78--- 79--- 80--- 81--- 82--- 83--- 84--- 85--- 86--- 87--- 88--- 89--- 90--- 91--- 92--- 93--- 94--- 95--- 96--- 97--- 98--- 99--- 100--- 101--- 102--- 103--- 104--- 105--- 106--- 107--- 108--- 109--- 110--- 111--- 112--- 113--- 114--- 115--- 116--- 117--- 118--- 119--- 120--- 121--- 122--- 123--- 124--- 125--- 126--- 127--- 128--- 129--- 130--- 131--- 132--- 133--- 134--- 135--- 136--- 137--- 138--- 139--- 140--- 141--- 142--- 143--- 144--- 145--- 146--- 147--- 148--- 149--- 150--- 151--- 152--- 153--- 154--- 155--- 156--- 157--- 158--- 159--- 160--- 161--- 162--- 163--- 164--- 165--- 166--- 167--- 168--- 169--- 170--- 171--- 172--- 173--- 174--- 175--- 176--- 177--- 178--- 179--- 180--- 181--- 182--- 183--- 184--- 185--- 186--- 187--- 188--- 189--- 190--- 191--- 192--- 193--- 194--- 195--- 196--- 197--- 198--- 199--- 200--- 201--- 202--- 203--- 204--- 205--- 206--- 207--- 208--- 209--- 210--- 211--- 212--- 213--- 214--- 215--- 216--- 217--- 218--- 219--- 220--- 221--- 222--- 223--- 224--- 225--- 226--- 227--- 228--- 229--- 230--- 231--- 232--- 233--- 234--- 235--- 236--- 237--- 238--- 239--- 240--- 241--- 242--- 243--- 244--- 245--- 246--- 247--- 248--- 249--- 250--- 251--- 252--- 253--- 254--- 255--- 256--- 257--- 258--- 259--- 260--- 261--- 262--- 263--- 264--- 265--- 266--- 267--- 268--- 269--- 270--- 271--- 272--- 273--- 274--- 275--- 276--- 277--- 278--- 279--- 280--- 281--- 282--- 283--- 284--- 285--- 286--- 287--- 288--- 289--- 290--- 291--- 292--- 293--- 294---abc 295--- 296--- 297--- 298--- 299--- 300--- 301--- 302--- 303--- 304--- 305--- 306--- 307--- 308--- 309---fgh 310--- 311--- 312--- 313--- 314--- 315--- 316--- 317---jhk 318--- 319--- 320--- 321---ghr 322--- 323--- 324--- 325--- 326--- 327--- 328--- 329--- 330--- 331--- 332--- 333--- 334--- 335--- 336--- 337--- 338--- 339--- 340--- 341--- 342--- 343--- 344---uyj 345--- 346--- 347--- 348--- 349--- 350--- 351--- 352--- 353--- 354--- 355--- 356--- 357--- 358--- 359--- 360--- 361--- 362--- 363--- 364--- 365--- 366---
Ecco: le stringhe da porre nella tabella erano queste:
createItem("abc")
createItem("fds")
createItem("ghr")
createItem("uyj")
createItem("jhk")
createItem("fgh")
mentre quelle ritrovate nella tabella sono:
294---abc 309---fgh 317---jhk 321---ghr 344---uyjc'è una collisione fra le stringhe "fds" e "jhk", la cui somma è sempre 317
Proviamo con il metodo Open Addressing.
Innanzitutto bisogna vedere come individuare una collisione.
Con questo accorgimento, jhk non dovrebbe sostituire fds.
Sub createItem(stringa As String)
If nodeArray(hashFunction(stringa)) Is Nothing Then
nodeArray(hashFunction(stringa)) = New Nodo
nodeArray(hashFunction(stringa)).valore = stringa
nodeArray(hashFunction(stringa)).prossimo = Nothing
End If
End Sub
Vediamo...
294---abc
309---fgh
317---fds
321---ghr
344---uyj
Confrontando con la lista precedente:
294---abc
309---fgh
317---jhk
321---ghr
344---uyj
Esatto! Come nelle previsioni!
Ora, individuata la collisione, dove andiamo a mettere quel jhk che la funzione hash ha reso uguale al fds?
Dobbiamo scorrere avanti nella lista fino a trovare uno "slot" vuoto.
Innanzitutto è più comodo modificare così la funzione createItem:
Sub createItem(stringa As String)
Dim hf As Integer = hashFunction(stringa)
If nodeArray(hf) Is Nothing Then
nodeArray(hf) = New Nodo
nodeArray(hf).valore = stringa
nodeArray(hf).prossimo = Nothing
End If
End Sub
Quindi...
Sub createItem(stringa As String)
Dim hf As Integer = hashFunction(stringa)
If nodeArray(hf) Is Nothing Then
nodeArray(hf) = New Nodo
nodeArray(hf).valore = stringa
nodeArray(hf).prossimo = Nothing
Else
Do
hf = hf + 1
If nodeArray(hf) Is Nothing Then
nodeArray(hf) = New Nodo
nodeArray(hf).valore = stringa
nodeArray(hf).prossimo = Nothing
End If
Loop
End If
End Sub
Aumentiamo il numero di indice della variabile nodo facente parte della matrice nodeArray, fin quando troviamo una variabile non inizializzata, che inizializziamo con il valore rimastoci "vacante".Proviamo.
Ecco una migliore gestione che evita al ciclo Do... Loop di andare avanti superando i limiti della matrice nodeArray:
Public Class Form1
Dim nodeArray(366) As Nodo
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
createItem("abc")
createItem("fds")
createItem("ghr")
createItem("uyj")
createItem("jhk")
createItem("fgh")
elenca()
End Sub
Sub createItem(stringa As String)
Dim hf As Integer = hashFunction(stringa)
If nodeArray(hf) Is Nothing Then
nodeArray(hf) = New Nodo
nodeArray(hf).valore = stringa
nodeArray(hf).prossimo = Nothing
Else
Do
hf = hf + 1
If hf > UBound(nodeArray) Then Exit Do
If nodeArray(hf) Is Nothing Then
nodeArray(hf) = New Nodo
nodeArray(hf).valore = stringa
nodeArray(hf).prossimo = Nothing
Exit Do
End If
Loop
End If
End Sub
Sub elenca()
For n = 0 To UBound(nodeArray)
If nodeArray(n) Is Nothing Then
Debug.Print(n & "---")
Else
Debug.Print(n & "---" & nodeArray(n).valore)
End If
Next
End Sub
Function hashFunction(stringa As String) As Integer
Dim asciValue As Integer = 0
For n = 1 To Len(stringa)
asciValue += Asc(Mid(stringa, n, 1))
Next
Return asciValue
End Function
End Class
Class Nodo
Public valore As String
Public prossimo As Nodo
End Class
Ed ecco come è stata sistemata la collisione:
294---abc 309---fgh 317---fds 318---jhk 321---ghr 344---uyjEcco, ora "jhk" non sparisce più ma viene "incasellato" con l'indice 318, primo "slot" libero dopo quello con cui si contendeva l'indice.
Confronto con le stringhe da "disporre" nel codice:
createItem("abc")
createItem("fds")
createItem("ghr")
createItem("uyj")
createItem("jhk")
createItem("fgh")
Perfetto!
Ora se io voglio ritrovare il punto in cui si trova la stringa "jhk", come faccio?
Tramite la funzione hash (hashFunction) trovo immediatamente la "locazione" 317. A questo punto faccio un confronto che non mi dà la corrispondenza, in quanto in quella "locazione" io ci trovo "fds". Così con un ciclo "while" scorro le locazioni successive fino a quando il confronto darà esito positivo.
Molto più economico che cercare "jhk" su tutta la matrice nodeArray di sana pianta a cominciare dal primo fino a quando avrò trovato la stringa!
giovedì 10 maggio 2018
Pulsante che attiva sul server il download personalizzato a seconda della transazione.
Ecco: ho creato un file dataselector.php, che ha a che fare con il database.
Ma basta cambiare il valore dell'input di nome "id":
Trovato. il link è questo Ho fatto il copia-incolla e sono riuscito a downloadare i files che avevo nella cartella sul server.
Domani mi studio meglio il codice.
<?php
$servername="localhost";
$username="XXXX";
$password="XXXX";
$database="id3147737_db";
$conn=new mysqli($servername,$username,$password,$database);
if($conn->connect_error){
die("Connessione non riuscita" . $conn->connect_error);
}
$sql="SELECT * FROM Transazioni WHERE id=" .$_POST['id'];
$result=$conn->query($sql);
if($result->num_rows >0){
while($row = $result->fetch_assoc()){
echo "id: " . $row["id"] . " - nome: " . $row["nome"] . "
";
}
}else{
echo "Nessun record trovato";
}
$conn->close();
?>
... e nel file index.php (che in futuro sarà la e-mail mandata al cliente) ci metto il form:
<form action="dataselector.php" method="POST"> <input type="hidden" name="id" value=1> <input type="submit">Nel file dataselector.php ho scritto così l'istruzione sql:
$sql="SELECT * FROM Transazioni WHERE id=" .$_POST['id'];in modo da selezionare nel database Transazioni il record dove il campo id equivale a quello inviato dal form sotto forma di input type="hidden" (cosa che un giorno farà la e-mail mandata al cliente per lo scaricamento) E così con un input type="hidden" name="id" value=1 ho ottenuto il valore corrispondente a ID = 1:
id: 1 - nome: Downloads/gerbert.png
Ma basta cambiare il valore dell'input di nome "id":
<form action="dataselector.php" method="POST"> <input type="hidden" name="id" value=2> <input type="submit">e ottengo:
id: 2 - nome: Downloads/abruzzo.pnge invece con il valore 3:
<form action="dataselector.php" method="POST"> <input type="hidden" name="id" value=3> <input type="submit">...ottengo:
id: 3 - nome: Downloads/bovino.jpgPerfetto! Adesso devo trovare il modo migliore per fare il download.
Trovato. il link è questo Ho fatto il copia-incolla e sono riuscito a downloadare i files che avevo nella cartella sul server.
Domani mi studio meglio il codice.
Iscriviti a:
Post (Atom)