Kom-pa-TI-bilitet
C# Hitta alla primtal mellan 1 och talet som anges som parameter
Andra for-loopen har fortfarande fel i loop-villkoret. Det står nu: loopa så länge i2 är större än kvadratroten av num.
Tänk också på att num bara representerar det sista talet du vill testa: din yttre loop är tänkt att representera mängden 1 till num
ps: du är nära nu.
Vet inte hur jag ska göra så att den testar 1-numret man matar in. Behöver hjälp hur jag ska kunna göra så att num representerar mängden 1 till numret man matar in.
Det finns lite egenskaper hos tal som inte är primtal som går att använda för att snabba upp sökandet.
Det finns ett lemma som går något i stil med "Alla tal är ett primtal eller en produkt av primtal"
Så din algoritm borde vara något i stil med
x: en lista av primtal
x <- [2] (börja med en lista med bara 2 i)
for(i = 3 < max, i++) (börja iterare på 3){
isPrime <- true;
foreach(x' in x){ (för alla primtal i listan)
if(i % x' == 0){
ifPrime <- false
break; //om talet ej är prima, avbryt
}
}
if(isPrime)
{
x <- x:[i] //lägg till i till primtalslistan.
}
}
Det finns lite egenskaper hos tal som inte är primtal som går att använda för att snabba upp sökandet.
Det finns ett lemma som går något i stil med "Alla tal är ett primtal eller en produkt av primtal"
Så din algoritm borde vara något i stil med
x: en lista av primtal
x <- [2] (börja med en lista med bara 2 i)
for(i = 3 < max, i++) (börja iterare på 3){
isPrime <- true;
foreach(x' in x){ (för alla primtal i listan)
if(i % x' == 0){
ifPrime <- false
break; //om talet ej är prima, avbryt
}
}
if(isPrime)
{
x <- x:[i] //lägg till i till primtalslistan.
}
}
Skulle gärna vilja hålla mig till en algoritmen jag har, bryr mig inte så mycket om hur fort det går. Vet du hur jag kan få num att representera 1-talet man sätter som tak?
Skulle gärna vilja hålla mig till en algoritmen jag har, bryr mig inte så mycket om hur fort det går. Vet du hur jag kan få num att representera 1-talet man sätter som tak?
num representerar ju redan det inskrivna värdet. Det är din yttre for-loop som representerar alla primtal mellan 1 och num
num representerar ju redan det inskrivna värdet. Det är din yttre for-loop som representerar alla primtal mellan 1 och num
Hur ser det ut nu då?
int num;
Console.WriteLine("Mata in nummer: ");
num = Convert.ToInt32(Console.ReadLine());
for (int i = 1; i < num; i++)
{
for (int j = i; j < Math.Sqrt(num); j++)
{
if (num % j != 0)
{
Console.WriteLine(j);
}
}
}
Hur ser det ut nu då?
int num;
Console.WriteLine("Mata in nummer: ");
num = Convert.ToInt32(Console.ReadLine());
for (int i = 1; i < num; i++)
{
for (int j = i; j < Math.Sqrt(num); j++)
{
if (num % j != 0)
{
Console.WriteLine(j);
}
}
}
Det är fortfarande fel i din inre loop. Bland annat ska utskriften komma i den yttre loopen, du loopar fel i den inre, du testar fel variabel och du behöver en variabel till för att hålla koll på om den inre loopen avgjorde att du hade ett primtal eller ej.
Det känns som om du gör ändringar på måfå. Förstår att du börjar bli less på detta nu men ta ett steg tillbaka och fråga din lärare om råd.
Kom-pa-TI-bilitet
Det är fortfarande fel i din inre loop. Bland annat ska utskriften komma i den yttre loopen, du loopar fel i den inre, du testar fel variabel och du behöver en variabel till för att hålla koll på om den inre loopen avgjorde att du hade ett primtal eller ej.
Det känns som om du gör ändringar på måfå. Förstår att du börjar bli less på detta nu men ta ett steg tillbaka och fråga din lärare om råd.
Eftersom att jag är väldigt ny i C# så förstår jag inte alltid vad du menar, hur jag ska göra saker osv. De är inte alltid lika självklart för mig som för dig. Förstår att du antagligen börjar tröttna på mitt tjat om den här tråden. Frågade faktiskt min lärare om råd/hjälp idag, gjorde mig dock inte så mycket klokare, du ser ju vad som ändrats i koden, det var de hon gjorde. Verkade inte som hon visste hur man skulle göra, då hon var tvungen och tänka i ca 10 minuter, detta var sedan vad hon hade kommit fram till och sa att jag skulle fundera på.
Eftersom att jag är väldigt ny i C# så förstår jag inte alltid vad du menar, hur jag ska göra saker osv. De är inte alltid lika självklart för mig som för dig. Förstår att du antagligen börjar tröttna på mitt tjat om den här tråden. Frågade faktiskt min lärare om råd/hjälp idag, gjorde mig dock inte så mycket klokare, du ser ju vad som ändrats i koden, det var de hon gjorde. Verkade inte som hon visste hur man skulle göra, då hon var tvungen och tänka i ca 10 minuter, detta var sedan vad hon hade kommit fram till och sa att jag skulle fundera på.
Kikade lite på det du skrivit och mitt huvudtips till att förstå är att kommentera vad du gör i din kod, på så sätt är det lättare att förstå vad som går fel.
Tänk på att ett tal är ett primtal om det enbart är jämnt delbart med sig själv och med ett men ger en rest i alla andra fall.
Som det har nämnt tidigare i tråden räcker det egentligen att testa ett tal mot alla andra primtal mindre än dess rot, detta skulle bli effektivare men känns inte direkt nödvändigt i ditt fall då det viktigaste nu är att fokusera på att förstå det man gör.
Kan ge två exempel att fundera på när du utformar din algoritm, säg att du vill kolla om 5 och 6 är primtal.
Först testar du 5, eftersom 5%2, 5%3, 5%4 alla är skilda från noll betyder det att det inte finns något tal mindre än 5 som delar det jämnt ut, altså ett primtal, samma experiement med 6 ger att det inte är ett primtal då 6%2 och 6%3 är lika med noll.
kort sagt, har du ett heltal n skall samtliga divisioner med heltal mellan 2 och n-1 ge en rest för att det skall vara ett primtal, hoppas det tankesättet kan få dig på rätt spår utan att avslöja för mycket
Eftersom att jag är väldigt ny i C# så förstår jag inte alltid vad du menar, hur jag ska göra saker osv. De är inte alltid lika självklart för mig som för dig. Förstår att du antagligen börjar tröttna på mitt tjat om den här tråden. Frågade faktiskt min lärare om råd/hjälp idag, gjorde mig dock inte så mycket klokare, du ser ju vad som ändrats i koden, det var de hon gjorde. Verkade inte som hon visste hur man skulle göra, då hon var tvungen och tänka i ca 10 minuter, detta var sedan vad hon hade kommit fram till och sa att jag skulle fundera på.
Jag gillar din envishet
Vi skulle kunna testa en annan approach, skita i alla optimeringar (kvadratrötter och fans moster) och bryta ner problemet i mindre, logiska bitar. Backtracka lite och reda ut vissa grejer. Är du med?
Till att börja med vill jag definiera vad ett primtal är. sv.wikipedia.org definierar ett primtal så här:
Ett primtal är ett heltal p, som är större än 1 och vars enda delare är ±1 och ±p.
Det vill säga, för att godtyckligt tal n skall vara ett primtal gäller att
n är större än 1
n inte går att dela jämnt med något tal mellan 2 och n-1, såvida n inte är 2:
då 2 bara går att dela med sig själv och med 1 är 2 ett primtal
Punkt 1 är enkel att formulera: om n är större än 1 kan n vara ett primtal
if (n > 1) {
... testa om n är jämnt delbart med något av talen mellan 2 och n-1
} else {
... n kan inte vara ett primtal om det är lika med eller mindre än 1.
}
För att se om ett tal är jämnt delbart med ett annat kollar vi vad resten blir av en division. Jag vill minnas att detta var något man höll på med i slutet av lågstadiet och sedan glömde bort när man gick över till att räkna med decimaler, liggande stolar och andra konstigheter.
För att få fram resten av en division använder vi oss av modulo-operatorn, vilken i programmeringssammanhang vanligtvis är ett procenttecken. Om det inte finns någon rest efter en division har man en kvot som är ett heltal, och om kvoten är ett heltal har divisionen gått jämnt ut. Det är av den enkla anledningen som man testar om resultatet av en modulo-operation är lika med 0.
if (n % ??? == 0) {
...
}
Frågetecknena representerar ett godtyckligt tal mellan 2 och n-1. Om resultatet av operationen [n % ???] är 0 har divisionen gått jämnt ut och n är inte ett primtal.
Om man var envis skulle man kunna testa ett primtal så här:
int n = 5;
if (n > 1 && n % 2 != 0 && n % 3 != 0 && n % 4 != 0) {
Console.WriteLine(n + " är ett primtal!");
} else {
Console.WriteLine("Nix, " + n + " är inget primtal.");
}
Som du kan se skulle det bli ganska tråkigt att skriva if-satsen när n är ett större tal, säg runt 42 eller så. För att göra livet lättare använder vi en for-loop:
for (int i = 2; i < n - 1; i++) {
... om resultatet av [n % i] == 0 är n inte ett primtal
}
For-loopar är fula och svårlästa men väldigt praktiska. Något som däremot bara är praktiskt är metoder. Det är snudd på överkurs men i just detta fall, när vi letar efter ett sätta att hitta primtal, är en metod helt oslagbar.
I grund och botten ser en metod ut så här:
returtyp Metodnamn(parametertyp parameternamn) {
... metod-kod
}
returtypen är den typ av värde som metoden kommer returneras. Exempel på detta är string, int och bool, som denna metod kommer returnera.
parametertyp är samma sak fast åt andra hållet och specifierar vad metoden kan arbeta med för värde. Eftersom vi vill testa ett heltal använder vi typen int
Metodnamn är ett valfritt ord som börjar med en bokstav eller underscore och kan följas av siffror, bokstäver eller underscore. Exempel på tillåtna namn är Glass, U2, KamelFodral och _Skriv_Inte_Så_Här. Otillåtna namn är 42IsANumber, 5+5=11 och ?!OMG?!
bool IsPrime(int n) {
om n > 1:
testa om n är jämnt delbart med mängden [2 -> n-1]
annars:
return false;
}
Det du ser ovan är pseudokod; "halvkod" som beskriver kod. Det som är fetmarkerat är riktig C#-kod. Sista raden, return false;, säger att metoden IsPrime returnerar bool-värdet false om n inte är ett primtal.
Genom att pussla med de exempel som getts kan du faktiskt få en helt fungerande IsPrime-metod som löser 95 % av uppgiften åt dig. Det slutgiltiga steget är att använda IsPrime-metoden i ännu en for-loop för att testa alla tal mellan 1 och det av användaren angivna talet num (som du redan har lyckats läsa in i tidigare kod-exempel).
Ett riktigt trevligt program att ha till hands när man sitter och testar C#-kod är LINQPad. Namnet är ganska missvisande då det går att använda till mycket mer än LINQ. Jag rekommenderar att du laddar ner det och labbar lite med det som tagits upp här. Skapa en ny "query" och tryck på CTRL + 3 för att få en liten main-metod där du kan testa kod.
Kom-pa-TI-bilitet
Jag gillar din envishet
Vi skulle kunna testa en annan approach, skita i alla optimeringar (kvadratrötter och fans moster) och bryta ner problemet i mindre, logiska bitar. Backtracka lite och reda ut vissa grejer. Är du med?
Till att börja med vill jag definiera vad ett primtal är. sv.wikipedia.org definierar ett primtal så här:
Det vill säga, för att godtyckligt tal n skall vara ett primtal gäller att
n är större än 1
n inte går att dela jämnt med något tal mellan 2 och n-1, såvida n inte är 2:
då 2 bara går att dela med sig själv och med 1 är 2 ett primtal
Punkt 1 är enkel att formulera: om n är större än 1 kan n vara ett primtal
if (n > 1) {
... testa om n är jämnt delbart med något av talen mellan 2 och n-1
} else {
... n kan inte vara ett primtal om det är lika med eller mindre än 1.
}
För att se om ett tal är jämnt delbart med ett annat kollar vi vad resten blir av en division. Jag vill minnas att detta var något man höll på med i slutet av lågstadiet och sedan glömde bort när man gick över till att räkna med decimaler, liggande stolar och andra konstigheter.
För att få fram resten av en division använder vi oss av modulo-operatorn, vilken i programmeringssammanhang vanligtvis är ett procenttecken. Om det inte finns någon rest efter en division har man en kvot som är ett heltal, och om kvoten är ett heltal har divisionen gått jämnt ut. Det är av den enkla anledningen som man testar om resultatet av en modulo-operation är lika med 0.
if (n % ??? == 0) {
...
}
Frågetecknena representerar ett godtyckligt tal mellan 2 och n-1. Om resultatet av operationen [n % ???] är 0 har divisionen gått jämnt ut och n är inte ett primtal.
Om man var envis skulle man kunna testa ett primtal så här:
int n = 5;
if (n > 1 && n % 2 != 0 && n % 3 != 0 && n % 4 != 0) {
Console.WriteLine(n + " är ett primtal!");
} else {
Console.WriteLine("Nix, " + n + " är inget primtal.");
}
Som du kan se skulle det bli ganska tråkigt att skriva if-satsen när n är ett större tal, säg runt 42 eller så. För att göra livet lättare använder vi en for-loop:
for (int i = 2; i < n - 1; i++) {
... om resultatet av [n % i] == 0 är n inte ett primtal
}
For-loopar är fula och svårlästa men väldigt praktiska. Något som däremot bara är praktiskt är metoder. Det är snudd på överkurs men i just detta fall, när vi letar efter ett sätta att hitta primtal, är en metod helt oslagbar.
I grund och botten ser en metod ut så här:
returtyp Metodnamn(parametertyp parameternamn) {
... metod-kod
}
returtypen är den typ av värde som metoden kommer returneras. Exempel på detta är string, int och bool, som denna metod kommer returnera.
parametertyp är samma sak fast åt andra hållet och specifierar vad metoden kan arbeta med för värde. Eftersom vi vill testa ett heltal använder vi typen int
Metodnamn är ett valfritt ord som börjar med en bokstav eller underscore och kan följas av siffror, bokstäver eller underscore. Exempel på tillåtna namn är Glass, U2, KamelFodral och _Skriv_Inte_Så_Här. Otillåtna namn är 42IsANumber, 5+5=11 och ?!OMG?!
bool IsPrime(int n) {
om n > 1:
testa om n är jämnt delbart med mängden [2 -> n-1]
annars:
return false;
}
Det du ser ovan är pseudokod; "halvkod" som beskriver kod. Det som är fetmarkerat är riktig C#-kod. Sista raden, return false;, säger att metoden IsPrime returnerar bool-värdet false om n inte är ett primtal.
Genom att pussla med de exempel som getts kan du faktiskt få en helt fungerande IsPrime-metod som löser 95 % av uppgiften åt dig. Det slutgiltiga steget är att använda IsPrime-metoden i ännu en for-loop för att testa alla tal mellan 1 och det av användaren angivna talet num (som du redan har lyckats läsa in i tidigare kod-exempel).
Ett riktigt trevligt program att ha till hands när man sitter och testar C#-kod är LINQPad. Namnet är ganska missvisande då det går att använda till mycket mer än LINQ. Jag rekommenderar att du laddar ner det och labbar lite med det som tagits upp här. Skapa en ny "query" och tryck på CTRL + 3 för att få en liten main-metod där du kan testa kod.
Tack för all hjälp. Har pratat mer med min lärare och hon tyckte att det var en svårt uppgift att göra, vi satt i ca 30 min och kunde in få ihop den själva. Dock var det 2 andra i klassen som googlade och kopierade en kod, de fick den att funka. Hon sa att jag inte skulle oroa mig för mitt betyg, eftersom att det var ett bra försök jag hade gjort.
Tack för all hjälp, är mycket tacksam!
- Igår Nvidia: "Energieffektiva RTX 4060 sparar hundralappar" 36
- Igår MSI Geforce RTX 4060 Ventus 2X OC – bra prestanda vid 1080p men medioker kylare 45
- Igår Noctua släpper monteringsram för "deliddade" Ryzen 7000-processorer 15
- Igår Nvidias nästa arkitektur för Geforce kommer år 2025 58
- 27 / 6 Afox släpper kompakt Geforce RTX 4090 36
- Igår Veckans fråga: Vilket operativsystem föredrar du? 76
- Igår Bilar med smarta inslag ger fler dumma fel 58
- 27 / 6 Telekombranschen: "Smarta glasögon ersätter telefoner inom fem år" 88
- 26 / 6 Lastpass-användare rasar – kan inte logga in 59
- 26 / 6 Inet frågar SweClockers – Vad skulle du vilja förbättra på Inet.se? 53
- Fel post (dödsbo)8
- Bildvisnings program5
- PSVR2 - diskussionstråd444
- Kommer flytta till stan och mitt wifi kommer säkert synas av hundratals människor varje dag. Vilken router ska jag köpa och hur ska den ställas in?6
- Solfilm till fönster för sommarvärmen. Behöver råd.30
- Hjälp angående gammal psu och "nytt" grafikkort2
- Ert dyraste ” datormisstag”?402
- MSI Geforce RTX 4060 Ventus 2X OC – bra prestanda vid 1080p men medioker kylare45
- Vad lyssnar du på just nu?12615
- Krönika: Teknikutvecklingen avstannar – men det gör också uppgraderingsbehovet66
- Säljes LG 27'' UltraGear 27GP950 4K Nano IPS 160 Hz HDMI 2.1
- Säljes Star Wars Jedi AMD kod
- Säljes Trasig Xiaomi Mi Electric Scooter (M365) Svart
- Säljes 5800x3D + x570 Meg Unify + be quiet! Dark Rock Slim
- Säljes AMD ASUS DUAL RX6700XT
- Säljes Dell OptiPlex 7010
- Säljes Datordelar: i5 9600k + 1070 GTX mm.
- Säljes 1080 TI | Vattenblock | 1TB SSD | Apple Watch 4 Stainless | Hörlurar | Mikrofon
- Säljes Intressekoll: Xbox Series S 512Gb samt Switch Oled 64Gb Vit
- Säljes Gamingdator RTX 3090, i9-10900K, 32GB ram
- Nvidia: "Energieffektiva RTX 4060 sparar hundralappar"36
- MSI Geforce RTX 4060 Ventus 2X OC – bra prestanda vid 1080p men medioker kylare45
- Veckans fråga: Vilket operativsystem föredrar du?76
- Bilar med smarta inslag ger fler dumma fel58
- Noctua släpper monteringsram för "deliddade" Ryzen 7000-processorer15
- Nvidias nästa arkitektur för Geforce kommer år 202558
- Microsoft vill strömma Windows från molnet71
- Starfield utvecklas med AMD:s välsignelse148
- Telekombranschen: "Smarta glasögon ersätter telefoner inom fem år"88
- En av tre svenskar använder annonsblockerare79
Externa nyheter
Spelnyheter från FZ
- Alan Wake och CoD: Kallt krig snart på PS Plus, enligt läcka igår
- Red Dead Redemption åldersmärkt igen i Korea – det spekuleras i remaster igår
- Fallout London flyttas för att slippa Starfield-konkurrensen igår
- Minecraft-filmen kan ha hittat sin Steve – Pedro "The Last of Us-Joel" Pascal igår
- Stor Diablo IV-patch släppt, mer XP och ombalanserade klasser igår