Кадндидат-студентски изпит по информатика на C++

С++ решаваня на задачи по информатика, от кандидатстудентски изпити

Изпит по информатика в ПУ, 13 юли 2009 г., вариант 2

leave a comment »

Решение на С++ на задача 1, дадена на кандидатстудентския изпит в ПУ на 13 юли 2009г.

Условие:

Необходимо е да се извършват различни справки за студенти, обучавани по бакалавърски програми от Факултета по математика и информатика (ФМИ). Един студент може да има само един факултетен номер и една специалност. Всички студенти са родени между 1950 и 1992 г. Известно е, че трябва да се осигури въвеждането на не повече от 1000 студенти. За всеки студент се въвежда: факултетен номер (ФН) – във формат AABBCCDEEE, т.е. състои се от 10 не непременно еднакви десетични цифри, където AA означават последните две цифри на годината, в която е записан студента, BB означават номера на факултета (за ФМИ е 01), CC – номер на специалност („информатика”, „бизнес информационни технологии”, „математика”, „приложна математика” и „математика и информатика” са съответно с кодове: 01, 02, 03, 04 и 05), D – вид обучение (1 – редовно, 2 – задочно), EEE – поредния номер на записване; единен граждански номер (ЕГН) или единен номер на чужденец (ЕНЧ) – ако е чужденец, които са във формат TTYYZZXXXX, т.е. състои се от 10 не непременно еднакви десетични цифри, като TT са последните две цифри на годината на раждане, YY е месеца на раждане, а ZZ е поредния номер на деня от месеца на раждане. Например: факултетен номер 0901012001 и ЕГН 8003019909 означава: студента е записан 2009 г., ФМИ, специалност „информатика”, задочно обучение, пореден номер 1, роден е на 01.03.1980 г. Реализирайте следната функционалност на програмата:

  1. Да се въведе и контролира броя студенти N – цяло неотрицателно число. За всеки студент въведете факултетен номер и съответен ЕГН/ЕНЧ, контролирайки уникалността на факултетния номер и уникалността на ЕГН/ЕНЧ;
  2. Да се отпечата списък на всички студенти от ФМИ, специалност „информатика”, редовно
    обучение, записани между 1999 г. и 2009 г. включително;
  3. Да се сортират във възходящ ред по номер на специалност, като при еднакви номера на специалности, се сортират в низходящ ред по ЕГН/ЕНЧ. Да се изведе така получения сортиран списък, съдържащ факултетните номера и съответните им ЕГН/ЕНЧ, разделени с точно един интервал.

Решение на С++:

// ---------------------------------------------------------------------//
// Ррешение на задача 1 от вариант 2 давана кандидатстудентски изпит по //
// информатика в Пловдивски университет на 13 юли 2009 година           //
//                                                                      //
// @author: Ivan Stoyanov                                               //
// ---------------------------------------------------------------------//

#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;

// Дефинира се структура описваща студент
struct Student {
    char fkNumber[11];
    char egn[11];
};
/* Ф-я за въвеждане данни за студент */
void inputStudentData(Student &student);
/* Извежда данните за студент */
void displayStudentData(Student const student);

// Структура описваща списък от студенти
struct StudentsList {
    int count;
    Student students[1000];
};
/* Инизицализира списъка (подаден като апраметър) като празен */
void initEmptyStudentsList(StudentsList &list);
/* Добавя студент в списъка */
void addStudentToList(StudentsList &list, Student const student);
/* Валидира студента */
bool validateStudent(StudentsList const list, Student student, char validateError);
/* Въвежда от клавиатурата студенти в списъка ( подаден като параметър)
   Входа се контролира по зададените изисквания
*/
void inputStudetsToList(StudentsList &list);
/* Извежда списъка със студенти */
void dispalyStudetsFromList(StudentsList &list);
/* Намира списък на всички студенти от ФМИ, специалност „информатика”,
   редовно обучение, записани между 1999 г. и 2009 г. включително
*/
StudentsList searchStudets(StudentsList &list);
/* Сортира списъка */
void sortStudentsList(StudentsList &list);

/* Главна функция на програмата */
int main() {

    StudentsList list;
    inputStudetsToList(list);

    StudentsList fmiStudents;
    fmiStudents = searchStudets(list);

    std::cout << "   --- Spisak na studentite ot FMI --- " << std::endl;
    dispalyStudetsFromList(fmiStudents);

    sortStudentsList(fmiStudents);
    std::cout << "   --- Sortiran spisak na studentite ot FMI --- " << std::endl;
    dispalyStudetsFromList(fmiStudents);

    return 0;
}

/* Ф-я за въвеждане данни за студент */
void inputStudentData(Student &student){
    std::cout << "FN: ";
    std::cin >> student.fkNumber;

    std::cout << "EGN: ";
    std::cin >> student.egn;
}

/* Извежда данните за студент */
void displayStudentData(Student const student){
    std::cout << student.fkNumber << " "
              << student.egn
              << std::endl;
}

/* Инизицализира списъка (подаден като апраметър) като празен */
void initEmptyStudentsList(StudentsList &list){
    list.count = 0;
}

