Vinnaren i pepparkakshustävlingen!
  • 1
  • 2
2018-04-19, 17:14
  #1
Medlem
Det är så att jag behöver hjälp med en c++ uppgift, som jag inte direkt vet hur jag ska lösa.

Programmet ska slumpa fram och skriva ut en lottorad på 7 siffror, mellan 1-35.

Detta är en skoluppgift som jag försöker att lösa. Vi fick en kod som inte fungerade, som vi skulle lösa. Jag har löst det mesta (förhoppningsvis), men när jag kör koden så skriver den ut 6 stycken siffror istället för 7. Någon som kan se något/några problem i koden nedanför?

Tackar ödmjukast för hjälp!

Kod:
#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
    
int lottorad[7]; // Ett heltalsfält som lagrar lottoraden
    
bool lika=false;

    for(
int i=1i<7i++){
        
lottorad[i]=rand()%35+1// Slumpar ett tal mellan 1 och 35

        
for(int j=1j<ij++) // Loopar igenom de tidigare slumpade tal och kontrollerar om det aktuella talet redan har dragits
            
if(lottorad[i]==lottorad[j])
                
lika=true;

        if(
lika) {   // Om det aktuella talet redan dragits så minskas i med 1. Man går alltså tillbaka ett steg i loopen och slumpar ett nytt tal
            
i--;
            
lika=false;
            }

            else {  
// Om det aktuella talet inte hade dragits tidigare så skrivs det ut
            
cout << lottorad[i] << endl;
            }

    }

    return 
0;

Citera
2018-04-19, 17:18
  #2
Medlem
4yoonlys avatar
Raden for(int i=1; i<7; i++)

I<7 I måste vara under 7 för vilket i praktiken då endast kan vara högst 6.

---edit
Det vill säga sätt 8 istället för 7.
Citera
2018-04-19, 17:20
  #3
Medlem
Citat:
Ursprungligen postat av 4yoonly
Raden for(int i=1; i<7; i++)

I<7 I måste vara under 7 för vilket i praktiken då endast kan vara högst 6.

Jo men precis, jag har också tänk på det. Ändrade till <=7, men problemet då är att koden skriver ut samma siffra två gånger. Då är ju min fråga vad som mer är fel :/
Citera
2018-04-19, 17:26
  #4
Medlem
4yoonlys avatar
Citat:
Ursprungligen postat av L3Finschk1
Jo men precis, jag har också tänk på det. Ändrade till <=7, men problemet då är att koden skriver ut samma siffra två gånger. Då är ju min fråga vad som mer är fel :/

Ah ok... om jag skall vara helt ärlig så kan jag inte C (kan läsa det, men har väldigt få gånger skrivit någon vettig programkod i det) och C++ har jag ännu mindre koll på.. Kan dock en massa andra programspråk.

Har du testat att öka arrayen Lottorad till 8?

---edit
Kan ju vara så att du skriver ut 1-8, fast din array är 0-7.
Citera
2018-04-19, 17:28
  #5
Medlem
Citat:
Ursprungligen postat av 4yoonly
Ah ok... om jag skall vara helt ärlig så kan jag inte C (kan läsa det, men har väldigt få gånger skrivit någon vettig programkod i det) och C++ har jag ännu mindre koll på.. Kan dock en massa andra programspråk.

Har du testat att öka arrayen Lottorad till 8?

Tack, det fungerade att ändra till 8..
Har ändrat allt fram och tillbaka, så kommer inte ihåg vad jag har gjort.

Nu ska jag bara försöka förklara varför jag har ändrat så som jag har gjort, hur man nu ska förklara det
Citera
2018-04-19, 17:30
  #6
Medlem
kodsnickrarns avatar
Arrayer i C/C++ börjar indexera på 0, inte 1.

Kod:
for(int i=0;i<7;i++)
{
   lottorad[i]=rand()%35+1;
   ...
}

Edit: om du räknar från 1 - 7 så blir det knas när du använder i som index till din lottorad[] array.

/K
Citera
2018-04-19, 17:49
  #7
Medlem
Cobber Kains avatar
Citat:
Ursprungligen postat av 4yoonly
Ah ok... om jag skall vara helt ärlig så kan jag inte C (kan läsa det, men har väldigt få gånger skrivit någon vettig programkod i det) och C++ har jag ännu mindre koll på.. Kan dock en massa andra programspråk.

Har du testat att öka arrayen Lottorad till 8?

---edit
Kan ju vara så att du skriver ut 1-8, fast din array är 0-7.

Nej, du kan uppenbarligen inte ens läsa C. Så låt bli att svara, tack.

