Meddelande

Du befinner dig just nu på en äldre version av Pluggakuten, gamla.pluggakuten.se. Nya Pluggakuten lanserades den 6 februari 2017 och du finner forumet på www.pluggakuten.se.

På gamla.pluggakuten.se kan du fortfarande läsa frågorna och svaren som ställts, men du kan inte skapa ett nytt konto eller nya trådar. Nya frågor och nytt konto skapar du på det nya forumet, välkommen dit!

Python kod

wow_08
Medlem

Offline

Registrerad: 2016-02-16
Inlägg: 52

Python kod

Hej!

Skulle någon kunna hjälpa mig med följande uppgift? Jag vet inte hur jag ska tänka här smile

Skriv en rekursiv funktion, almostPrime(i, f) som returnerar en lista med tal som talet i är jämt delbara med. Listan ska innehålla alla tal från och med f till och i, som i är jämt delbara med. Exempel:
   >>> almostPrimeFact(111,2)
   [3, 37, 111]
   >>> almostPrimeFact(38,2)
   [2, 19, 38]
   >>> almostPrimeFact(38,3)
   [19, 38]
   >>>

 
Henrik E
Medlem

Offline

Registrerad: 2015-09-22
Inlägg: 3189

Re: Python kod

Konstigt namn eftersom det inte har med primtal att göra. Jag kallar den factors(n,f) i stället.
Rekursiv betyder att den ska anropa sej själv, alltså vara av typen
def factors(n,f):
    - - -
    b=factors(..,..)
    - - -
    return factorlist

Det rekursiva anropet ska vara ett enklare problem, till exempel factors(n-1,f) eller factors(n,f+1).
I det här fallet är den senare lämplig. En rekursiv tanke är så här:
"Faktorlistan (n,f) är oftast samma som faktorlistan (n,f+1), men om f är en faktor i n ska man lägga till f först i listan."
Och så måste man ha ett basfall och det är när f>n, för då blir listan tom.
def factors(n,f):
    if f>n: return []
    b=factors(n,f+1)
    if .... : b=[f]+b     # om f delar n
    return b

 
Pistolero
Medlem

Offline

Registrerad: 2008-12-09
Inlägg: 633

Re: Python kod

wow_08 skrev:

Hej!

Skulle någon kunna hjälpa mig med följande uppgift? Jag vet inte hur jag ska tänka här smile

Skriv en rekursiv funktion, almostPrime(i, f) som returnerar en lista med tal som talet i är jämt delbara med. Listan ska innehålla alla tal från och med f till och i, som i är jämt delbara med. Exempel:
   >>> almostPrimeFact(111,2)
   [3, 37, 111]
   >>> almostPrimeFact(38,2)
   [2, 19, 38]
   >>> almostPrimeFact(38,3)
   [19, 38]
   >>>

När du ska göra en rekursiv funktion så återanvänder du samma funktion. Funktionen anropar alltså sig själv och på så viss kan ett stort problem göras till ett litet. smile

Om vi kollar på en icke-rekursiv funktion, så får vi följande:

Kod:

def almostPrimeFact(i, f):
    arr = []
    for x in range(f, i+1):
        if i%x == 0:
            arr.append(x)
    return arr

print( almostPrimeFact(111, 2) )
print( almostPrimeFact(38, 2) )
print( almostPrimeFact(38, 3) )

För att göra det rekusivt måste funktionen anropa sig själv. Det innebär att man måste ha ett basfall 0! och resterande körs rekusivt n!.

Vi kan ha basfallet att i%f == 0, vilket innebär att i/f ger ett heltal när i%f == 0. Om fallet inte är den, då kan vi återanropa funktionen och testa på nytt genom att höja upp i ett steg. För att det inte ska vara oändligt (för det måste stanna nån gång), så kan man lägga in en if-sats att i > f.

Vi får då en rekusiv funktion:

Kod:

def almostPrimeFact(i, f):
    arr = []
    if i%f == 0:
        arr.append(f)
    if i > f:
        arr.extend(almostPrimeFact(i, f+1))
    return arr

print( almostPrimeFact(111, 2) )
print( almostPrimeFact(38, 2) )
print( almostPrimeFact(38, 3) )

Det som händer är följande:
Steg 1: almostPrimeFact(111, 2) => i%f == 0 är falst, i > f är sant, vilket gör att almostPrimeFact(i, f+1) körs.
Steg 2: almostPrimeFact(111, 3) => i%f == 0 är sant och vi lägger in f i listan, i > f är också sant, vilket gör att vi kör almostPrimeFact(i, f+1).
Steg 3: almostPrimeFact(111, 4) => i%f == 0 är falskt, i > f är sant så vi kör almostPrimeFact(i, f+1).
Steg 4: almostPrimeFact(111, 5) => i%f == 0 är falskt, i > f är sant.
Steg 5: almostPrimeFact(111, 6) => i%f == 0 är falskt, i > f är sant.
o.s.v.
Steg 36: almostPrimeFact(111, 37) => i%f == 0 är sant, så vi sparar 37 i listan, i > f är sant.
Steg 37: almostPrimeFact(111, 38) => i%f == 0 är falskt, i > f är sant.
Steg 38: almostPrimeFact(111, 39) => i%f == 0 är falskt, i > f är sant.
o.s.v.
Steg 110: almostPrimeFact(111, 111) => i%f == 0 är sant, så vi sparar det i listan, i > f är falskt, så vi kör inte if-satsen, och därför avslutas funktionen och vi erhåller listan [3, 37, 111]