/* Добавя студент в списъка */
void addStudentToList( StudentsList &list, Student const student){
    list.students[list.count] = student;
    list.count++;
}

bool validateStudent(StudentsList const list, Student student, char validateError[]=""){

    for(int i=0; i<list.count; i++){
        if( 0 == strcmp(list.students[i].egn, student.egn) ) {
            strcpy(validateError, "Egn already exist!");
            return false;
        }
        else if ( 0 == strcmp(list.students[i].fkNumber, student.fkNumber) ) {
            strcpy(validateError, "Fakultet number already exist!");
            return false;
        }
    }

    return true;
}

/* Въвежда от клавиатурата студенти в списъка ( подаден като параметър)
   Входа се контролира по зададените изисквания, като се предполага, че
  типовете се спазват (не се въвежда символен низ, където се изисква
  цяло число)
*/
void inputStudetsToList(StudentsList &list){

    int countStudents;

    do {
        std::cout << "Input count of students: ";
        std::cin >> countStudents;
        // Ако входа е коректен се прекъсва цикъла
        if( countStudents >= 1 && countStudents <= 1000 ) break;

        std::cout << "Error count of students. The count muss be in range 1 - 1000!"
                  << std::endl;
    }
    while(true);

    // Променлива за студент, на който се въвеждат данни и той се добавя в списъка
    Student student;
    char error[100];
    for(int i=0; i<countStudents; i++){

        // Въвежда данните за студент (в променливата student)
        // Въвеждането става докато се въведат коректни данни (контрол на входа)
        do {
            std::cout << "Input student " << (list.count+1) << std::endl;
            inputStudentData(student); // въвежда данни за съответния студент
            if( true == validateStudent(list, student, error) ) break;
            std::cout << error << std::endl;
        }
        while(true);

        addStudentToList(list, student);
    }
}

/* Извежда списъка със студенти */
void dispalyStudetsFromList(StudentsList &list){

    if( 0 == list.count ){
        std::cout << "List is empty! " << std::endl;
    }

    for(int i=0; i<list.count; i++){
        displayStudentData(list.students[i]);
    }
    std::cout << endl;
}

/* Намира списък на всички студенти от ФМИ, специалност „информатика”,
   редовно обучение, записани между 1999 г. и 2009 г. включително
*/
StudentsList searchStudets(StudentsList &list){

    StudentsList newList; // Нов списък за студентите отговарящи на критериите
    initEmptyStudentsList(newList); // Инициализира новия списък като празен

    // Низ за годината на записване, която е от 2 символа
    char strStartYear[3];
    int intStartYear;

    // Тази променлива се ползва за четивност
    // (по-удобно е да е указател char *, за тези които разбират указатели)
    char fkNum[11];

    for(int i=0; i<list.count; i++){

        strcpy(fkNum, list.students[i].fkNumber);

        // копира 1-те 2 символа от студента на позиция "i" от масива със студенти
        // намиращ се в променливата за списък
        strncpy(strStartYear, fkNum, 2);
        // преобразува strStartYear до цяло число
        intStartYear = atoi(strStartYear);

        // Проверява дали отговаря на условието
        if( ( 99 == intStartYear || intStartYear <= 9) &&
            ( '0' == fkNum[2] && '1' == fkNum[3] ) &&        //  01 => ФМИ
            ( '0' == fkNum[4] && '1' == fkNum[5] ) &&        //  01 => информатика
              '2' == fkNum[6]                                //   2 => задочно
          ) {
            addStudentToList(newList, list.students[i]);
        }
    }

    return newList;
}

void sortStudentsList(StudentsList &list){

    Student tmpStudent;
    int pos, min_num_spec, num_spec;
    for(int i=0; i<list.count-1; i++) {
        pos = i;
        min_num_spec = 10*(list.students[i].fkNumber[4]-'0') + list.students[i].fkNumber[5]-'0';
        for(int j=i+1; j<list.count; j++) {

            num_spec = 10*(list.students[j].fkNumber[4]-'0') + list.students[j].fkNumber[5]-'0';
           if( num_spec < min_num_spec ){
               min_num_spec = num_spec;
               pos = j;
           }
           else if ( num_spec == min_num_spec && strcmp( list.students[i].egn,  list.students[j].egn) > 0) {
               pos = j;
           }
        }

        if( pos != i ) {
            tmpStudent = list.students[i];
            list.students[i] = list.students[pos];
            list.students[pos] = tmpStudent;
        }
    }
}

Written by Stoyanoff

12/07/2012 в 14:27

Вашият коментар

Попълнете полетата по-долу или кликнете върху икона, за да влезете:

WordPress.com лого

В момента коментирате, използвайки вашия профил WordPress.com. Излизане /  Промяна )

Google photo

В момента коментирате, използвайки вашия профил Google. Излизане /  Промяна )

Twitter picture

В момента коментирате, използвайки вашия профил Twitter. Излизане /  Промяна )

Facebook photo

В момента коментирате, използвайки вашия профил Facebook. Излизане /  Промяна )

Connecting to %s

%d блогъра харесват това: