Nagy ZH 2012

A NZH feladatok és megoldásaik.

1 NZH 2012

Egyik feladatcsoport

1. Beugró

Definiálj típust, amely egy szakasz adatait (kezdőpont: x, y koordináta, végpont: x, y koordináta, színkód: nemnegatív szám) tudja tárolni!

Megoldás

struct Szakasz {
    double x1, y1, x2, y2;   /* jó az int is */
    unsigned szinkod;
};

A main() függvényben adott két lokális, egész típusú változónk, x és y. Írj függvényt (csere), amely meg tudja cserélni ezek tartalmát!

Megoldás

void csere(int *pa, int *pb) {
    int temp = *pa; *pa = *pb; *pb = temp;
}

Írj függvényt, amely igaz értékkel tér vissza, ha a paraméterként kapott karakter egy hexadecimális számjegy (a...f, A...F, 0...9)!

Megoldás

int hexakar(char c) {
    return (c>='0' && c<='9')
          || (c>='a' && c<='f') || (c>='A' && c<='F');
}

Írj függvényt, amely paraméterként kap egy sztringet és egy karaktert, és visszaadja, hogy a karakter hányszor fordul elő a sztringben! A string.h függvényeit ne használd!

Megoldás

int hanyszor(char *str, char micsoda) {
    int i, db;
    db = 0;
    for (i=0; str[i]!='\0'; ++i)
        if (str[i]==micsoda) db++;
    return db;
}

Írj rövid programrészt, amely a „szamok.txt” szöveges fájlba beírja 1-től 20-ig a számokat, soronként egyet!

Megoldás

FILE *fp;
int i;
fp = fopen("szamok.txt", "wt");
for (i=1; i<=20; ++i) fprintf(fp, "%d\n", i);
fclose(fp);

2. Kapitány

A kapitány abban az évben született, amely 2012-höz alulról a legközelebbi olyan szám, melynek osztói száma 8, és van benne 4-es számjegy. Hány éves a kapitány? Határozd meg algoritmikus módszerrel egy teljes C programban az évszámot! Írd ki ezt is, és azt is, hogy most hány éves!

Megoldás

#include <stdio.h>

int osztokszama(int szam) {
    int db, i;
    db = 0;
    for (i=1; i<=szam; ++i)
       if (szam%i==0)
           ++db;
    return db;
}

int vanbenne(int szam, int mi) {
    while (szam>0) {
       if (szam%10 == mi)
           return 1;
       szam/=10;
    }
    return 0;
}

int main() {
    int ev = 2012;

    while (!(osztokszama(ev)==8 && vanbenne(ev, 4)))
       --ev;
    printf("%d-ben született, %d éves", ev, 2012-ev);

    return 0;
}

3. Tömörítő

Meg szeretnénk valósítani a következő tömörítési algoritmust: egy tömbben lévő bájtokat összevonjuk karakter-darabszám egységekbe és ezeket tároljuk le. Pl. ha a bemenet: 5, 6, 6, 12, 12, 12, 12, 12, 12, 12, 6, akkor a kimenet (5,1),(6,2),(12,7),(6,1). Definiálj típust, amely egy tömörített adatfolyam egységeit (Egyseg) tárolja: egy bájtot és a bájt ismétléseinek számát! Írj függvényt, amely paraméterként átvesz egy bájtokból álló tömböt; és egy úgyszintén paraméterként átvett, egységekből álló tömbbe tömörítve helyezi el azt! A függvény visszatérési értéke legyen a tömbbe beírt egységek száma (itt: 4)! Mutass példát a függvény használatára! Írj rövid kódrészletet, amelyben egy bájtokból álló tömböt tömörítesz; írd ki, hány bájtból állt eredetileg, és hány egységből áll tömörítve!

Megoldás

typedef struct Egyseg {
    unsigned char bajt;
    int hanyszor;
} Egyseg;

