Kezdőlap › Fórumok › Programozás › Permutációk kiíratása bash-ban
- This topic has 6 hozzászólás, 3 résztvevő, and was last updated 17 years, 11 months telt el by
uzsolt.
-
SzerzőBejegyzés
-
2007-08-08-09:22 #2126967
bash-ban annyira nem vagyok jó, hogy ilyeneket írjak, de valahogy úgy kellene nekiállni, mint ahogyan a bicikln működik a számzár. Szóval kell egy két dimenziós tömb, és azokban kell iterálgatni végig. Valami ilyesmit képzelj el (php):
Code:$tomb[]=array(‘lehetoseg0’, ‘lehetoseg1’, ‘lehetoseg2’);Ha ez megvan, akkor szépen csak végig kell rajta menni, és legenrálni a lehetőségeket.
2007-08-08-09:22 #2126968bash-ban annyira nem vagyok jó, hogy ilyeneket írjak, de valahogy úgy kellene nekiállni, mint ahogyan a bicikln működik a számzár. Szóval kell egy két dimenziós tömb, és azokban kell iterálgatni végig. Valami ilyesmit képzelj el (php):
Code:$tomb[]=array(‘lehetoseg0’, ‘lehetoseg1’, ‘lehetoseg2’);Ha ez megvan, akkor szépen csak végig kell rajta menni, és legenrálni a lehetőségeket.
2007-08-08-09:49 #2126969Ez a progi is ezt csinálja/csinálná lényegében. Ha esetleg segít, és valaki valamit észrevesz, akkor egy kicsit kommentelem:
#!/bin/bash
if [ $# -eq 0 ]; then exit ; fi
# Hány mezőre bomlik – csak a vesszőket hagyjuk a szövegben, és a karaktereket megszámoljuk (wc), de előtte még töröljük az újsor-karaktert (tr)
FIELD_NR=$(echo $* | grep -o „,” | tr -d „n” | wc -m)
FIELD_NR=$((FIELD_NR + 2)) # Nem igazán értem, miért +2 kell, miért nem +1# Egy ideiglenes fájlt csinálunk
TEMPFILE=$(mktemp)# A paramétert a „vesszőknél fogva” sorokra tördeljük (awk), az elején levő felesleges szóközöket töröljük (sed) és a TEMPFILE-ba írjuk
echo $* | awk -F „,” {‘for (i=1;i $TEMPFILE# A rekurzív függvénykém
# Hívása: Permutacio hanyadik_szint eddig_generált_karakter_sor
function Permutacio () {# Lokális változók…
local level
local CUR_ROW
local i# Az első paramétert eltároljuk, majd őt „kilökjük” (shift), hogy ne zavarjon bele a generált szövegbe
level=$1
shift# Ha elértük a „bűvös” szintet, akkor az eddig generált karaktersort kiírjuk, és nem rekurvulunk tovább
if [ $level -eq $FIELD_NR ]; then
echo $*
break
fi# A level sorszámú („leveledik” 😉 ) sort kiszedjük a fájlból (sed)
CUR_ROW=$(sed -n „${level}p” $TEMPFILE)
# A level-t eggyel növeljük – bár szerintem ezt a megjegyzést nem is kellett volna ideírni 🙂
level=$((level+1))# Az aktuális sor szóközökkel elválasztott szavain szalad végig az i változó
for i in $CUR_ROW ; do
# Rekurzió, a már megnövelt level-lel, az eddig kapott karaktersor ($*) kibővítve az aktuális „szóval” ($i)
Permutacio $level $* $i
done
}# Rekurzió elkezdése level=1-gyel és üres sorozattal
Permutacio 1# Szerintem az uccsó sor nem szorul magyarázatra
rm $TEMPFILEPróbáltam én debuggolni (különféle echo-üzik), de mintha az történne, hogy a legutolsó szintű for-cikluson nem halad végig, csak az első elemre hajtja végre a ciklusmagot…
2007-08-08-09:49 #2126970Ez a progi is ezt csinálja/csinálná lényegében. Ha esetleg segít, és valaki valamit észrevesz, akkor egy kicsit kommentelem:
#!/bin/bash
if [ $# -eq 0 ]; then exit ; fi
# Hány mezőre bomlik – csak a vesszőket hagyjuk a szövegben, és a karaktereket megszámoljuk (wc), de előtte még töröljük az újsor-karaktert (tr)
FIELD_NR=$(echo $* | grep -o „,” | tr -d „n” | wc -m)
FIELD_NR=$((FIELD_NR + 2)) # Nem igazán értem, miért +2 kell, miért nem +1# Egy ideiglenes fájlt csinálunk
TEMPFILE=$(mktemp)# A paramétert a „vesszőknél fogva” sorokra tördeljük (awk), az elején levő felesleges szóközöket töröljük (sed) és a TEMPFILE-ba írjuk
echo $* | awk -F „,” {‘for (i=1;i $TEMPFILE# A rekurzív függvénykém
# Hívása: Permutacio hanyadik_szint eddig_generált_karakter_sor
function Permutacio () {# Lokális változók…
local level
local CUR_ROW
local i# Az első paramétert eltároljuk, majd őt „kilökjük” (shift), hogy ne zavarjon bele a generált szövegbe
level=$1
shift# Ha elértük a „bűvös” szintet, akkor az eddig generált karaktersort kiírjuk, és nem rekurvulunk tovább
if [ $level -eq $FIELD_NR ]; then
echo $*
break
fi# A level sorszámú („leveledik” 😉 ) sort kiszedjük a fájlból (sed)
CUR_ROW=$(sed -n „${level}p” $TEMPFILE)
# A level-t eggyel növeljük – bár szerintem ezt a megjegyzést nem is kellett volna ideírni 🙂
level=$((level+1))# Az aktuális sor szóközökkel elválasztott szavain szalad végig az i változó
for i in $CUR_ROW ; do
# Rekurzió, a már megnövelt level-lel, az eddig kapott karaktersor ($*) kibővítve az aktuális „szóval” ($i)
Permutacio $level $* $i
done
}# Rekurzió elkezdése level=1-gyel és üres sorozattal
Permutacio 1# Szerintem az uccsó sor nem szorul magyarázatra
rm $TEMPFILEPróbáltam én debuggolni (különféle echo-üzik), de mintha az történne, hogy a legutolsó szintű for-cikluson nem halad végig, csak az első elemre hajtja végre a ciklusmagot…
2007-08-08-09:59 #2126971Hopp, meg is van!
Azt hittem, hogy a break „csak” a függvényből lép ki. Ezt meg is teszi, de az épp aktuálisan futó for (az előző rekurzió) is megszakad. Ezért a következő a helyes:Code:#!/bin/bashif [ $# -eq 0 ]; then exit ; fi
FIELD_NR=$(echo $* | grep -o „,” | tr -d „n” | wc -m)
FIELD_NR=$((FIELD_NR + 2))TEMPFILE=$(mktemp)
echo $* | awk -F „,” {‘for (i=1;i $TEMPFILE
function Permutacio () {
local level
local CUR_ROW
local ilevel=$1
shiftif [ $level -eq $FIELD_NR ]; then
echo $*
elseCUR_ROW=$(sed -n „${level}p” $TEMPFILE)
level=$((level+1))for i in ${CUR_ROW} ; do
Permutacio $level $* $i
done
fi
}Permutacio 1
rm $TEMPFILE
És a szám is stimmel:
Code:$ ./perm 1 2 3 , a b c , x y z | wc -l
27(persze a permutációk is megfelelőek, csak 27 sort nem írok még ide)
2007-08-08-09:59 #2126972Hopp, meg is van!
Azt hittem, hogy a break „csak” a függvényből lép ki. Ezt meg is teszi, de az épp aktuálisan futó for (az előző rekurzió) is megszakad. Ezért a következő a helyes:Code:#!/bin/bashif [ $# -eq 0 ]; then exit ; fi
FIELD_NR=$(echo $* | grep -o „,” | tr -d „n” | wc -m)
FIELD_NR=$((FIELD_NR + 2))TEMPFILE=$(mktemp)
echo $* | awk -F „,” {‘for (i=1;i $TEMPFILE
function Permutacio () {
local level
local CUR_ROW
local ilevel=$1
shiftif [ $level -eq $FIELD_NR ]; then
echo $*
elseCUR_ROW=$(sed -n „${level}p” $TEMPFILE)
level=$((level+1))for i in ${CUR_ROW} ; do
Permutacio $level $* $i
done
fi
}Permutacio 1
rm $TEMPFILE
És a szám is stimmel:
Code:$ ./perm 1 2 3 , a b c , x y z | wc -l
27(persze a permutációk is megfelelőek, csak 27 sort nem írok még ide)
2009-12-04-20:02 #1886878Szóval a következővel fordulnék a nagyérdeműhöz: hogy-hogy nem, egy olyan dologra lenne szükségem, ami (bizonyos értelemben) permutációkat ír ki.
Egész konkrétan:Code:a b c
x y z
1 2 3kupacokból mindent mindennel írjon ki, tehát az első karakter az első sorból, a második karakter a második sorból, a harmadik a harmadikból, stb. származzon.
Neki is estem, gondoltam paraméterként átadom, és a „sorokat” vesszővel választom el, ebben az esetben az átadott paraméterlista:Code:a b c , x y z , 1 2 3Nyilván a legkézenfekvőbb megoldás a rekurzió, de valahogy egy apró gikszer csak van a progiban. Először is a progi:
Code:#!/bin/bashif [ $# -eq 0 ]; then exit ; fi
FIELD_NR=$(echo $* | grep -o „,” | tr -d „n” | wc -m)
FIELD_NR=$((FIELD_NR + 2))TEMPFILE=$(mktemp)
echo $* | awk -F „,” {‘for (i=1;i
$TEMPFILE function Permutacio () {
local level
local CUR_ROW
local ilevel=$1
shiftif [ $level -eq $FIELD_NR ]; then
echo $*
break
fiCUR_ROW=$(sed -n „${level}p” $TEMPFILE)
level=$((level+1))for i in $CUR_ROW ; do
Permutacio $level $* $i
done
}Permutacio 1
rm $TEMPFILE
Szóval a működése:
$ ./perm a b c , x y z , 1 2 3
a x 1
a y 1
a z 1
b x 1
b y 1
b z 1
c x 1
c y 1
c z 1
# Tehát a harmadik csoporton nem megy végig
$ ./perm a b c , x y z , 1 2 3 , szilva
a x 1 szilva
a x 2 szilva
a x 3 szilva
a y 1 szilva
a y 2 szilva
a y 3 szilva
a z 1 szilva
a z 2 szilva
a z 3 szilva
b x 1 szilva
b x 2 szilva
b x 3 szilva
b y 1 szilva
b y 2 szilva
b y 3 szilva
b z 1 szilva
b z 2 szilva
b z 3 szilva
c x 1 szilva
c x 2 szilva
c x 3 szilva
c y 1 szilva
c y 2 szilva
c y 3 szilva
c z 1 szilva
c z 2 szilva
c z 3 szilva
$ ./perm a b c , x y z , 1 2 3 , szilva | wc -l
27
# Tehát a permutációk száma stimmelTehát ilyen hekkeléssel tudom csak a jó működésre rábírni. Persze utána törlöm a végéről a szilva szót, de azért mégis, hol a hiba? Esetleg egy elegánsabb megoldás? (lehetőleg bash-ban, csak a móka kedvéért)
-
SzerzőBejegyzés
- Be kell jelentkezni a hozzászóláshoz.
legutóbbi hsz