1 Востаннє редагувалося Qwerty (29.04.2015 21:57:30)

Тема: Задача по Set C++

Допоможіть перетворити цю задачу в задачу з використанням set

#include <iostream>
#include <conio.h>
#include <cstdlib>

using namespace std;
int color = system("color F0");
int main()
{
    setlocale(LC_ALL,"Rus");
    system("cls");
 int aN,bN,cN;

cout<<"Введiть кiлькiсть елементiв 1-ї множини:";
    cin>>aN;

    int *A=new int[aN];
    for(int i=0;i<aN;i++){
            system("cls");
        int z;
        cout << i+1 << "-й елемент"<<endl;
        cin>>z;
        A[i]=z;
        system("cls");
}


    cout<<"Введiть кiлькiсть елементiв 2-ї множини:";
    cin>>bN;
        int *B=new int[bN];

    for(int i=0;i<bN;i++)
        {
            system("cls");
        int z;
        cout << i+1 << "-й елемент"<<endl;
        cin>>z;
        B[i]=z;
        system("cls");
        }

    cout<<"Введiть кiлькiсть елементiв 3-ї множини:";
    cin>>cN;
int *C=new int[cN];

    for(int i=0;i<cN;i++)
        {
            system("cls");
        int z;
        cout << i+1 << "-й елемент"<<endl;
        cin>>z;
        C[i]=z;
        system("cls");
        }

cout<<"\nA:";
    for(int i=0;i<aN;i++)

        cout <<A[i]<<":";

    cout<<endl;
cout<<"\nB:";
    for(int i=0;i<bN;i++)
        cout<<B[i]<<":";
    cout<<endl;
cout<<"\nС:";
    for(int i=0;i<cN;i++)
        cout<<C[i]<<":";
    cout<<endl<<endl;

_getch();
  return 0;
}

2

Re: Задача по Set C++

Попрацюю за К.О.
Тут немає ніякої задачі. Тут є код. І цей код неможливо "перетворити в код з використанням set", бо тоді це буде вже не цей код.

З вас умова задачі і ваша спроба "перетворити" (код у 100 рядків зазвичай легше переписати з нуля, ніж переробити).

3

Re: Задача по Set C++

Спроектувати і реалізувати програму з наступними програмними функціями:
1) дозволяє користувачу увести з клавіатури елементи множин А, В, С.(діапазон допустимих значень задати самостійно);
2) виводить на екран ці множини у вигляді трьох рядків;
3) виконує розрахунки за  В∩(С∩А∩В); |A∩C|; 2^B;

4

Re: Задача по Set C++

Я взявся за цю задачу і уже зробив п. 1 і п. 2
У мене виникло декілька питань:
1) Чи можуть повторюватись числа в множині?
2) Яким чином можна використати функцію rand(), щоб отримати числа в діапазоні [a; b], якщо і a, і b можуть бути від’ємними.

5 Востаннє редагувалося quez (02.05.2015 19:14:32)

Re: Задача по Set C++

1) Чи можуть повторюватись числа в множині?

Ні.

2) Яким чином можна використати функцію rand(), щоб отримати числа в діапазоні [a; b], якщо і a, і b можуть бути від’ємними.

Формула та ж сама, що й для додатніх чисел: rand()%(b-a) + a.

6

Re: Задача по Set C++

quez написав:

2) Яким чином можна використати функцію rand(), щоб отримати числа в діапазоні [a; b], якщо і a, і b можуть бути від’ємними.

Формула та ж сама, що й для додатніх чисел: rand()%(b-a) + a.

Питали про закритий діапазон, так що rand()%(b-a+1) + a.

7 Востаннє редагувалося Ярослав (04.05.2015 20:13:47)

Re: Задача по Set C++

Вийшов отакий код.

/* 
 * set_operations
 * 1. Користувач вибирає розмір трьох множин,
 *    діапазон їх значень і задає значення елементів.
 * 2. Програма виводить множини на екран.
 * 3. Програма розраховує функції:
 *    В∩(С∩А∩В);
 *    |A∩C|;
 *    2^B
 *    і виводить результат на екран.
 */

#include <cstdio>
#include <cstdlib>
#include <iostream>
/* INPUT_BUFFER - буфер для вводу користувача */
#define INPUT_BUFFER 20

using namespace std;

/* set - множина 
 * start - покажчик на початок масиву із елементами множини
 * size - розмір множини
 * range_max - максимальне значення елементів множини
 * range_min - мінімальне значення елементів множини
 */
struct set {
    int *start;
    int size;
    int range_max;
    int range_min;
};

