webForumDet fria alternativet

Sök efter anagramer i ordlista

ASP

13 svar · 959 visningar · startad av dp81

Medlem sedan okt. 200447 inlägg
Frågan#1

Vilket är det bästa sättet om jag vill söka efter anagram av ett visst ord från en ordlista?

Går det att skriva allt i selectsatsen eller måste jag först lista alla kombinationerna?

/mvh
Daniel

Medlem sedan juni 20019 519 inlägg
#2
<%
dim sWord
sWord = "jeh"

Function SQLSecure(s)
	SQLSecure = Replace(s,"'","''")
End Function

dim sql

'Början av SQL strängen.
sql = "SELECT word From tabell WHERE 1 = 1"

' Kör igenom alla tecken som finns i ordet och lägg in en det i en SQL fråga.
For i = 1 to len(sWord)
	sql = sql & " AND word LIKE '%" & SQLSecure(mid(sWord,i,1) & "") & "%'"
Next

'Skriv ut SQL strängen använd sql-strängen till ditt Recordset.
Response.Write sql 

%>

Kanske?

Medlem sedan juni 20031 837 inlägg
#3

Det blir väl inte riktigt rätt?
då kommer du få med ord som t.ex. "heje", "heeeej" m.m. och de är väl inte anagram på "jeh"?
så man måste begränsa antal förekomster av varje bokstav till samma som finns i ursprungsordet.

Medlem sedan juni 20019 519 inlägg
#4

sant. Räcker det inte att lägga till

sql = sql & " AND Len(word) = " & Len(sWord)

Efter Next?

Medlem sedan juni 20008 205 inlägg
#5

Nope, strängen "bba" motsvarar då "abb". Det effektivaste sättet (dock ej minnesmässigt :) ) jag kan komma på att hitta anagram på, är att varje ord i databasen också finns "sorterat" bokstav för bokstav, och när man vill hitta ett anagram sorterar man då tecknen i ordet man vill hitta anagram för. Sökningen blir skitsnabb eftersom man kan indexera det sorterade fältet.

red. Exempel. Databasen:

word | sortedWord
------------
hej  | ehj
salt | alst
last | alst

För att sen hitta anagram på "salt" skulle man då kunna ställa en SQL-fråga i stil med SELECT word FROM tabellen WHERE sortedWord = 'alst' AND word <> 'salt'.

Sen kan man göra diverse jobb för att få ner minnesförbrukningen (typ att man sparar en hash på det "sorterade ordet" istället för ordet självt) men det är överkurs.

Medlem sedan okt. 200447 inlägg
#6

Att skapa "sortedWord" var faktiskt inte en så dum idé. Blir värre om man vill visa svar som består av två eller fler ord (tex George Bush = He bugs Gore).

Medlem sedan okt. 200447 inlägg
#7

Hur gör man för att sortera ett strängvärde i bokstavsordning?
Alltså göra om ordet "salt" till "alst".

Medlem sedan okt. 200447 inlägg
#8

Har hittat följande, men går det inte att ordna smidigare då jag inte behöver någon split och teckengrupperingar?
http://www.webforum.nu/showthread.php?t=106635&highlight=�ndra+str�ng

Medlem sedan juni 20008 205 inlägg
#9

Att hitta flerordsanagram är jäkligt komplicerat, men går gör det. En googlesökning på "multi-word anagram algorithm" kan kanske ge lite klarhet.

Skulle gärna hjälpa till med de specifika detaljerna hur du får sorterar strängen, men vbscript är så jävla dåligt att jag undvikit att lära mig det :) Men principen är enkel, gör en array med lika många element som strängen du ska sortera, loopa över strängen och använd mid-funktionen för att plocka ut varje tecken från strängen och sen lägga det på motsvarande plats i arrayen (om strängen är "salt" är arrayen ["s", "a", "l", "t"] nu). Sortera arrayen (googla "vbscript sort array", det eländiga språket har ingen inbyggd sorteringsfunktion) och bygg sen upp en sträng från arrayen (["a", "l", "s", "t"] → "alst").

Medlem sedan okt. 200447 inlägg
#10

