Структурно програмирање

Аудиториска вежба 12 - Текстуални низи (стрингови)


1. Потсетување од предавања

1.1. Функции за работа со текстуални низи од библиотеката <cstring>

Функции за менување на текстуални низи:

Функции за менување на меморијата:

Функции за претворање на текстуални низи во броеви:

Функции за испитување на текстуални низи:

1.2. Функции за работа со знаци од библиотеката <cctype>

Функции за работа со единечен знак:

2. Задачи

2.1. Задача 1

Да се напише функција што ќе одредува колку пати даден знак се наоѓа во даден стринг. Знакот за споредување и стрингот се внесуваат од тастатура.

Пример

За стрингот

HELLO FINKI

знакот L се појавува 2 пати.

#include <iostream>
using namespace std;

int count_char(char str[], char c) {
    int vkupno = 0;
    for (int i = 0; str[i] != '\0'; i++) {
        if (str[i] == c) vkupno++;
    }
    return vkupno;
}

int main() {
    int MAX = 100;
    char s[MAX], c;
    cin.getline(s, MAX);
    cin >> c;
    cout << count_char(s, c);
    return 0;
}

2.2. Задача 2

Да се напише функција што ќе ја одредува должината на една текстуална низа.

Да се даде итеративно и рекурзивно решение.

Пример

Ако на функцијата како аргумент и се предаде стрингот

zdravo!

тогаш таа треба да врати: 7

#include <iostream>
using namespace std;

int length(char s[]) {
    int len = 0;
    for (int i = 0; s[i] != '\0'; i++)
        len++;
    return len;
}

int length_r(char *s) { // same as char s[]
    if (*s == '\0') // same as if (s[0] == '\0')
        return 0;
    return 1 + length_r(s + 1);
}

int main() {
    int MAX = 100;
    char s[MAX];
    cin.getline(s, MAX);
    cout << "Dolzhina: " << length(s) << " i " << length_r(s);
    return 0;
}

2.3. Задача 3

Да се напише програма која ќе ја отпечати поднизата на дадена текстуална низа (што се внесува од тастатура) определена со позицијата и должината, што како параметри се внесуваат од тастатура. Поднизата започнува од знакот што се наоѓа на соодветната позиција во текстуалната низа, броејќи од лево.

Пример

Ако од тастатура се внесе:

banana

позиција: 2

должина: 4

тогаш програмата треба да отпечати: nana


#include <iostream>
#include <cstring>

using namespace std;

int main() {
    int MAX = 100;
    char s[MAX], dest[MAX];
    int pozicija, dolzhina;

    cin.getline(s, MAX);
    cin >> pozicija >> dolzhina;

    if (pozicija <= strlen(s)) {
        strncpy(dest, s + pozicija - 1, dolzhina);
        dest[dolzhina] = '\0';
        cout << "Rezultat: " << dest << endl;
    } else
        cout << "Nevaliden vnes, prochitaniot string ima samo %d znaci.\n" << strlen(s);
    return 0;
}

2.4. Задача 4

Да се напише функција која ќе одредува дали една текстуална низа е подниза на друга текстуална низа.

Пример

face е подниза на Please faceAbook


#include <iostream>
#include <cstring>

using namespace std;

int podstring(char *s1, char *s2) {
    int d1 = strlen(s1);
    int d2 = strlen(s2);
    if (d1 > d2)
        return 0;
    for (int i = 0; i <= d2 - d1; i++)
        if (strncmp(s1, s2 + i, d1) == 0)
            return 1;
    return 0;
}

int main() {
    int MAX = 100;
    char s1[MAX], s2[MAX];
    cin.getline(s1, MAX);
    cin.getline(s2, MAX);
    if (podstring(s1, s2))
        cout << s1 << " e podstring na " << s2 << endl;
    else
        cout << s1 << " NE e podstring na " << s2 << endl;
    return 0;
}

2.5. Задача 5

Да се напише функција која ќе проверува дали дадена текстуална низа е палиндром.