/* init_set - ініціалізує множину із параметрами, заданими користувачем */
set  init_set(void);
/* print_set - виводить на екран множину */
void print_set(set given_set);
/* intersect - розраховує перетин двох множин */
set  intersect(set a, set b);
/* exist - визначає чи є задане число в масиві */
bool exist(int number, int *array, int size);

/*
 * Демонстрація роботи із множинами 
 */
int main(int argc, char** argv) {
    set a, b, c, new_set;
    
    /* Ініціалізація множин */
    cout << "Будь ласка, задайте початкові значення множин.\n"
            "Множина A.\n";
    a = init_set();
    cout << "Множина B.\n";
    b = init_set();
    cout << "Множина C.\n";
    c = init_set();
    
    /* Вивід на екран */
    cout << "Утворені наступні множини:\n"
            "A: ";
    print_set(a);
    cout << "B: ";
    print_set(b);
    cout << "C: ";
    print_set(c);
    
    /* Демонстрація розрахунків */
    cout << "Обраховується формула В∩(С∩А∩В).\n";
    new_set = intersect(intersect(a, b), c); 
    cout << "В∩(С∩А∩В) = ";
    if (new_set.size) {
        print_set(new_set);
    } else {
        cout << "Порожня множина\n";
    }
                
    cout << "Обраховується формула |A∩C|.\n";
    new_set = intersect(a, c);
    cout << "|A∩C| = " << new_set.size << '\n';
    
    cout << "Обраховується формула 2^B.\n";
    if (b.size == 1 && *(b.start) == 2) {
        cout << "2^B = true\n";
    } else {
        cout << "2^B = false\n";
    }
        
    return 0;
}

set init_set(void) {
    /* Нова множина */
    set given_set;
    /* Буфер для вводу користувача */
    char str[INPUT_BUFFER];
    /* Лічильник */
    int i;
    /* Змінна для згенерованого випадкового числа */
    int random;
    
    /* Ініціалізація нової множини */
    given_set.size = 10;
    given_set.range_min = -10;
    given_set.range_max = 10;
    
    do {
        cout << "Оберіть розмір множини від 1 до 10\n";
        gets(str);
        given_set.size = atoi(str);
    } while (given_set.size < 1 || given_set.size > 10);
    
    do {
        cout << "Задайте мінімальне значення для множини від -100 до "
             << 100 - given_set.size << '\n';
        gets(str);
        given_set.range_min = atoi(str);
    } while (given_set.range_min < -100 || given_set.range_min > 100 - given_set.size);
    
    do {
        cout << "Задайте максимальне значення для множини від "
             << given_set.range_min + given_set.size << " до 100\n";
        gets(str);
        given_set.range_max = atoi(str);
    } while (given_set.range_max < -100 
            || given_set.range_max > 100 
            || given_set.range_max < given_set.range_min + given_set.size);
    
    /* Виділення пам’яті для нової множини */
    given_set.start = new int[given_set.size];
    
    cout << "Ви бажаєте, щоб програма задала значення множини? (y/n): ";
    gets(str);
    if (str[0] == 'y') {
        /* Розраховуємо унікальні випадкові числа */
        i = 0;
        while(i < given_set.size) {
            /* Продовжуємо отримувати випадкові числа, доки не знайдемо таке,
             * якого іще немає в множині
             */
            random = rand() % (given_set.range_max - (given_set.range_min - 1)) + given_set.range_min;
            if ( !(exist(random, given_set.start, i)) ) {
                *(given_set.start + i) = random;
                i++;
            }
        }
    } else {
        cout << "Задайте значення елементів множини.\n";
        for (i = 0; i < given_set.size; i++){
            /* Перевіряємо отримані числа, щоб вони входили в допустимий діапазон
             * і були унікальними
             */
            do {
                cout << i << ": ";
                gets(str);
                *(given_set.start + i) = atoi(str);
            } while (*(given_set.start + i) < given_set.range_min 
                    || *(given_set.start + i) > given_set.range_max
                    || exist(*(given_set.start + i), given_set.start, i));
        }
    }
    
    /* Повертаємо утворену множину */
    return given_set;
}

void print_set(set given_set) {
    int i = 0;
    
    /* Послідовно виводимо елементи масиву через пробіл */
    for (i = 0; i < given_set.size; i++) {
        cout << *(given_set.start + i) << ' ';
    }
    
    cout << '\n';
}

bool exist(int number, int *array, int size) {
    int i;
    
    /* Перевіряємо елементи масиву доки не знайдемо задане число */
    for (i = 0; i < size; i++){
        if (*(array + i) == number) {
            return true;
        }
    }
    
    return false;
}

