Permalänk
Medlem

Hjälp med C++ övning

Tjena Sweclockers! Det är så att jag har börjat läsa Bjarne Stroustrups Programming: Principles and Practise using C++ och har fastnat på en uppgift i flertalet dagar nu. Jag skall använda Eratosthenes såll för att beräkna alla primtal upp till 100 helt enkelt. Jag vill inte direkt ha en färdig lösning utan ser helst att någon förklarar vad jag har gjort för fel. Här har ni koden:

#include<iostream> #include<string> #include<vector> #include<algorithm> #include<cmath> using namespace std; inline void keep_window_open() { char ch; cin >> ch; } vector<int>primes{ 2 }; vector<int>not_primes; int val_max = 100; int done = 0; int main() { for (int p : primes) { //Check the current prime if (p < val_max) { //Is current prime less than max value? for (int n = 2;n <= val_max;n += p) { //Loop from 2-100 incrementing by the prime not_primes.push_back(n); //Add prime*n to not_primes } sort(not_primes.begin(), not_primes.end()); for (int i : not_primes) { //Loop through list of primes for (int l = 3;l < val_max;++l) { //Go from 3-100 if (l > p && l != i) { //Check if number is greater than last prime and it isn't marked in not_primes primes.push_back(l); done = 1; break; } } if (done = 1) { //If done with this run, break break; } } done = 0; //Reset exit condition } } for (int p : primes) { cout << p << "\n"; } keep_window_open(); }

Får detta error: Expression: vector iterator not incrementable.
Primes innehåller 2 och 3 men jag ser att den första loopen inte körs mer än en gång. Jag förstår helt enkelt inte VARFÖR?!

Är det för lite information för att ni skall kunna hjälpa mig så får ni gärna ryta till.

Permalänk
Medlem

@DinMatta:
Rent spontant brukar det vara en dålig idé att ändra storlek på vectorer/listor etc som du loopar igenom. Dvs att du lägger till element i primes samtidigt som du loopar över primes. Jag kan inte svara på om det är ett av dina fel men det känns inte helt 100. Det är definitivt fel om du skulle loopat över en lista och ta bort element mitt i för att sedan fortsätta loopa över resterande element, men det borde vara samma sak när du lägger till element eftersom vector internt kan allokera om sin interna array.