/* char is jo, ha konzekvens */
int betomorit(unsigned char mit[], int hossz, Egyseg hova[]) {
    int bepos = 0, kipos = 0;

    if (hossz == 0)   /* ez ajandek +1 pont */
        return 0;

    /* az elso */
    hova[kipos].bajt = mit[bepos];
    hova[kipos].hanyszor = 1;
    /* es a tobbi */
    while (++bepos < hossz) {
        /* ha ugyanaz, csak noveljuk a darabszamot */
        if (mit[bepos]==hova[kipos].bajt) {
            hova[kipos].hanyszor++;
        } else {
            kipos++;
            hova[kipos].bajt = mit[bepos];
            hova[kipos].hanyszor = 1;
            }
        }

    return kipos + 1;
}

/* kódrész */
unsigned char eredeti[19] = { 4, 9, 12, 12, 12, 12, 12, 12, 12, 5, 4, 5, 5, 5, 5, 0, 0, 0, 1 };
Egyseg tomoritett[19];  /* tomoritve nem fog tobb egysegbol allni */
int tomhossz;

tomhossz = betomorit(eredeti, sizeof(eredeti), tomoritett);
printf("Eredetileg: %d bájt, betömörítve: %d egység\n", 19, tomhossz);

4. Dátum

A programunknak háromféle formátumban írt dátumot kell kezelnie: (a) 'éé.hh.nn, (b) éééé.hh.nn és (c) nn.hh.éééé formátumokat. Az (a)-nak aposztróf van az elején; továbbá ha a megadott kétjegyű év kisebb, mint 50, akkor a 2000-esekről beszélünk (pl. '12 = 2012), ha nagyobb vagy egyenlő, akkor az 1900-asokról (pl. '95 = 1995). A (b) és (c) formátumban biztosan négy számjeggyel van írva az év. Írj függvényt, amelynek első paramétere egy sztring, amely a fentiek közül valamelyik formában egy dátumot tartalmaz; a második paramétere pedig egy másik sztring, amelybe a dátumot „normalizálva”, éééé.hh.nn. formátumban kell írja! Írj rövid programrészt, amelyben kiírod normalizálva az alábbi dátumokat: '97.12.31, 29.10.2012, 2012.09.03.

Megoldás

#include <stdio.h>

void datum(char *in, char *out) {
    int ev, honap, nap;

    if (in[0]=='\'') {
        sscanf(in+1, "%d.%d.%d", &ev, &honap, &nap);
        if (ev<50)
            ev+=2000;
        else
            ev+=1900;
    } else {
        sscanf(in, "%d.%d.%d", &ev, &honap, &nap);
        if (ev<=31) { /* ha a nap lenne elöl, kicsi szám lesz */
            int tmp = ev;
            ev = nap;
            nap = tmp;
        }
    }
    sprintf(out, "%04d.%02d.%02d.", ev, honap, nap);
}

/* kódrész */
char res[20];
datum("'97.12.31", res); printf("%s\n", res);
datum("29.10.2012", res); printf("%s\n", res);
datum("2012.9.3", res); printf("%s\n", res);   /* ezt is eszi */

Másik lehetőség:

Megoldás

void datum(char *in, char *out) {
    if (in[0]=='\'') {  /* (a) típus: ha aposztróffal kezdődik */
        if (in[1]<='4') /* ha 49 vagy alatta van - első számjegyből kiderül */
            strcpy(out, "20");
        else
            strcpy(out, "19");
        strcat(out, in+1);
    } else if (in[4]=='.') {    /* éééé.hh.nn-nek az első pontja alapján (b) lehet */
        strcpy(out, in);    /* a kimenet ugyanilyen */
    } else {    /* ha semmi más nem marad, akkor (c) típus */
        strncpy(out, in+6, 4);  /* az év 4 számjegye */
        out[4] = '.';
        strncat(out, in+3, 2);  /* hónap 2 számjegye */
        out[7] = '.';
        strncat(out, in, 2);    /* nap 2 számjegye */
        out[10] = '\0';         /* lezáró 0 */
    }
    strcat(out, ".");
}

Másik feladatcsoport

1. Beugró

Definiálj típust, amely egy kör adatait (középpont: x, y koordináta, sugár, szín: max. 10 betűs szó) tudja tárolni!

Megoldás

struct Kor {
    double x, y, r;   /* jó az int is */
    char szin[10+1];
};

A main() függvényben adott két lokális, egész típusú változónk, k és t. Írj függvényt (teglalap), amely átveszi egy téglalap oldalhosszait (első és második paraméter), és ezekben a változókba tudja tenni a téglalap kerületét és területét (harmadik és negyedik paraméter)!

Megoldás

void teglalap(int a, int b, int *k, int *t) {
    *k = 2*(a+b);
    *t = a*b;
}

Írj függvényt, amely visszatér a paraméterként kapott hexadecimális számjegy karakter (0...9, A...F) értékével (0...15)! Ha nem ilyen, akkor -1-gyel.

Megoldás

int hexaertek(char c) {
   if (c>='0' && c<='9') return c-'0';
   if (c>='A' && c<='F') return c-'A'+10;
   return -1;
}

Írj függvényt, amely paraméterként kap egy sztringet, és logikai igazat ad vissza, ha szerepel-e benne újsor karakter! (Amúgy hamisat.) A string.h függvényeit ne használd!

Megoldás

int vanebenneujsor(char *str) {
    int i;
    for (i=0; str[i]!='\0'; ++i)
        if (str[i]=='\n') return 1;
    return 0;
}

Írj rövid programrészt, amelyben definiálsz egy 150 elemű, előjel nélküli egészekből álló tömböt, és kiírod azt a „szamok.dat” nevű bináris fájlba!

Megoldás

FILE *fp; unsigned szamok[150];
fp = fopen("szamok.dat", "wb");
fwrite(szamok, sizeof(unsigned), 150, fp);
fclose(fp);

2. Kapitány

A kapitány abban az évben született, amely 2012-höz alulról a legközelebbi prímszám, és amelyre igaz az is, hogy számjegyeinek összege 14. Hány éves a kapitány? Határozd meg algoritmikus módszerrel egy teljes C programban az évszámot! Írd ki ezt is, és azt is, hogy most hány éves!

Megoldás

#include <stdio.h>

int prim(int szam) {
    int oszto;
    for (oszto=2; oszto<=szam/2; ++oszto)
       if (szam%oszto == 0)
           return 0;
    return 1;
}

int szamjegyosszeg(int szam) {
    int ossz = 0;
    while (szam>0) {
       ossz += szam%10;
       szam/=10;
    }
    return ossz;
}

int main() {
    int ev = 2012;

    while (!(prim(ev) && szamjegyosszeg(ev)==14))
       --ev;
    printf("%d-ben született, %d éves", ev, 2012-ev);

    return 0;
}

3. Számok darabszáma

Definiálj típust, amelyben egy egész számot és előfordulásai számát lehet tárolni (SzamDb)! Írj függvényt, amely átvesz egy tömböt, amely egész számokat tartalmaz; továbbá egy SzamDb tömböt, amelybe azt írja, hogy melyik szám hányszor szerepelt. Pl. ha a bemenet 12, 12, 12, 12, 12, 12, 12, 6, 6, 6, 6, 12, 9, akkor a kimenet (12,8),(6,4),(9,1). Az utóbbi tömbben a számok sorrendje tetszőleges. A függvény visszatérési értéke legyen a bemenet különböző számainak száma (itt: 3)! Mutass példát a függvény használatára! Definiálj és inicializálj egy tömböt néhány egésszel, hívd meg a függvényed, utána írd ki, melyik szám hányszor szerepel benne!

Megoldás

typedef struct SzamDb {
    int szam;
    int db;
} SzamDb;

int szamol(int tomb[], int meret, SzamDb stat[]) {
    int statdb = 0;
    int i, hol;

    /* végig a tömbön */
    for (i=0; i<meret; ++i) {
       /* megkeressük, volt-e eddig */
       for (hol=0; hol<statdb; ++hol)
           if (stat[hol].szam == tomb[i])
               break;
       /* ha nincs még benne, be kell tenni */
       if (hol==statdb) {
           stat[statdb].szam = tomb[i];
           stat[statdb].db = 1;
           statdb++;
       } else {
           stat[hol].db++;
       }
    }
    return statdb;
}

/* kódrész */
int szamok[19] = { 4, 9, 12, 12, 12, 12, 12, 12, 12, 5, 4, 5, 5, 5, 5, 0, 0, 0, 1 };
SzamDb stat[19]; /* ha legalább akkora, mint az input, tuti belefér */
int db, i;

db = szamol(szamok, 19, stat);
for (i=0; i<db; ++i)
printf("%d: %dx szerepel\n", stat[i].szam, stat[i].db);

4. Telefonszám

Egy telefonszám vagy tartalmaz körzetszámot, vagy nem. Ha tartalmaz, akkor a szám első két számjegye 06, ezt követi egy vagy két számjegy, amely a körzetszám. A körzet lehet 1 vagy 20-99 közötti érték. Utána pedig a törzsszám. Pl. 0614631111-ben a körzet 1, a törzs 4631111. Írj függvényt, amelynek első paramétere egy feldolgozandó telefonszám. Ez egy sztring, amelyben csak számjegyeket vannak. A függvény visszatérési értéke legyen a körzetszám egész típusú értékként (vagy ha a telefonszámban ilyen nincs, akkor 0). Paraméterként vegyen át egy másik sztringet is, melyben a körzetszámtól megfosztott telefonszámot kell eltárolnia. Írj rövid programrészt, amelyben a fenti telefonszámot darabolod fel a függvénnyel, és kiírod külön a körzetszámot és a telefonszámot!

Megoldás

#include <string.h>
#include <stdio.h>

int telefonszam(char *be, char *ki) {
    if(be[0]=='0' && be[1]=='6') {  /* vagy strncmp(be, "06", 2)==0 */
        if (be[2]=='1') {           /* vagy strncmp(be+2, "1", 1)==0 */
            strcpy(ki, be+3);
            return 1;
        }
        strcpy(ki, be+4);
        return (be[2]-'0')*10+be[3]-'0'; /* vagy sscanf(be+2, "%2d", &k) */
    }
    strcpy(ki, be);
    return 0;
}

/* kódrész */
char torzs[15];
int korzet;
korzet = telefonszam("0614631111", torzs);
printf("Korzet: %u, szam: %s", korzet, torzs);

2 PZH 2012

1. beugró

Írj egy függvényt, amely ha az angol ábécé nagybetűjét kapja, akkor visszatér azzal, hogy hányadik betű az ábécében a kapott karakter (A=1, B=2 stb.), ha egyéb karaktert kap, akkor pedig -1-gyel!

Megoldás

int hanyadik(char c) {
    if (c>='A' && c<='Z') return c-'A'+1;
    else return -1;
}

Írj függvényt, amely át tudja adni a hívójának a paraméterként kapott két egész szám szorzatát (ez is egész), és hányadosát (ez viszont lehet, hogy nem!)

Megoldás

void szamol(int a, int b, int *szorzat, double *hanyados) {
    *szorzat = a*b;
    *hanyados = (double)a/b;
}

Írj függvényt, amely átvesz egy valós számokból álló tömböt, és megfordítja azt! Ha a tömb eredeti tartalma {1, 2, 3, 4}, akkor a hívás után {4, 3, 2, 1} legyen.

Megoldás

void megfordit(double tomb[], int meret) {
    int i;
    for (i=0; i<meret/2; ++i) {
        double temp=tomb[i];
        tomb[i]=tomb[meret-1-i];
        tomb[meret-1-i]=temp;
    }
}

Írj függvényt, amely átvesz egy sztringet, és megszámolja, hány számjegy karakter van benne!

Megoldás

int hanyszam(char *str) {
    int i, db = 0;
    for (i=0; str[i]!='\0'; ++i)
        if (isdigit(str[i]))
            ++db;
    return db;
}

Definiálj felsorolt típust, amely egy Sokoban pálya egy cellájának értékeit tudja felvenni: üres mező, fal, emberke, eltolható láda!

Megoldás

typedef enum Cella { ures, fal, ember, lada } Cella;

2. Ikerprímek

Ikerprímeknek nevezzük azokat a prímszám együtteseket, amelyeknél n és n+2 is prím. Az első 3 ilyen pár (3, 5), (5, 7) és (11, 13). Melyik a 60-adik? Határozd meg C programban! A két prím közötti egész számnak van 5-ös számjegye? Határozd meg ezt is!

Megoldás

#include <stdio.h>

int prim(int szam) {
    int oszto;

    for (oszto=2; oszto<szam; ++oszto)
        if (szam%oszto == 0)
            return 0;
    return 1;
}

int main() {
    int szam, i, vanbenne;

    /* ez a nulladik (ami nincs). az elso, amit megtalalunk, a 3;5 lesz. */
    szam=1;
    i=0;
    while (i<60) {
        /* keressük a következőtől (lehetne hátultesztelő is) */
        szam+=2;
        while (!(prim(szam) && prim(szam+2)))
            szam+=2;
        i++;
    }
    printf("%d. ikerprim: %d %d\n", 60, szam, szam+2);

    vanbenne = 0;
    szam += 1;  /* ez van kozottuk */
    while (szam>0) {
        if (szam%10 == 5)
            vanbenne = 1;
        szam/=10;
    }
    printf("%s benne 5-os.\n", vanbenne ? "Van":"Nincs");

    return 0;
}

Állapotgép

Tervezz állapotgépet állapot- és tevékenységtáblával (4p), és valósítsd meg C programmal (6p), amely a szabványos bemenetről, fájl vége jelig olvasott szöveget „emo-speech”-csé konvertál, és úgy ír ki a kimenetre! A következő cseréket kell elvégezni: (1) minden sz betűt c-re (ssz-t cc-re), (2) minden s betűt sz-re (ss-t ssz-re), (3) a kimeneten véletlenszerűen kell használni kisbetűket és nagybetűket (a bemeneten is lehetnek kisbetűk és nagybetűk), (4) a szöveg végére oda kell írni, hogy xD.

Példa bemenet: Ma helyenként húsz milliméternél is több eső hullhat.
Példa kimenet: MA HelyEnkéNt húC MILLIMéTeRnél IsZ TöbB EsZő HULLhat. xD

(Kettőnél több s nem lesz egymás után. Javasolt a beolvasott karaktereket egyből kisbetűssé konvertálni, és úgy dolgozni velük.)

defaultsz
alapki: c→ eski: c
eski: "sz", c, →alap→ esski: "c", alap
esski: "ssz", c, →alap(mindegy)ki: "cc", →alap

Megoldás

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

void emo_putc(char c) { putchar(rand()%2 ? toupper(c):tolower(c)); }

int main() {
    enum Allapot { alap, es, ess } all = alap;
    int c;

    while ((c=getchar()) != EOF) {
      c=tolower(c);
      switch (all) {
          case alap:
              if (c=='s') all=es;
              else emo_putc(c);
              break;
          case es:
              switch (c) {
                  default: emo_putc('s'); emo_putc('z'); emo_putc(c);
                           all=alap;
                           break;
                  case 's': all=ess; break;
                  case 'z': emo_putc('c'); all=alap; break;
              }
              break;
          case ess:
              if (c=='z') {
                  emo_putc('c'); emo_putc('c'); all=alap;
              } else {
                  emo_putc('s'); emo_putc('s'); emo_putc('z');
                  emo_putc(c); all=alap;
              }
              break;
      }
    }
    /* ezt itt ajandek pontert lehetett */
    if (all==es) { emo_putc('s'); emo_putc('z'); }
    if (all==ess) { emo_putc('s'); emo_putc('s'); emo_putc('z'); }

    emo_putc('x'); emo_putc('d');

    return 0;
}

Sztring

A verssorokat attól függően halljuk rímelni, hogy a sorok végén az utolsó magánhangzók egyformák-e. Páros rímnek nevezzük az aabb mintázatot, keresztrímnek az abab-t, félrímnek az xaxa-t (ilyenkor csak a 2. és a 4. sor rímel, az 1. és a 3. nem). Pl. ez keresztrím:

Ime, itt a költeményem. (a)
Ez a második sora. (b)
K betűkkel szól keményen (a)
Címe: „Költőnk és Kora”. (b)

Írj függvényt, amely átvesz négy sztringet, és visszatér egy felsorolt típusú értékkel, amelynek lehetséges értékei: páros rím, keresztrím, félrím és ismeretlen (ha az előzők közül egyik sem)! Írj rövid programrészt, amelyben példát mutatsz a függvény használatára: átadsz neki négy verssort, és eltárolod a visszatérési értékét.

Megoldás

#include <stdio.h>
#include <string.h>

typedef enum Rim { parosrim, keresztrim, felrim, nincs } Rim;

int maganhangzo(char c) {
    return c=='a' || c=='e' || c=='i' || c=='o' || c=='u';
}

char utolso_maganhangzo(char *s) {
    int i=strlen(s)-1;
    while (!maganhangzo(s[i]))
        --i;
    return s[i];
}

Rim rimel(char *s1, char *s2, char *s3, char *s4) {
    char a = utolso_maganhangzo(s1);
    char b = utolso_maganhangzo(s2);
    char c = utolso_maganhangzo(s3);
    char d = utolso_maganhangzo(s4);

    if (a==b && c==d) return parosrim;
    if (a==c && b==d) return keresztrim;
    if (b==d) return felrim;
    return nincs;
}

int main() {
    Rim r;

	r = rimel("Ime, itt a koltemenyem.",
              "Ez a masodik sora.",
              "K betukkel szol kemenyen",
              "Cime: \"Koltonk es Kora\".");
    printf("%d tipusu rim", r);

    return 0;
}

3 PPZH 2012

1. beugró

Definiálj típust, mely alkalmas egy kör adatainak (koordináta, sugár) nyilvántartására a 2D síkon, és értékként adható át egy függvénynek!

Megoldás

typedef struct Kor {
    double x, y, r;
} Kor;

Írj függvényt, mely alkalmas arra, hogy két Kor típusú változó tartalmát, amelyek a main() függvényben vannak lokális változóként definiálva, felcseréli!

Megoldás

void csere(Kor *k1, Kor *k2) {
    Kor temp = *k1;
    *k1 = *k2;
    *k2 = temp;
}

Írj függvényt, mely egy karaktert vesz át, és ha az számjegy, annak értékét, ellenkező esetben -1-et ad vissza.

kzh.php#3
kedd 10, b

Megoldás

int szamjegy(char c) {
  if (c>='0' && c<='9')
    return c-'0';
  else
    return -1;
}

Írj függvényt, amely megadja a hívójának, hogy a paraméterként kapott egészek tömbjében minden elem pozitív-e!

Megoldás

int pozitivak(int *tomb, int meret) {
  int van_negativ, i;
  van_negativ = 0;
  for (i=0; i<meret && !van_negativ; ++i)
    if (tomb[i]<0)
      van_negativ = 1; 
  return !van_negativ;
}

Írj memóriaszivárgás nélküli programrészletet, mely a “szamok.txt” szövegfájlba írja egytől húszig az egész számokat!

Megoldás

FILE *fp = fopen("szamok.txt", "wt");
int i;
for (i=1; i<=20; ++i)
   fprintf(fp, "%d\n", i);
fclose(fp);

2. sin(), cos()

A gépünkön „tönkrementek” a szabványos C könyvtárban a math.h-beli matematikai függvények. Taylor azonban megsúgta, hogy sin(x)=+x1/1! – x3/3! + x5/5! – x7/7! + ..., illetve cos(x)=+x0/0! – x2/2! + x4/4! – x6/6! + ... összegekkel közelíthető.

Írj olyan szabványos C függvényt, amely a paraméterlistán kap egy valós számot (x), valamint egy egész értéket. Ez utóbbi határozza meg, hogy melyik szögfüggvény értékét kell számolnunk: 0 esetén cos(), 1 esetén sin() értékére kíváncsi a hívó. Számold ki, és add vissza a kívánt szögfüggvény közelítő értékét, melyet a fenti sorok első 16 tagjával kapsz! (A pow() függvényt sem használhatod, az is a math.h-ban van.)

Egészítsd ki a kódot teljes C programmá, amelyben kiszámolod és kiírod sin(1) és cos(2) értékét!

Megoldás

#include <stdio.h>

#define TAG 16

double egeszhatvany(double x, unsigned kitevo) {
    int i;
    double prod=1;
    for (i=0; i<kitevo; i++)
        prod*=x;
    return prod;
}

unsigned fakt(unsigned n) {
    unsigned prod=1;
    for ( ; n>1; n--)
        prod*=n;
    return prod;
}

double cossin(double x, unsigned mode) {
    double sum=0;
    int i;
    for (i=0; i<TAG; i++)
        sum += egeszhatvany(-1.0, i) * egeszhatvany(x, 2*i+mode)/fakt(2*i+mode);   
    return sum;
}

int main() {
    printf("%f\n", cossin(1.0, 1)); /*sin(1)*/
    printf("%f\n", cossin(2.0, 0)); /*cos(2)*/
    return 0;
}

3. Könyvtár

Definiálj adattípust könyvtári könyvek adatainak tárolására! A tárolandó adatok: szerző (max. 30 karakter), cím (50), azonosító (egész szám), kiadás éve (egész), darabszám (egész).

Írj függvényt, amely paraméterként vesz át egy könyvtári könyvek adatait tartalmazó, fenti típusú elemekből álló tömböt, és rendezi azt szerző szerinti ABC sorrendbe!

Írj függvényt, amely paraméterként vesz át egy könyvtári könyvek adatait tartalmazó, fenti módon rendezett tömböt, és a szabványos kimenetre írja, hogy egy szerzőtől hány könyve van a könyvtárnak! Egy szerző neve csak egyszer szerepeljen a kiírt listában!

Megoldás

typedef struct {
   char szerzo[30+1];
   char cim[50+1];
   int azonosito, kiadas, db;
} konyv;

void rendez(konyv t[], int n) {
   int i, j, min;
   for (i = 0; i < n; i++) {
       min = i;
       for (j = 0; j < n; j++)
           if (strcmp( t[j].szerzo, t[min].szerzo ) < 0)
               min = j;
       if (i != min){ konyv temp = t[min]; t[min] = t[i]; t[i] = temp; }
   }
}

void kiir(konyv t[], int n) {
   int i, db;
   for (i = db = 0; i < n; i++) {
       if (i == n - 1 || strcmp(t[i].szerzo,t[i+1].szerzo) != 0) {
           printf("%s: %d db\n",t[i].szerzo, t[i].db + db );
           db = 0;
       }
       else db += t[i].db;
   }
}

4. Palindrom

Írj C függvényt, amely megvizsgálja a paramétereként kapott sztringet, hogy az palindrom-e! A visszatérési értéke logikai igaz kell legyen, ha a sztring visszafelé olvasva, csak a benne szereplő számjegyeket és angol betűket figyelembe véve, valamint eltekintve azok kis- illetve nagybetűs voltától, ugyanaz, mint előrefelé; egyéb esetben pedig hamis. (A kapott sztringet nem szabad módosítani, viszont tetszőlegesen hosszú lehet.)

Írj rövid főprogramot, amely beolvas egy legfeljebb 80 karakterből álló sort, és kiírja, hogy palindrom-e! Pl. palindrom: “Keresik a tavat a kis erek.”

Megoldás

#include <stdio.h>
#include <string.h>
#include <ctype.h>

/* két praktikus megoldás:
     (1) szétválogatás tétele cserék nélkül (lásd lent)
     (2) másolat a kihagyandók nélkül, és egyszerű összehasonlítás */
int palindrom(char const *str) {
    int eleje, vege, pali;
  
    eleje=0;
    vege=strlen(str)-1;
    pali=1;
    while (pali && eleje<vege) {
        while (eleje<vege && !isalnum(str[eleje]))
            eleje++;
        while (eleje<vege && !isalnum(str[vege]))
            vege--;
        if (eleje<vege)
            if (toupper(str[eleje]) != toupper(str[vege]))
                pali=0;
        eleje++;
        vege--;
    }
  
    return pali;
}

int main() {
    char sor[80+1];
    gets(sor);
    printf("%s.\n", palindrom(sor) ? "Palindrom" : "Nem palindrom");
    return 0;
}