Räkna ut vilken veckodag ett viss datum.

Permalänk
Medlem

Räkna ut vilken veckodag ett viss datum.

Hej, jag försöker lära mig C++ och själva kodantet går bra. mina "algoritmer" är däremot inte lika bra.
Just nu har jag blivit utmanad att skriva en kod som kan räkna ut vilken veckodag ett viss datum är.
detta är vad jag kommit fram till hittills.
det konstiga är att det funkar för alla dagar i år 2013, men inga andra år av dom jag provat.
har suttit i flera dagar och bara stirrat på koden och googlat mig vansinnig men jag förstår inte varför det blir fel...

#include <iostream> #include <cmath> #include <cstdlib> using namespace std; int main(){ int year, day, tot, veckodag, namn, days, year1, skottdagar, x, exess, month; cout << "what year are you interested in (after 1904)?" << endl; cin >> year; year1 = year - 1904; exess = year1 % 4; skottdagar = year1 / 4 + exess; days = year1 * 365 + skottdagar; cout << "what numeric month are you interested in ?" << endl; cin >> month; { switch (month) { case 1: x=0; break; case 2: x=31; break; case 3: x=59; break; case 4: x=90; break; case 5: x=120; break; case 6: x=151; break; case 7: x=181; break; case 8: x=212; break; case 9: x=243; break; case 10: x=273; break; case 11: x=304; break; case 12: x=334; break; default: cout << "The month you entered is incorrect" << endl; break;}} cout << "what day are you interested in?" << endl; cin >> day; tot = days + x + day; veckodag = tot % 7;{ cout << veckodag << endl; cout << "The day you looking for is "; if (veckodag == 0) cout << "Thursday"; else if (veckodag == 1) cout << "Friday"; else if (veckodag == 2) cout << "Saturday"; else if (veckodag == 3) cout << "Sunday"; else if (veckodag == 4) cout << "Monday"; else if (veckodag == 5) cout << "Tuesday"; else if (veckodag == 6) cout << "Wednesday"; } return (0); }

Dold text
Visa signatur

i5 3570k / Asus p8z77-i Deluxe / Asus Gtx680 DCII / Corsair Ax 750w / Ocz Petrol 256GB / Corsair Vengeance 16GB

Permalänk
Medlem

Tycker du gör det lite svårt och jobbigt för dig.
Försök ta en titt på arrayer, fungerar väldigt bra i denna uppgift.
Sen försök alltid att hålla dig till ett språk gärna engelska, försök namnge variabler så det är lätt att förstå vad dom gör och ha för funktion.
Tex. variablen x är inte så bra, då det bruka vara en räknar/index etc.

Sen förstår jag inte varför du blandar in 1940?
Sen är din leapyear (skottår) inte riktigt korrekt vad jag kan se, om det är det du är ute efter?
Byt ut din switch mot en array, din veckodag till en enum.
Dela upp din kod i funktioner/metoder.
Lägg till validering för, leapday, year, day, month etc...
Och glöm inte att lägga till kommentarer i koden.