Една текстуална низа е палиндром ако таа се чита исто од лево на десно и од десно на лево.

Примери за палиндроми

dovod
ana
kalabalak

#include <iostream>
#include <cstring>

using namespace std;

int e_palindrom(char str[]) {
    int n = strlen(str);
    for (int i = 0; i < n / 2; i++)
        if (str[i] != str[n - 1 - i])
            return 0;;
    return 1;
}

// REKURZIVNO
int e_pal(char str[], int start, int end) {
    if (start >= end) return 1;
    if (str[start] == str[end])
        return e_pal(str, start + 1, end - 1);
    return 0;
}

int main() {
    int MAX = 100;
    char s[MAX];
    cin.getline(s, MAX);
    cout << s << " ";
    if (e_pal(s, 0, strlen(s) - 1))
        printf("e palindrom.");
    else
        printf("NE e palindrom.");
    return 0;
}

2.6. Задача 5-a (За Дома)

Да се напише функција која ќе проверува дали дадена реченица е палиндром. При проверката да се игнорираат празните места, интерпункциските знаци, а соодветните мали и големи букви да се сметаат за еднакви (A == a, B == b, итн.).

Примери за реченици - палиндроми

Jadejne i pienje daj!
A man, a plan, a canal, Panama.
Never odd or even.
Rise to vote sir!

2.7. Задача 6

Да се напише функција која за дадена текстуална низа ќе одредува дали таа е доволно сложена за да биде лозинка.

Секоја лозинка мора да содржи барем една буква, барем една цифра и барем еден специјален знак.

Пример

zdr@v0! е валидна лозинка.

zdravo не е валидна лозинка.

#include <iostream>
#include <cctype>

using namespace std;

int e_validna_lozinka(char str[]) {
    int bukvi = 0, cifri = 0, spec = 0;
    for (int i = 0; str[i] != '\0'; i++) {
        if (isalpha(str[i]))
            bukvi++;
        else if (isdigit(str[i]))
            cifri++;
        else
            spec++;
    }
    return (bukvi > 0 && cifri > 0 && spec > 0);
}


int main() {
    int MAX = 100;
    char s[MAX];
    cin.getline(s, MAX);

    cout << s << " ";
    if (e_validna_lozinka(s))
        cout << "e validna lozinka.";
    else
        cout << "NE e validna lozinka.";
    return 0;
}

2.8. Задача 7

Да се напише функција која во стринг што и се предава како влезен параметар ќе ги промени малите букви во големи и обратно, и ќе ги отстрани сите цифри и специјални знаци.

Пример

За низата:

0v@ePr1m3R

треба да се добие:

VEpRMr

#include <iostream>
#include <cctype>

using namespace std;

void filter(char str[]) {
    int i = 0, j = 0;
    while (str[i] != '\0') {
        if (isalpha(str[i])) {
            if (islower(str[i]))
                str[j] = toupper(str[i]);
            else if (isupper(str[i]))
                str[j] = tolower(str[i]);
            j++;
        }
        i++;
    }
    str[j] = '\0';
}

int main() {
    int MAX = 100;
    char s[MAX];
    cin.getline(s, MAX);

    filter(s);
    cout << s << endl;
    return 0;
}

2.9. Задача 8

Да се напише функција која во дадена текстуална низа ќе ги отстранува празните места на почетокот и крајот од низата.

Пример

За низата:

"   make trim   "

треба да се добие:

"make trim"
#include <iostream>
#include <cctype>

using namespace std;

void trim(char s[]) {
    int spaces = 0;
    while (isspace(s[spaces])) {
        spaces++;
    }
    int i;
    for (i = 0; s[i + spaces] != '\0'; i++) {
        s[i] = s[i + spaces];
    }
    s[i] = '\0';
    while (i > 0 && isspace(s[i - 1])) {
        i--;
        s[i] = '\0';
    }
}

int main() {
    int MAX = 100;
    char s[MAX];
    cin.getline(s, MAX);
    cout << "[" << s << "] -> ";
    trim(s);
    cout << "[" << s << "]";
    return 0;
}