if (done = 1) { //If done with this run, break break; }

Här får done en tilldelning vilket troligen returnerar sant vid lyckad tilldelning, jämförelse gör du med == operatorn.

Sedan har jag ingen koll på Eratosthenes såll för att avgöra vad du borde göra annorlunda i din algoritm.

/ Jonas

Permalänk
Skrivet av DinMatta:

Tjena Sweclockers! Det är så att jag har börjat läsa Bjarne Stroustrups Programming: Principles and Practise using C++ och har fastnat på en uppgift i flertalet dagar nu. Jag skall använda Eratosthenes såll för att beräkna alla primtal upp till 100 helt enkelt. Jag vill inte direkt ha en färdig lösning utan ser helst att någon förklarar vad jag har gjort för fel. Här har ni koden:

<coderino>

Får detta error: Expression: vector iterator not incrementable.
Primes innehåller 2 och 3 men jag ser att den första loopen inte körs mer än en gång. Jag förstår helt enkelt inte VARFÖR?!

Är det för lite information för att ni skall kunna hjälpa mig så får ni gärna ryta till.

Ett par saker:
Följande loop:

for (int n = 2;n <= val_max;n += p) { //Loop from 2-100 incrementing by the prime not_primes.push_back(n); //Add prime*n to not_primes }

allokerar apamycket minne (198 * 4 = 792 Bytes) varje varv den yttre loopen går. Eftersom en std::vector flyttas för att kunna ha alla element sekvensiellt ifall mer minne behöver allokeras kommer detta äta prestanda och minne. Eventuellt kan det resultera i att det helt enkelt inte finns plats för fler intar...
På min burk låser sig programmet i detta:

┌─[aarsus]->[zephi]:~/Desktop └──>>./a.out terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc Aborted (core dumped) Exit 134

(Ser medan jag skriver att @jangs svarat på problemet med = vs ==, tack!)

Jag skulle börja med att ordna så att du ersätter elementen i not_primes, eventuellt byta ut std::vector mot int[]....
För trött för att komma med vettig hjälp egentligen just nu, tyvärr :/

Edit: förtydligade

Visa signatur

Vill du ha svar från mig bör du citer
Segmentation fault (core dumped)

Permalänk
Medlem
Skrivet av DinMatta:

Tjena Sweclockers! Det är så att jag har börjat läsa Bjarne Stroustrups Programming: Principles and Practise using C++ och har fastnat på en uppgift i flertalet dagar nu. Jag skall använda Eratosthenes såll för att beräkna alla primtal upp till 100 helt enkelt. Jag vill inte direkt ha en färdig lösning utan ser helst att någon förklarar vad jag har gjort för fel. Här har ni koden:

#include<iostream> #include<string> #include<vector> #include<algorithm> #include<cmath> using namespace std; inline void keep_window_open() { char ch; cin >> ch; } vector<int>primes{ 2 }; vector<int>not_primes; int val_max = 100; int done = 0; int main() { for (int p : primes) { //Check the current prime if (p < val_max) { //Is current prime less than max value? for (int n = 2;n <= val_max;n += p) { //Loop from 2-100 incrementing by the prime not_primes.push_back(n); //Add prime*n to not_primes } sort(not_primes.begin(), not_primes.end()); for (int i : not_primes) { //Loop through list of primes for (int l = 3;l < val_max;++l) { //Go from 3-100 if (l > p && l != i) { //Check if number is greater than last prime and it isn't marked in not_primes primes.push_back(l); done = 1; break; } } if (done = 1) { //If done with this run, break break; } } done = 0; //Reset exit condition } } for (int p : primes) { cout << p << "\n"; } keep_window_open(); }

Får detta error: Expression: vector iterator not incrementable.
Primes innehåller 2 och 3 men jag ser att den första loopen inte körs mer än en gång. Jag förstår helt enkelt inte VARFÖR?!

Är det för lite information för att ni skall kunna hjälpa mig så får ni gärna ryta till.

Ett litet tips är att skriva ut spårkod, det brukar kunna hjälpa till om man inte är säker på vad som egentligen pågår bakom kulisserna. I ditt fall skulle jag, utöver == delen nämnd ovan, ta och skriva ut värdena på l och p och fundera lite över dem och varför det stannar där.

Visa signatur

Desktop: AMD 3950X, 64 GB RAM, Nvidia 4070 ... (Windows 11)
Serverdesktop: AMD 5600G, 64 GB RAM (Proxmox)
Labbmiljö: Supermicro SC825 X9DRi-F 2xE5-2667v2 64GB RAM
Kamera: Canon R5, Canon RF 100-500, Laowa 100mm f/2.8, Canon RF 24-70 f/2,8

Permalänk
Medlem

@DinMatta: Om du ändrar storlek på en container (vector i ditt fall) så kan du riskera att dina iteratorer blir invaliderade. Enligt cplusplus hemsida så sker detta när containern behöver realloceras. Om du inte har väldigt bra koll när reallocering sker, så är förslaget att hålla dig borta från att lägga till eller ta borta element från din vector inuti loopen som loopar över containern i fråga.

Ett alternativ som kan vara användbart om du vet något om vektorns storlek är att preallocera med vector::reserve()

Vad gäller ditt specifika fall så skulle jag använda en vektor med tal som ännu inte "sållats", initierad med alla tal upp till 100. Sedan loopar du över den vektorn tills den är tom med en while-sats. Hur du ska plocka ur tal ur vektorn har du redan koll på.

Visa signatur

Louqe Ghost S1 MK3 | Asus ROG Strix B660-I Gaming WiFi | Intel Core i7 12700K | nVidia RTX 2070 Super FE | Corsair 64GB (2x32GB) DDR5 5600MHz CL40 Vengeance | Samsung 980 PRO M.2 NVMe SSD 2TB | Corsair SF750 750W 80+ Platinum | Noctua NH-L12 Ghost S1 edition | Kablar från pslate customs | 2 stk Dell Ultrasharp 3014 | Logitech MX Keys | Logitech MX Anywhere

Permalänk
Medlem

Som @TheAvenger sagt så garanterar en std::vector att minnet ligger sekventiellt ordnat. Detta är INTE en länkad lista eller något annat dumt, utan den är en "tunn" datatyp som ger lika bra eller bättre prestanda en raw memory arrays (beroende på kompilator) vid front->back eller back-front access pattern. Ursäkta svengelskan här.

En av Bjarne Stroustrup's stora mål i livet, har han sagt, är att döda c arrays, och std:vector är en datatyp som är vänlig för processorns cache-system och prediktor. Tänkte det kunde peppa dig lite när nu vector inte funkar riktigt som du tänkt

Visa signatur

Louqe Ghost S1 MK3 | Asus ROG Strix B660-I Gaming WiFi | Intel Core i7 12700K | nVidia RTX 2070 Super FE | Corsair 64GB (2x32GB) DDR5 5600MHz CL40 Vengeance | Samsung 980 PRO M.2 NVMe SSD 2TB | Corsair SF750 750W 80+ Platinum | Noctua NH-L12 Ghost S1 edition | Kablar från pslate customs | 2 stk Dell Ultrasharp 3014 | Logitech MX Keys | Logitech MX Anywhere

Permalänk
Medlem

@DinMatta:
Lyckades fixa det till slut. Är dock lite sur iochmed att man inte fick reda på detta under kapitlet >:(

Tack för att ni var så vänliga mot en så förvirrad nybörjare som mig!