Både den icke-rekusiva och den rekusiva funktionen utför precis samma sak. Vilket man föredrar att använda är en smaksak. Dock kan rekusiv funktion vara mer lämplig vid lite mer svårare uppgifter, t.ex. om man vill göra ett program som löser sudoku. Då räcker det med några rader kod med binära sökträd, istället för att kämpa sig igenom med icke-rekusiva funktioner i form av massor av for-loopar, där man snabbt tappar bort sig i röran.

Senast redigerat av Pistolero (2016-10-12 18:08)

 
Nikkster
Medlem

Offline

Registrerad: 2011-12-13
Inlägg: 237

Re: Python kod

Pistolero skrev:

wow_08 skrev:

Hej!

Skulle någon kunna hjälpa mig med följande uppgift? Jag vet inte hur jag ska tänka här smile

Skriv en rekursiv funktion, almostPrime(i, f) som returnerar en lista med tal som talet i är jämt delbara med. Listan ska innehålla alla tal från och med f till och i, som i är jämt delbara med. Exempel:
   >>> almostPrimeFact(111,2)
   [3, 37, 111]
   >>> almostPrimeFact(38,2)
   [2, 19, 38]
   >>> almostPrimeFact(38,3)
   [19, 38]
   >>>

När du ska göra en rekursiv funktion så återanvänder du samma funktion. Funktionen anropar alltså sig själv och på så viss kan ett stort problem göras till ett litet. smile

Om vi kollar på en icke-rekursiv funktion, så får vi följande:

Kod:

def almostPrimeFact(i, f):
    arr = []
    for x in range(f, i+1):
        if i%x == 0:
            arr.append(x)
    return arr

print( almostPrimeFact(111, 2) )
print( almostPrimeFact(38, 2) )
print( almostPrimeFact(38, 3) )

För att göra det rekusivt måste funktionen anropa sig själv. Det innebär att man måste ha ett basfall 0! och resterande körs rekusivt n!.

Vi kan ha basfallet att i%f == 0, vilket innebär att i/f ger ett heltal när i%f == 0. Om fallet inte är den, då kan vi återanropa funktionen och testa på nytt genom att höja upp i ett steg. För att det inte ska vara oändligt (för det måste stanna nån gång), så kan man lägga in en if-sats att i > f.

Vi får då en rekusiv funktion:

Kod:

def almostPrimeFact(i, f):
    arr = []
    if i%f == 0:
        arr.append(f)
    if i > f:
        arr.extend(almostPrimeFact(i, f+1))
    return arr

print( almostPrimeFact(111, 2) )
print( almostPrimeFact(38, 2) )
print( almostPrimeFact(38, 3) )

Det som händer är följande:
Steg 1: almostPrimeFact(111, 2) => i%f == 0 är falst, i > f är sant, vilket gör att almostPrimeFact(i, f+1) körs.
Steg 2: almostPrimeFact(111, 3) => i%f == 0 är sant och vi lägger in f i listan, i > f är också sant, vilket gör att vi kör almostPrimeFact(i, f+1).
Steg 3: almostPrimeFact(111, 4) => i%f == 0 är falskt, i > f är sant så vi kör almostPrimeFact(i, f+1).
Steg 4: almostPrimeFact(111, 5) => i%f == 0 är falskt, i > f är sant.
Steg 5: almostPrimeFact(111, 6) => i%f == 0 är falskt, i > f är sant.
o.s.v.
Steg 36: almostPrimeFact(111, 37) => i%f == 0 är sant, så vi sparar 37 i listan, i > f är sant.
Steg 37: almostPrimeFact(111, 38) => i%f == 0 är falskt, i > f är sant.
Steg 38: almostPrimeFact(111, 39) => i%f == 0 är falskt, i > f är sant.
o.s.v.
Steg 110: almostPrimeFact(111, 111) => i%f == 0 är sant, så vi sparar det i listan, i > f är falskt, så vi kör inte if-satsen, och därför avslutas funktionen och vi erhåller listan [3, 37, 111]

Både den icke-rekusiva och den rekusiva funktionen utför precis samma sak. Vilket man föredrar att använda är en smaksak. Dock kan rekusiv funktion vara mer lämplig vid lite mer svårare uppgifter, t.ex. om man vill göra ett program som löser sudoku. Då räcker det med några rader kod med binära sökträd, istället för att kämpa sig igenom med icke-rekusiva funktioner i form av massor av for-loopar, där man snabbt tappar bort sig i röran.

Bara fliker in lite allmänt:

Ditt tänk är i princip iterativt. Rekursion är en helt annan problemlösningsstrategi och man bör inte öht blanda in eller jämföra med iterativ kod. Med detta tänk löser man knappast bland de enklare rekursiva problem.

Jag tycker Henriks inlägg efterliknar det rekursiva tänket mycket mer.

När vi designar rekursiva algoritmer är basfallen de fall Där vi direkt kan svara på frågan / lösa problemen. Kan vi inte det, vill vi bryta ned vårt problem till en mindre instans I SAMMA FORM. Det mindre problemet löser vi genom att anropa rekursivt. Det slutgiltliga steget blir att skapa en lösning på originala problemet mha sina delllösningar.


Fråga gärna om .NET (toknörd) och datavetenskap. Försöker titta hit då och då när det finns tid.
 
wow_08
Medlem

Offline

Registrerad: 2016-02-16
Inlägg: 52

Re: Python kod

Jag såg aldrig era svar, märkte precis notisen. TACK för hjälpen!!

 


Sidfot

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson

Powered by Mattecentrum
 |  Denna sida använder cookies |  Kontakta oss |  Feedback |