set intersect(set a, set b) {
    /* Лічильники */
    int i, j;
    /* Розмір нової множини */
    int new_size = 0;
    /* Покажчик на початок нової множини */
    int *ptr;
    /* Нова множина */
    set new_set;
    
    /* Знаходимо меншу множину */
    if (a.size < b.size) {
        /* При перетині елементів буде не більше ніж в меншій множині */
        ptr = new int[a.size];
        /* Знаходимо однакові елементи */
        for (i = 0; i < a.size; i++) {
            for (j = 0; j < b.size; j++) {
                if( *(a.start + i) == *(b.start + j) ) {
                    *(ptr + new_size) = *(a.start + i);
                    new_size++;
                }
            }
        }
    } else {
        ptr = new int[b.size];
        for (i = 0; i < b.size; i++) {
            for (j = 0; j < a.size; j++) {
                if( *(b.start + i) == *(a.start + j) ) {
                    *(ptr + new_size) = *(b.start + i);
                    new_size++;
                }
            }
        }
    }
    
    /* Ініціалізуємо нову множину */
    new_set.size = new_size;
    new_set.start = ptr;
    
    /* Повертаємо нову множину */
    return new_set;
}

Які є зауваження по коду?

Чи правильно я зрозумів умови задачі?

Є питання по 133 рядку. Якщо на українській розкладці ввести 'н', а потім змінити розкладку на англійську і прибрати 'н' і написати 'y', то програма запропонує ввести елементи автоматично. Як із цим боротись?

8

Re: Задача по Set C++

1. Ви фактично винайшли std::set. В умові я ніде не помітив "не користуватися множинами зі стандартної бібліотеки". Так і треба?
2. Пам'ять не тече - вона падає Ніагарою. 6 new, 0 delete.
3. stdio та iostream - різні бібліотеки для однієї мети. Бажано користуватися тільки однією, YAGNI.
4. Ви не використовуєте передачу по посиланнях, що вкупі з п.2 і створює Ніагару.
5. Замість *(a+b) краще писати a[ b ]. Це краще читається. Нотацію *(a+b) краще використовувати при операціях із вказівниками на кшталт a+=b;*a.
6. По 133-му рядку - подивіться, що знаходиться в str після вводу.

9 Востаннє редагувалося Ярослав (05.05.2015 06:50:33)

Re: Задача по Set C++

Із врахуванням зауважень koala.

/* 
 * set_operations
 * 1. Користувач вибирає розмір трьох множин,
 *    діапазон їх значень і задає значення елементів.
 * 2. Програма виводить множини на екран.
 * 3. Програма розраховує функції:
 *    В∩(С∩А∩В);
 *    |A∩C|;
 *    2^B
 *    і виводить результат на екран.
 */


#include <cstdlib>
#include <iostream>
/* INPUT_BUFFER - буфер для вводу користувача */
#define INPUT_BUFFER 20

using namespace std;

/* set - множина 
 * start - покажчик на початок масиву із елементами множини
 * size - розмір множини
 * range_max - максимальне значення елементів множини
 * range_min - мінімальне значення елементів множини
 */
struct set {
    int *start;
    int size;
    int range_max;
    int range_min;
};

/* init_set - ініціалізує множину із параметрами, заданими користувачем */
set  init_set(void);
/* print_set - виводить на екран множину */
void print_set(set given_set);
/* remove set - звільняє пам’ять, виділену під множину */
void remove_set(set given_set);
/* intersect - розраховує перетин двох множин */
set  intersect(set a, set b);
/* exist - визначає чи є задане число в масиві */
bool exist(int number, int *array, int size);

/*
 * Демонстрація роботи із множинами 
 */
int main(int argc, char** argv) {
    set a, b, c, d, e;
    
    /* Ініціалізація множин */
    cout << "Будь ласка, задайте початкові значення множин.\n"
            "Множина A.\n";
    a = init_set();
    cout << "Множина B.\n";
    b = init_set();
    cout << "Множина C.\n";
    c = init_set();
    
    /* Вивід на екран */
    cout << "Утворені наступні множини:\n"
            "A: ";
    print_set(a);
    cout << "B: ";
    print_set(b);
    cout << "C: ";
    print_set(c);
    
    /* Демонстрація розрахунків */
    cout << "Обраховується формула В∩(С∩А∩В).\n";
    d = intersect(a, b);
    e = intersect(d, c);
    cout << "В∩(С∩А∩В) = ";
    if (e.size) {
        print_set(e);
    } else {
        cout << "Порожня множина\n";
    }
    
    /* Звільняємо пам’ять */
    remove_set(d);
    remove_set(e);
                
    cout << "Обраховується формула |A∩C|.\n";
    d = intersect(a, c);
    cout << "|A∩C| = " << d.size << '\n';
    
    cout << "Обраховується формула 2^B.\n";
    if (b.size == 1 && *(b.start) == 2) {
        cout << "2^B = true\n";
    } else {
        cout << "2^B = false\n";
    }
    
    /* Звільняємо пам’ять */
    remove_set(a);
    remove_set(b);
    remove_set(c);
    remove_set(d);
        
    return 0;
}