const int DAYS[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; enum MONTH { jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec }; //Så här kan din koll för skottår se ut inline bool isLeapYear(int year) { return (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)); }

Hoppas detta kanske hjälper dig lite, annars får du skrika till

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Medlem
Skrivet av NoPaiN^:

Tycker du gör det lite svårt och jobbigt för dig.
Försök ta en titt på arrayer, fungerar väldigt bra i denna uppgift.
Sen försök alltid att hålla dig till ett språk gärna engelska, försök namnge variabler så det är lätt att förstå vad dom gör och ha för funktion.
Tex. variablen x är inte så bra, då det bruka vara en räknar/index etc.

Sen förstår jag inte varför du blandar in 1940?
Sen är din leapyear (skottår) inte riktigt korrekt vad jag kan se, om det är det du är ute efter?
Byt ut din switch mot en array, din veckodag till en enum.
Dela upp din kod i funktioner/metoder.
Lägg till validering för, leapday, year, day, month etc...
Och glöm inte att lägga till kommentarer i koden.

const int DAYS[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; enum MONTH { jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec }; //Så här kan din koll för skottår se ut inline bool isLeapYear(int year) { return (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)); }

Hoppas detta kanske hjälper dig lite, annars får du skrika till

okej tack!
för det första, vet att det går att göra mycke enklare. men mina kompisar har redan gjort på det sättet, dom fick det som skoluppgift, också började jag fundera på ett eget sätt att göra det på och kom fram till det här.
för det andra, variablerna suger, jag vet xD det bara blev så

1904 måste jag ha med för att jag behöver ett skottår att utgå från. tanken är ju att man ska räkna ut antalet dagar från ett fast datum till det man är ute efter. och då är det meningen att 1904 ska vara det fasta datumet då det är det första skottåret efter 1806.
kan du förklara hur skottårsuträknaren fungerar? vet att den inte varit helt korrekt förut då den inte räknar bort år delbara med 100. därför jag räknat från 1904 och frammåt.
tack för tipsen iaf. ska försöka implentera dom i koden

Visa signatur

i5 3570k / Asus p8z77-i Deluxe / Asus Gtx680 DCII / Corsair Ax 750w / Ocz Petrol 256GB / Corsair Vengeance 16GB

Permalänk
Medlem

Vi kan säga så här om skottår, skottår är jämnt delbart med 4, utom vid sekelskiften (jämna 100 år), då är året endast skottår om det är jämnt delbart med 400. Alltså 2100 är inte det medans 2000 är det.

Dvs kan du använda koden jag pasta i förra inlägget, och du behöver inte ha nån start som 1940.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Medlem
Skrivet av NoPaiN^:

Vi kan säga så här om skottår, skottår är jämnt delbart med 4, utom vid sekelskiften (jämna 100 år), då är året endast skottår om det är jämnt delbart med 400. Alltså 2100 är inte det medans 2000 är det.

Dvs kan du använda koden jag pasta i förra inlägget, och du behöver inte ha nån start som 1940.

men måste jag inte ha något att jämföra med? den där koden räknar väll bara ut om året som är inmatat är ett skottår eller inte.

Visa signatur

i5 3570k / Asus p8z77-i Deluxe / Asus Gtx680 DCII / Corsair Ax 750w / Ocz Petrol 256GB / Corsair Vengeance 16GB

Permalänk
Medlem
Skrivet av NoPaiN^:

Tycker du gör det lite svårt och jobbigt för dig.
Försök ta en titt på arrayer, fungerar väldigt bra i denna uppgift.
Sen försök alltid att hålla dig till ett språk gärna engelska, försök namnge variabler så det är lätt att förstå vad dom gör och ha för funktion.
Tex. variablen x är inte så bra, då det bruka vara en räknar/index etc.

Sen förstår jag inte varför du blandar in 1940?
Sen är din leapyear (skottår) inte riktigt korrekt vad jag kan se, om det är det du är ute efter?
Byt ut din switch mot en array, din veckodag till en enum.
Dela upp din kod i funktioner/metoder.
Lägg till validering för, leapday, year, day, month etc...
Och glöm inte att lägga till kommentarer i koden.

const int DAYS[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; enum MONTH { jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec }; //Så här kan din koll för skottår se ut inline bool isLeapYear(int year) { return (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)); }

Hoppas detta kanske hjälper dig lite, annars får du skrika till

Försöker använda din inline bool, men får "error function-definition is not allowed here before'{' token"
har googlat lite och förstår att man inte kan define en ny funktion i en redan existerande funktion. så jag måste lägga den utanför main. men hur kallar jag på den då? alltså vad ska jag ha i main funktionen för att kunna använda den?
lite luddigt kanske men hoppas du förstår.

Visa signatur

i5 3570k / Asus p8z77-i Deluxe / Asus Gtx680 DCII / Corsair Ax 750w / Ocz Petrol 256GB / Corsair Vengeance 16GB

Permalänk
Medlem
Skrivet av Mr.Azum:

Försöker använda din inline bool, men får "error function-definition is not allowed here before'{' token"
har googlat lite och förstår att man inte kan define en ny funktion i en redan existerande funktion. så jag måste lägga den utanför main. men hur kallar jag på den då? alltså vad ska jag ha i main funktionen för att kunna använda den?
lite luddigt kanske men hoppas du förstår.

Lättast är väl att lägga den innan main och skippa inline det var bara dumt av mig att lägga till det.
Sen anropar du den typ så här..

if( isLeapYear(year) ) { //Aha skottår, då gör vi så här... } else { //Aha inte skottår, då gör vi så här istället... }

Sen det här med ett startår, ja nån form utav vetenskap måste vi ha om en dag för att kunna lösa uppgiften.
Sista februari nått år kan bra.

Om vi tar ett exempel, 1900 då är sista feb onsdag.
Om vi nu säger att användaren matar in 1936-10-7.
Varje år som inte är skott år går vi en dag framåt, skottår två.
Alltså måste vi loopa, kolla om det skottår och lägga till.
Koden kan bli nåt sånt här för att kolla vilken dag sista feb är på angivet år.
Sen får du beräkna månad, dagar med hjälp av att du vet sista feb på angivet år.

diffYears = year - startYear; //1936 - 1900 finalDay = startDay; //Onsdag 3 for(int i = 1; i <= diffYears; i++) { if(isLeapYear(startYear+i)) { if(finalDay >= 7) { finalDay = 2; } else if(finalDay == 6) { finalDay = 1; } else { finalDay += 2; } } else { if(finalDay >= 7) { finalDay = 1; } else { finalDay++; } } }

Ett annat alternativ kan vara, för varje multipel av 12 år som vi lägger till år 1900, så flyttas den
sista februari 1 dag framåt.
diffYears = year - startYear; //1936 - 1900
multipel = diffYears / 12;
Här är alltså multipel 3, flyttar vi då 3 steg fram så får vi ut att sista feb 1936 är en lördag.
Sen beräknar man som vanligt månader, dagar från sista feb.

Blev väldigt mycket text ser jag nu men hoppas du förstår.
Sen går det självklart att göra koden bättre och jag har inte tagit med en del kollar etc...

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Medlem
Skrivet av NoPaiN^:

gjorde så här istället

#include <iostream> using namespace std; int main(){ int year, day, days, years, weekday, month; int scount = 0; const int dais[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; enum month { jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec }; cout << "What year are you interested in?" << endl; cin >> year; cout << "What day are you interested in?" << endl; cin >> day; cout << "What month are you interested in? jan, feb, etc" << endl; cin >> month; cout << endl; for (int i = 0; i < 2096 - year; i++) { if ((year + i) % 400 == 0 || ((year + i) % 100 != 0 && (year + i) % 4 == 0)) { scount++; } } years = 2096 - year; days = (years + 1) * 365 + scount + month + day; cout << scount << endl; cout << days; return 0; } //2096 är den sista december. och det är en måndag.

har jag använt enum och const int korrekt?

Visa signatur

i5 3570k / Asus p8z77-i Deluxe / Asus Gtx680 DCII / Corsair Ax 750w / Ocz Petrol 256GB / Corsair Vengeance 16GB

Permalänk
Medlem

Din dekleration av din const array och enum är ok, tänk bara på att försöka namnge dom så du lätt förstår.
Finns olika standard man kan följa hur man ange saker, underlättar enormt sen när det blir mycket stora projekt.
Eller följer du det som du tycker känns bra, kanske stora bokstäver med C för en konstant, stora bokstäver med E för enum..

Men ditt sätt att använda enum är inte korrekt.

int year, day, days, years, weekday, month; cout << "What month are you interested in? jan, feb, etc" << endl; cin >> month;

Matar du in tex. jan så kommer month att få väldigt konstiga värden.
Vill du använda cin till en enumvariabel måste du dessutom deklarerar din egna >> operator vilket kan vara lite mycket på den här nivån.
Var kanske lite dumt av mig att blanda in enums.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770