HI1024TEN2_140108 Lösningar

HI1024 Programmering, grundkurs TEN2
2014-01-08
KTH STH Haninge 8.15-13.00
Tillåtna hjälpmedel:
En A4 handskriven på ena sidan med egna anteckningar
Kursboken ”C PROGRAMMING A Modern Approach” K. N. King – helt utan anteckningar
Logga in med tentamenskontot ni får av skrivvakten. Det kommer att ta tid att logga in – ha
tålamod! Logga inte ut förrän ni är klara med hela tentan. Svaren på uppgifterna ska vara program
bestående av en fil som kallas uppg1.c, uppg2.c, uppg3.c, uppg4.c och uppg5.c. Dessa ska sparas
direkt under H:. Även om ni inte löser hela uppgiften så kan ni få delpoäng men ni måste se till att
koden kompilerar och kan köras. Både output och koden bedöms och det är viktigt att denna är
välskriven och uppfyller uppgiftens instruktioner. Välj bra variabelnamn och struktur men lägg inte så
stor vikt vid kommentarer. Kom ihåg ert tentamenskonto. Resultaten kommer att presenteras
kopplade till dessa!
Lycka till
Examinator: Nicklas Brandefelt
Rättande lärare: Nicklas Brandefelt, Fredrik Bergholm
Betygsgränser: Fx-8, E-9, D-11, C-12, B-14, A-16 (MAX-18)
Generella rättningsnormer:
Mycket dåliga variabelnamn ger -1p totalt på provet vid andra tillfället
Inga eller dåliga kommentarer ger -0p på provet
Dålig struktur ger avdrag varje gång
Generellt gäller: -1p per avvikelse, minst -1p om koden ej kompilerar
1. En lek med vanliga heltal (4p)
Vi skapar en följd av heltal på följande sätt: Välj ett tal. Om talet är jämnt dividera med 2, annars
multiplicera med 3 och lägg till 1. Gör nu likadant med resultatet. Fortsätt tills du får 1.
Exempel:
Välj 3
Udda så: 3∙3 + 1 = 10
Jämnt så: 10/2 = 5
Udda så: 3∙5 + 1 = 16
Jämnt så: 16/2 = 8
Jämnt så 8/2 = 4
Jämnt så 4/2 = 2
Jämnt så 2/2 = 1
klar i 7 steg
Skriv ett program som tar in ett positivt heltal från användaren och anger hur många steg (enligt
ovanstående process) som behövs för att komma till 1. Programmet ger användaren möjlighet att mata
in nya tal till dess att denne matar in 0. En körning skall se ut enligt nedan:
Tal: 1
Steg: 0.
Tal: 2
Steg: 1.
Tal: 3
Steg: 7.
Tal: 4
Steg: 2.
Tal: 5
Steg: 5.
Tal: 6
Steg: 8.
Tal: 7
Steg: 16.
Tal: 8
Steg: 3.
Tal: 0
Lösning:
#include <stdio.h>
int main()
{
int tal, n;
do
{
n=0;
printf("Tal: ");
scanf("%d",&tal);
if(tal!=0)
{
while(tal!=1)
{
if(tal%2==0)
tal/=2;
else
tal=3*tal+1;
n++;
}
printf("Steg: %d\n", n);
}
}while(tal!=0);
return 0;
}
2. Par av heltal (4p)
Skriv ett program som slumpar en lista på ett antal par av positiva heltal mellan 1 och 10. Användaren
ska ange hur många par av tal som ska slumpas fram. Talparen ska sedan lagras i en array av structar av
typen
struct talpar
{ int n,m; }
och arrayen ska sedan sorteras med avseende på summan av de båda talen som ingår i varje talpar. Vi
kan tänka oss att programmet hanterar max 10 par av heltal. Interaktionen med användaren ska vara av
följande typ:
Antal talpar (max 10): 4
Resultat:
====================
Talpar 1: (3,2)
Talpar 2: (1,6)
Talpar 3: (3,4)
Talpar 4: (6,7)
<-- Användaren matar in detta
Lösning:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct talpar
{
int n,m;
};
int main()
{
int i, j, antal;
struct talpar talparen[10], ettpar;
srand(time(0));
printf("Antal talpar (max 10): ");
scanf("%d", &antal);
for(i=0;i<antal;i++) {
talparen[i].n=rand()%10+1;
talparen[i].m=rand()%10+1;
}
for(i=0;i<antal;i++)for(j=0;j<i;j++) {
if( talparen[j].n+talparen[j].m > talparen[i].n+talparen[i].m )
{
ettpar = talparen[i];
talparen[i]=talparen[j];
talparen[j] = ettpar;
}
}
printf("Resultat:\n===================\n");
for(i=0;i<antal;i++)
printf("Talpar %d: (%d,%d)\n", i+1, talparen[i].n, talparen[i].m);
return 0;
}
3. Formatering av namn (4p)
Det finns två omvandlingsfunktioner som omvandlar mellan stora och små bokstäver, de heter
toupper() respektive tolower(). Funktionen toupper() omvandlar bokstäver till stora genom att
returnera ett heltal som kan tolkas som en stor bokstav, den fullständiga funktionsprototypen är
int toupper(int c);
och ett anrop kan vara printf(“%c”, toupper('a')); som alltså skulle resultera i utskriften av ett
stort A. Funktionen tolower() fungerar på motsvarande sätt. Dessa funktioner finns i ctype.h som
behöver inkluderas.
Använd dessa funktioner för att formatera namnuppgifter. Ditt program ska ta ett namn som består av
ett antal bokstäver (ett förnamn) följt av exakt ett mellanslag följt av ytterligare ett antal bokstäver (ett
efternamn). Programmet ska se till att begynnelsebokstäverna är stora och alla andra är små. En
provkörning ska se ut enligt nedan:
Namn: jOHnny pAnRIKE
Formaterat namn: Johnny Panrike
Vi antar att programmet inte behandlar å, ä eller ö. (Och inte heller Å, Ä eller Ö.) Vidare antar vi också
att ett namn har formen av två sammanhängande ord separerat av precis ett mellanslag (namn som
“Karl Erik Jonsson” räknas alltså inte). Programmet skall använda funktioner på ett bra sätt och får
inte använda globala variabler.
Lösning:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int make_all_small(char namn[])
{
int i=0;
while(namn[i])
namn[i]=tolower(namn[i++]);
}
int do_capitals(char namn[])
{
int i=0;
while(namn[i++]!=' ');
namn[i]=toupper(namn[i]);
namn[0]=toupper(namn[0]);
}
int main()
{
char namn[30];
printf("Namn: "); gets(namn);
make_all_small(namn);
do_capitals(namn);
printf("Namn: %s.\n", namn);
return 0;
}
4. Ett ofullständigt program (4p)
Studera följande program:
#include <stdio.h>
#include <string.h>
#define MAX 10
struct person
{
char namn[10];
int alder;
}
main() //Huvudprogram, får inte ändras
{
struct person personer[MAX]; int antal;
matain(personer, &antal);
sortera(personer, antal);
skrivut(personer, antal);
}
Skriv funktionerna matain(), sortera() och skrivut() så att programmet fungerar på följande sätt:
först tar det in en lista på ett antal personer, sedan sorteras dessa på ålder (med yngsta först). Vi kan
anta att namn endast bildas av små bokstäver från a till z. Ett exempel på en körning (det användaren
matar in visas i fet stil):
Mata in personuppgifter (avsluta med ålder = 0.)
Ålder: 10
Namn: kalle
Ålder: 8
Namn: olle
Ålder: 10
Namn: olle
Ålder: 9
Namn: kalle
Ålder: 11
Namn: lisa
Ålder: 10
Namn: anders
Ålder: 0
Resultat:
olle, 8
kalle, 9
kalle, 10
anders, 10
lisa, 11
Du får absolut inte införa globala variabler i programmet eller ändra i huvudprogrammet. Det enda du
får göra är att lägga till de tre funktionerna som ska fungera med exakt de anrop som finns i
huvudprogrammet.
Lösning:
#include <stdio.h>
#include <string.h>
#define MAX 10
struct person
{
char namn[10];
int alder;
};
void matain(struct person personer[], int *antal)
{
*antal = 0;
struct person bufp;
char bufs[2];
printf("Mata in personuppgifter (avsluta med alder = 0.)\n\n");
do
{
printf("Alder: ");
scanf("%d", &(bufp.alder) );
if(bufp.alder==0)return;
gets(bufs);
printf("Namn: ");
gets(bufp.namn);
personer[*antal] = bufp;
(*antal)++;
printf("\n");
} while(*antal<MAX);
}
void sortera(struct person personer[], int antal)
{
int i, j;
struct person bufp;
for(i=0;i<antal;i++)for(j=i+1;j<antal;j++)
{
if(personer[j].alder<personer[i].alder)
{
bufp=personer[i]; personer[i]=personer[j]; personer[j]=bufp;
}
}
}
void skrivut(struct person personer[], int antal)
{
int i=0;
printf("\nResultat:\n\n");
for(i=0;i<antal;i++)
printf("%s, %d\n",personer[i].namn, personer[i].alder );
}
main() //Huvudprogram, får inte ändras
{
struct person personer[MAX]; int antal;
matain(personer, &antal);
sortera(personer, antal);
skrivut(personer, antal);
}
5. Addition av stora tal (2p)
I denna uppgift skall du skriva ett program som låter användaren addera stora heltal och presenterar
resultatet. Talen skall kunna innehålla upp till 1000 siffror. Resultatet i en beräkning ska användas i
nästa beräkning. Programmet fortsätter till dess att användaren matar in 0. En körning ska se ut enligt
nedan:
Tal 1: 100000000000000000000000000089002
Tal 2: 304000000000000000000000000000321009
Resultat: 304100000000000000000000000000410011
Tal 2: 10002
Resultat: 304100000000000000000000000000420013
Tal 2:0
Avslutar
Lösning:
#include <stdio.h>
#include <string.h>
#define MAX 10000
int main(){
char tal1[MAX],tal2[MAX],resultat[MAX];
printf("Tal 1: ");
fgets(tal1,sizeof(tal1),stdin);
tal1[strlen(tal1)-1]=0;
while(1){
printf("Tal 2: ");
fgets(tal2,sizeof(tal2),stdin);
if(tal2[0]=='0') break;
tal2[strlen(tal2)-1]=0;
int aktuellSiffra1,aktuellSiffra2,minne=0,aktuellRes=0,delresultat;
aktuellSiffra1=strlen(tal1)-1;
aktuellSiffra2=strlen(tal2)-1;
while(aktuellSiffra1!=-1&&aktuellSiffra2!=-1){
delresultat=minne+(tal1[aktuellSiffra1]-'0')+(tal2[aktuellSiffra2]-'0');
resultat[aktuellRes]='0'+delresultat%10;
minne=delresultat/10;
aktuellSiffra1--;
aktuellSiffra2--;
aktuellRes++;
}
while(aktuellSiffra1!=-1){
delresultat=minne+(tal1[aktuellSiffra1]-'0');
resultat[aktuellRes]='0'+delresultat%10;
minne=delresultat/10;
aktuellSiffra1--;
aktuellRes++;
}
while(aktuellSiffra2!=-1){
delresultat=minne+(tal2[aktuellSiffra2]-'0');
resultat[aktuellRes]='0'+delresultat%10;
minne=delresultat/10;
aktuellSiffra2--;
aktuellRes++;
}
resultat[aktuellRes]='\0';
int i,j=0;
for(i=strlen(resultat)-1;i>-1;i--)
tal1[j++]=resultat[i];
tal1[j]='\0';
printf("Resultat: %s\n",tal1);
}
printf("Avslutar");
return 0;
}