set init_set(void) {
    /* Нова множина */
    set given_set;
    /* Буфер для вводу користувача */
    char str[ INPUT_BUFFER ];
    /* Лічильник */
    int i;
    /* Змінна для згенерованого випадкового числа */
    int random;
    
    /* Ініціалізація нової множини */
    given_set.size = 10;
    given_set.range_min = -10;
    given_set.range_max = 10;
    
    do {
        cout << "Оберіть розмір множини від 1 до 10\n";
        cin >> str;
        given_set.size = atoi(str);
    } while (given_set.size < 1 || given_set.size > 10);
    
    do {
        cout << "Задайте мінімальне значення для множини від -100 до "
             << 100 - given_set.size << '\n';
        cin >> str;
        given_set.range_min = atoi(str);
    } while (given_set.range_min < -100 || given_set.range_min > 100 - given_set.size);
    
    do {
        cout << "Задайте максимальне значення для множини від "
             << given_set.range_min + given_set.size << " до 100\n";
        cin >> str;
        given_set.range_max = atoi(str);
    } while (given_set.range_max < -100 
            || given_set.range_max > 100 
            || given_set.range_max < given_set.range_min + given_set.size);
    
    /* Виділення пам’яті для нової множини */
    given_set.start = new int[ given_set.size ];
    
    cout << "Ви бажаєте, щоб програма задала значення множини? (y/n): ";
    cin >> str;
    if (str[ 0 ] == 'y') {
        /* Розраховуємо унікальні випадкові числа */
        i = 0;
        while(i < given_set.size) {
            /* Продовжуємо отримувати випадкові числа, доки не знайдемо таке,
             * якого іще немає в множині
             */
            random = rand() % (given_set.range_max - (given_set.range_min - 1)) + given_set.range_min;
            if ( !(exist(random, given_set.start, i)) ) {
                given_set.start[ i ] = random;
                i++;
            }
        }
    } else {
        cout << "Задайте значення елементів множини.\n";
        for (i = 0; i < given_set.size; i++){
            /* Перевіряємо отримані числа, щоб вони входили в допустимий діапазон
             * і були унікальними
             */
            do {
                cout << i << ": ";
                cin >> str;
                given_set.start[ i ] = atoi(str);
            } while (given_set.start[ i ] < given_set.range_min 
                    || given_set.start[ i ] > given_set.range_max
                    || exist(given_set.start[ i ], given_set.start, i));
        }
    }
    
    /* Повертаємо утворену множину */
    return given_set;
}

void print_set(set given_set) {
    int i = 0;
    
    /* Послідовно виводимо елементи масиву через пробіл */
    for (i = 0; i < given_set.size; i++) {
        cout << *(given_set.start + i) << ' ';
    }
    
    cout << '\n';
}

void remove_set(set given_set) {
    /* Звільнення пам’яті, виділеної для множини */
    delete given_set.start;
}

bool exist(int number, int *array, int size) {
    int i;
    
    /* Перевіряємо елементи масиву доки не знайдемо задане число */
    for (i = 0; i < size; i++){
        if (array[ i ] == number) {
            return true;
        }
    }
    
    return false;
}

set intersect(set a, set b) {
    /* Лічильники */
    int i, j;
    /* Розмір нової множини */
    int new_size = 0;
    /* Покажчик на початок нової множини */
    int *ptr;
    /* Нова множина */
    set new_set;
    
    /* Знаходимо меншу множину */
    if (a.size < b.size) {
        /* При перетині елементів буде не більше ніж в меншій множині */
        ptr = new int[ a.size ];
        /* Знаходимо однакові елементи */
        for (i = 0; i < a.size; i++) {
            for (j = 0; j < b.size; j++) {
                if( a.start[ i ] == b.start[ j ] ) {
                    ptr[ new_size ] = a.start[ i ];
                    new_size++;
                }
            }
        }
    } else {
        ptr = new int[ b.size ];
        for (i = 0; i < b.size; i++) {
            for (j = 0; j < a.size; j++) {
                if( b.start[ i ] == a.start[ j ] ) {
                    ptr[ new_size ] = b.start[ i ];
                    new_size++;
                }
            }
        }
    }
    
    /* Ініціалізуємо нову множину */
    new_set.size = new_size;
    new_set.start = ptr;
    
    /* Повертаємо нову множину */
    return new_set;
}

