Where a calculator on the ENIAC is equipped with 18,000 vacuum tubes and weighs 30 tons, computers in the future may have only 1,000 vacuum tubes and weigh only 1.5 tons.
– Popular Mechanics, March 1949
Of wil je misschien alle mogelijke combinaties genereren? Zoek dan eens op "permutatie"
[ Voor 6% gewijzigd door Creepy op 03-01-2006 17:22 ]
"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney
Als je 'panman' als invoer hebt, wat betekent de volgorde van letters dan voor de mogelijke uitvoer? Is het van belang dat de 'a' twee keer voorkomt en de 'p' maar één keer?
Schrijf desnoods een voorbeeld helemaal uit. Zo is het absoluut niet duidelijk waar je heen wilt.
Sorry als ik onduidelijk was, maar ik weet zeker waar ik heen wilSoultaker schreef op dinsdag 03 januari 2006 @ 17:35:
Geen wonder dat het je het niet kunt implementeren, als je niet eens duidelijk kunt formuleren waar je naartoe wil.
Als je 'panman' als invoer hebt, wat betekent de volgorde van letters dan voor de mogelijke uitvoer? Is het van belang dat de 'a' twee keer voorkomt en de 'p' maar één keer?
Schrijf desnoods een voorbeeld helemaal uit. Zo is het absoluut niet duidelijk waar je heen wilt.
Stel, ik heb als input PAN, dan wil ik alle mogelijke combinaties genereren, met als enige eis dat er nooit 2x dezelfde letter achter elkaar staat
Dus:
PAN
NAP
APN
NAN
PAP
APA
ANA
enz.
maar NIET
AAP
PPA
NNA
NNP
etc
Ik wil dus alle mogelijke permutaties (dat woord zocht ik inderdaad!), behalve diegene waar 2x dezelfde letter achter elkaar staat. Maar met alle lukt het waarschijnlijk wel om die met dubbele letters eruit te vegen.
Where a calculator on the ENIAC is equipped with 18,000 vacuum tubes and weighs 30 tons, computers in the future may have only 1,000 vacuum tubes and weigh only 1.5 tons.
– Popular Mechanics, March 1949
Dan, zou je een random reeel getal R kunnen genereren tussen de 0 en de 1. Afhankelijk van de integer representatie van R (0 of 1), ga je dan de te kiezen random letter ONDER X ( namelijk {LETTER | LETTER >= 0 EN LETTER < X} ), danwel BOVEN X (namelijk {LETTER | LETTER > X EN LETTER < 26}) verkrijgen. Voor de eerste iteratie heb je dan de hele range van 0 t/m 25.
LETTER kan je bepalen mbv R, door deze te vermenigvuldigen mbv numeric promotion met je 'interval' (boven of onder X), en dan de integer representatie nemen van de uitkomst daarvan.
Vervolgens nadat je bepaalt hebt welke letter het gaat worden, assign je LETTER aan X, i.e. X = LETTER en ga je door naar de volgende iteratie net zo lang tot je de max lengte van je woord bereikt hebt.
[ Voor 29% gewijzigd door prototype op 04-01-2006 01:32 ]
1
2
3
4
5
6
7
8
9
10
11
12
13
| inputString = 'blablaadafdsa'
outputString = '';
currentChar = null;
for( 0 to x )
currentChar = GetRandomChar( inputString, currentChar )
outputString += currentChar
function GetRandomChar( stringToPickFrom, excludeChar )
chosenChar = null
while( chosenChar == null || chosenChar == excludeChar )
chosenChar = stringToPickFrom[ random ]
return chosenChar
end function |
[ Voor 7% gewijzigd door Woy op 04-01-2006 09:40 ]
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Wat ik zou doen is het volgende:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| StringLength := 5
CharSet := "abc"
Generate("", "")
Sub Generate(CurChar, CurString)
String := ""
For Each Char In CharSet
IF Char != CurChar
String := CurString & Char
IF(Length(String) = StringLength)
Write(String)
Else
Generate(Char, String)
EndIF
EndIf
NEXT FOR
End Sub |
[ Voor 8% gewijzigd door mrBussy op 04-01-2006 09:56 ]
Verwijderd
Als je ALLE combinaties wilt hebben, dan moet je niet met random getallen werken.Daaruit wil ik alle mogelijke combinaties (tot een max aan lengte) genereren.
Loop gewoon alles af, en check daarna of aan de voorwaarde is voldaan.
Voor de duidelijkheid laat ik het zien in pseudocode, met het domste algoritme mogelijk. Je kunt het genereren van alle combinaties ook in 1 loop verpakken, maar dat is afhankelijk van de programeertaal hoe je dat doet.
Maak eerst een functie die checkt of er verboden combinaties in staan:
1
2
3
4
5
6
7
8
| check=function(lettercombi)
{
verboden=false
loop i=1 tot length(lettercombi)-1
if lettercombi[i]==lettercombi[i+1] then verboden=true
next
} |
Vervolgens loop je alle letters af:
stel je wilt tot 3 letters lengte, en je hebt 26 letters
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
| 1 letter: loop i=1 tot 26 res_1[i] = letter [i] next 2 letters k=1 loop i=1 tot 26 loop j=1 tot 26 temp=letter [i] & letter[j] if (check( temp ) == false) then res_2[k] = temp k=k+1 endif next next 3 letters k=1 loop i=1 tot 26 loop j=1 tot 26 loop l=1 tot 26 temp=letter [i] & letter[j] & letter[l] if (check( temp ) == false) then res_2[k] = temp k=k+1 endif next next next |
[ Voor 10% gewijzigd door Verwijderd op 04-01-2006 10:07 ]
Ik heb nu deze code, in PHP:
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
| <?php function check($lettercombi){ for ($i=0;$i<strlen($lettercombi)-1;$i++) { #echo "$i-Testing: $lettercombi: -", $lettercombi[$i],"-VS-", $lettercombi[$i+1],"<br>"; if ($lettercombi[$i] == $lettercombi[$i+1]) { return(false);} } return(true); } $letters='panman'; #echo $letters[3]; echo strlen($letters); for ($i=0;$i<strlen($letters);$i++) { for ($j=0;$j<strlen($letters);$j++) { for ($k=0;$k<strlen($letters);$k++) { $temp=$letters[$i].$letters[$j].$letters[$k]; if (check($temp)) {$res2[]=$temp;} } } } echo "<pre>"; var_dump($res2); ?> |
Die werkt, dus dat is fijn! Nu ga ik nog even kijken of ik de recursieve ook aan de praat kan krijgen, want ik wil natuurlijk eigenlijk meer dan 3 letters kunnen genereren, zonder nogmeer loopjes...
Where a calculator on the ENIAC is equipped with 18,000 vacuum tubes and weighs 30 tons, computers in the future may have only 1,000 vacuum tubes and weigh only 1.5 tons.
– Popular Mechanics, March 1949
[ Voor 3% gewijzigd door prototype op 04-01-2006 16:28 ]
string(4) "papa"
[1]=>
string(4) "papn"
[2]=>
string(4) "papm"
[3]=>
string(4) "papa"
[4]=>
string(4) "papn"
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
| <?php $letters=array('p','a','n','m','a','n'); $StringLength=4; Generate("", ""); function Generate($CurChar, $CurString) { $temp=""; global $letters, $StringLength; foreach ($letters as $char) { echo "Letter: ", $char, "<br>", $a++; if ($char!=$CurChar ) { $temp= $CurString .$char; echo "temp: ", $temp,"- togoto:", $StringLength, "- lengthnu:", strlen($temp); if(strlen($temp)>=$StringLength) { echo "<hr>Stoppen:", $temp,"<hr>"; $GLOBALS[res3][]=$temp; } else { Generate($char, $temp); } } } } var_dump($GLOBALS[res3]); ?> |
Where a calculator on the ENIAC is equipped with 18,000 vacuum tubes and weighs 30 tons, computers in the future may have only 1,000 vacuum tubes and weigh only 1.5 tons.
– Popular Mechanics, March 1949
Verwijderd
Het werkt niet met letters, maar met getallen. Dat kun je zo veranderen door elk getal dat eruit komt een index te laten zijn naar de array met letters. Verder is het iets algemener omdat elke kolom een ander aantal 'letters' mag hebben.
Input:
maxcat: een array met lengte van aantal letters, met in elke cell het maximaal aantal letters.
bv je wilt alle woorden maken van 4 letters lang, en je hebt 8 verschilllende letters, dan is maxcat (8,8,8,8)
Output:
mindex
de array met alle combinaties.
vb met bovenstaande getallen is mindex een array van 8^4 bij 4
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
| subroutine multi_index (maxcat,mindex)
!index a contingency table in an anti lexicographical manner
implicit none
integer, intent(out),dimension(:,:) ::mindex
integer, intent(in),dimension(:) ::maxcat
logical ::more=.false.
integer, dimension(size(maxcat)) ::mindex1
integer ::i
do i=1,product(maxcat)
call index_next (maxcat,mindex1,more)
mindex(i,:)=mindex1
enddo
contains
subroutine index_next(maxcat, mindex, more)
implicit none
integer,dimension(:) :: maxcat
integer :: i,inc
integer, dimension(size(maxcat)) :: mindex
logical more
if (more==.false. ) then
mindex(1:size(maxcat)) = 1
else
inc = 0
do
inc = inc + 1
if ( mindex(inc) < maxcat(inc) ) exit
mindex(inc) = 1
end do
mindex(inc) = mindex(inc) + 1
end if
more = .false.
do i = 1, size(maxcat)
if ( mindex(i) < maxcat(i) ) more = .true.
end do
end subroutine
end subroutine |