Jag får inte till det, är det någon som kan skriva hur jag omvandlar ett strängvärde till ett annat i bokstavsordning? (salt = alst)

Medlem sedan juni 20008 205 inlägg
#11

Jag är så sjuk att jag bestämde mig för att fräscha upp min vbs lite. För att göra en array av en sträng kan du göra en funktion som ser ut på följande vis:

Function str2arr(str)
	Dim arr, i
	arr = Array()
	Redim arr(len(str))
	For i = 1 to Len(str) 
		arr(i) = Mid(str, i, 1)
	Next
	str2arr = arr
End Function

Från den får du en array som du måste sortera. Jag vill vara noga med att poängtera att vbscript är ett av de sämsta språken som någonsin uppfunnits, något som uppenbarar sig i att eländet inte ens har en inbyggd sorteringsfunktion. Som tur är finns Internet:
http://www.4guysfromrolla.com/webtech/012799-2.shtml

Sen när du har sorterat arrayen slår du bara ihop den till en sträng igen med join(arrayen, ""). Kort och gott:

Function SortString(str)
	Dim arr
	arr = str2arr(str) ' funktionen ovan
	QuickSort arr, LBound(arr), UBound(arr) ' funktionen från 4guysfromrolla
	SortString = Join(arr, "")
End Function
Medlem sedan okt. 200447 inlägg
#12

Stort tack! Nu funkar det!
På endast 70 rader kod så kan ett strängvärde sorteras i bokstavsordning :-D

Medlem sedan okt. 200447 inlägg
#13

<%
Function str2arr(str)
Dim arr, i
arr = Array()
Redim arr(len(str))
For i = 1 to Len(str)
arr(i) = Mid(str, i, 1)
Next
str2arr = arr
End Function

Sub QuickSort(vec,loBound,hiBound)
Dim pivot,loSwap,hiSwap,temp

'== This procedure is adapted from the algorithm given in:
'== Data Abstractions & Structures using C++ by
'== Mark Headington and David Riley, pg. 586
'== Quicksort is the fastest array sorting routine for
'== unordered arrays. Its big O is n log n

'== Two items to sort
if hiBound - loBound = 1 then
if vec(loBound) > vec(hiBound) then
temp=vec(loBound)
vec(loBound) = vec(hiBound)
vec(hiBound) = temp
End If
End If

'== Three or more items to sort
pivot = vec(int((loBound + hiBound) / 2))
vec(int((loBound + hiBound) / 2)) = vec(loBound)
vec(loBound) = pivot
loSwap = loBound + 1
hiSwap = hiBound

do
'== Find the right loSwap
while loSwap < hiSwap and vec(loSwap) <= pivot
loSwap = loSwap + 1
wend
'== Find the right hiSwap
while vec(hiSwap) > pivot
hiSwap = hiSwap - 1
wend
'== Swap values if loSwap is less then hiSwap
if loSwap < hiSwap then
temp = vec(loSwap)
vec(loSwap) = vec(hiSwap)
vec(hiSwap) = temp
End If
loop while loSwap < hiSwap

vec(loBound) = vec(hiSwap)
vec(hiSwap) = pivot

'== Recursively call function .. the beauty of Quicksort
'== 2 or more items in first section
if loBound < (hiSwap - 1) then Call QuickSort(vec,loBound,hiSwap-1)
'== 2 or more items in second section
if hiSwap + 1 < hibound then Call QuickSort(vec,hiSwap+1,hiBound)

End Sub 'QuickSort

Function SortString(str)
Dim arr
arr = str2arr(str) ' funktionen ovan
QuickSort arr, LBound(arr), UBound(arr) ' funktionen från 4guysfromrolla
SortString = Join(arr, "")
End Function

response.write SortString("testord")
%>

Medlem sedan juni 20031 837 inlägg
#14

använd helst [ kod ] taggen när du skriver in kod, speciellt långa kodstycken.

264 ms totalt · 4 externa anrop · v20260731065814-full.6fe65c25
131 ms — deklarationer (db)
0 ms — hämta statistik (cache)
128 ms — hämta tråd, inlägg och bilagor (db)
128 ms — ändringar (db)