10 Востаннє редагувалося koala (05.05.2015 08:52:33)

Re: Задача по Set C++

П. 4 лишився на місці.
Ну і для того, щоб спростити код, придумали конструктор (замість init_set) і деструктор (замість remove_set).
А ще останній пункт - це ось це.

11 Востаннє редагувалося koala (06.05.2015 06:08:15)

Re: Задача по Set C++

Вільні варіації на задану тему
#include <iostream>  //cin, cout
#include <set>       //set
#include <algorithm> //set_intersection, for_each
#include <string>    //string
#include <sstream>   //stringstream
#include <cstdlib>   //rand
#include <vector>    //vector

using namespace std;

int input_int(int min, int max, const string& prompt);
void input_set(set<int>& given_set);
void output_set(const set<int>& given_set);
set<int> intersect(const set<int>& set1, const set<int>& set2);
void boolean(const set<int>& given_set);

int main() {
    setlocale(LC_ALL, "Ukrainian");
    set<int> A, B, C;
    cout << "Будь ласка, задайте початкові значення множин.\n"
        << "Множина A.\n";
    input_set(A);
    cout << "Множина B.\n";
    input_set(B);
    cout << "Множина C.\n";
    input_set(C);
    cout << "Утворені наступні множини:\n"
        << "A: ";
    output_set(A);
    cout << "B: ";
    output_set(B);
    cout << "C: ";
    output_set(C);
    cout << "Обраховується формула В^(С^А^В).\n";
    output_set(intersect(B, intersect(C, intersect(A, B))));
    cout << "Обраховується формула |A^C|.\n";
    cout << intersect(A, C).size() << '\n';
        cout << "Булеан B:";
    boolean(B);

    return 0;
}

int input_int(int min, int max, const string& prompt)
{
    int value;
    do {
        cout << prompt;
        cin.clear();
        cin >> value;
    } while (!cin || (value < min) || (value > max));
    return value;
}

void input_set(set<int>& given_set)
{
    size_t size = input_int(1, 10, "Оберіть розмір множини від 1 до 10\n");
    stringstream ss;
    ss << "Задайте мінімальне значення для множини від -100 до " << (100 - size);
    int min = input_int(-100, 100 - size, ss.str());
    ss.str("");
    ss << "Задайте максимальне значення для множини від " << int(size + min) << " до 100\n";
    int max = input_int(min + size, 100, ss.str());
    cout << "Ви бажаєте, щоб програма задала значення множини? (y/n): ";
    char newValues;
    cin >> newValues;
    if (newValues == 'y'){
        vector<int> values(max - min + 1); //числа від min до max
        for (int i = 0; i < max - min + 1; ++i) {
            values[i] = i + min;
        }
        random_shuffle(values.begin(), values.end());
        while (size--) {
            given_set.insert(values[size]);
        }
    }
    else {
        while (given_set.size() < size) {
            given_set.insert(input_int(min, max, "Задайте значення елементів множини.\n"));
        }
    }
}

void output_set(const set<int>& given_set)
{
    for (auto x : given_set)
        cout << x << " ";
    cout << '\n';
}

set<int> intersect(const set<int>& set1, const set<int>& set2)
{
    set<int> result;
    for (int x : set1) {
        result.insert(x);
    }
    for (int x : set2) {
        result.insert(x);
    }
    return result;
}

void boolean(const set<int>& given_set)
{
    vector<bool> includes(given_set.size() + 1);
    while (!includes[given_set.size()]) {
        cout << "{ ";
        int i = 0;
        for (set<int>::const_iterator element = given_set.begin(); 
                                      element != given_set.end(); 
                                      ++element, ++i) {
            if (includes[i]) {
                cout << *element << " ";
            }
        }
        for (auto element = includes.begin(); element < includes.end(); ++element) {
            *element = !*element;
            if ( *element ){
                break;
            }
        }
        cout << "}\n";
    }
}

P.S. Трохи виправив intersect

12

Re: Задача по Set C++

Класно! Для мене в цьому коді багато нового, іще, але головна ідея зрозуміла. Дякую!

13

Re: Задача по Set C++

Я ледь мозок не зламав над void boolean(const set<int>& given_set). :D

Подякували: Yola1