for(int i=1;

ska vara:

for(int i=0;
Citera
2018-04-19, 17:58
  #8
Medlem
4yoonlys avatar
Citat:
Ursprungligen postat av Cobber Kain
Nej, du kan uppenbarligen inte ens läsa C. Så låt bli att svara, tack.

for(int i=1;

ska vara:

for(int i=0;

Jag ber så hemskt mycket om ursäkt. Har du analyserat maskinkoden som kompilatorn skapade så är jag rätt säker på att (icke) användandet av den första variabeln i array'en inte kommer göra någon som helst skillnad. Inte ens på en 8 bitars dator...
Citera
2018-04-19, 18:17
  #9
Moderator
Neksnors avatar
Som redan nämnts kallas första positionen i en array generellt sett för 0, alltså ska for-loopen börja på 0. Bakgrunden är att allt lagras på olika platser (adresser) i minnet som internt är numrerade. Så lottorad[0] (första elementet i arrayen) betyder helt enkelt "adressen till lottorad + 0" osv.

Hur många "beräkningsvarv" behöver ditt program göra för att fixa 7 nummer? Kan det göra effektivare/snabbare?
Citera
2018-04-19, 19:27
  #10
Avstängd
Digitalteknik, datorers hårdvara, processorer, språk (fast det finns några scriptspråk som använder 1-indexering) och mjukvara, alla räknar från basen 0. Man pratar om ettor och nollor, inte tvåor och ettor, och det finns tio siffror: 0-9. Om du alltid kör 0-baserat internt undviker du många off by one-buggar och slipper extra tankekraft på det.

Använd dessutom endast < och >=, inte <= och >, så krånglar du till det ännu mindre. Bara halvöppna intervall, mixa inte med öppna och slutna.

Och när du räknar uppåt: ändra, dvs öka, variabeln i slutet av loopens kropp. När du räknar nedåt: ändra, dvs minska, den i början av kroppen. För att räkna från och med 99 och nedåt, initiera alltså variabeln till 100. For-loopen har automatiskt ändringen av variabeln i slutet, vilket gör den olämplig för nedräkning, men den är ändå bara en snyggare variant av while-loopen och jag pissar på den.

Detsamma gäller postinkrementering (pekare++) för uppåträkning och predekrementering (--pekare) för nedåt, avsky de två andra varianterna som pesten.

För minimalism är bra. Bättre än att kombinera en for-loop med ++j, pekare--, >= och 1-baserad räkning, då är du riktigt i träsket.

När/om datat ska presenteras (eller matas in) i annan form, t.ex. 1-baserat, gör det direkt i samband med detta.

Kod:
/* skriv ut de första tre positiva heltalen */

for (int n = 0; n < 3; n++) {
    cout << 1 + n << '\n';
}

Jag har i alla fall lyckas hålla mig borta från logiska vurpor genom att behandla en "serie" som börjar på 1 likadant som en som börjar på t.ex. 14. Eftersom 0 och 1 är så nära varandra är det nyttigt att hålla dem så separerade som möjligt, annars lockas man att tänka "ett värde hit och dit, vad spelar det för roll". Skillanden mellan 63 och 10678 är roligare att hålla isär.
__________________
Senast redigerad av Eliwood 2018-04-19 kl. 19:34.
Citera
2018-04-21, 12:22
  #11
Medlem
Du borde fundera över hur lottonummer dras på riktigt. Brukar Svenska spel säga "oj, det numret har vi redan dragit, gör ett nytt försök" eller har de en bättre metod som ditt program kan efterlikna?
Citera
2018-04-21, 14:46
  #12
Moderator
RostigHinks avatar
Enligt rubriken gäller det c++ så kan man använda vektorer och lite magisk indexering. Dragning utan återläggning implementeras som att sätta en bolls värde till -1. Loopen testar om värdet är negativt och drar i så fall ett nytt slumptal. For-looparna kräver minst 2011 års standard. Det går att implementera looparna på klassiskt vis om man vill. Detta är bara ett sätt, det finns flera.
Kod:
#include <iostream>
#include <vector>
#include <ctime>

using std::vector;
using std::cout;
using std::endl;

int main() {

  vector<int> bollar{-1,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};
  vector<int> rad{0,0,0,0,0,0,0};

  int boll;
  srand(time(NULL));
  for (auto&& i: rad) {
    do {
      boll = rand() % 35 + 1;  // slumptal mellan 1 och 35
      if (bollar[boll] > 0) {
        i = bollar[boll];
      }
    } while (bollar[boll] < 0);
    bollar[boll] = -1;
  }

  for (auto&& i: rad) {
    cout << i << " ";
  }
  cout << endl;
}
Citera
  • 1
  • 2

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback