81

(3 відповідей, залишених у C++)

Задача така: Створити функцію для роботи з дин двовимірним рваним масивом(рядки можуть  бути різної довжини): пошук заданого значення у масиві(повертати вказівник на перше входження шуканого чи nullptr, якщо не знайдено).
Я реалізувала її таким чинном:

Прихований текст
int * searchFirstEntryElement(int ** mas, int row, int elem)
{
    int *p = NULL;
    for (int i = 0; i < row; ++i)
    {
        int col = mas[i][0];
        int j = 1;
        while (mas[i][j] != elem && j <= col)
            ++j;
        if (j <= col)
        {
            p = &mas[i][j];
            return p;
        }
     }

    return p;
}
int main()
{
...
int find_element;
    cout << "Enter number wich you want find in the matrix: ";
    cin >> find_element;
    int first_entry_elements = *searchFirstEntryElement(numbers, rows, find_element);
    if (first_entry_elements != NULL)
        cout << "The first entry of the desired element: " << first_entry_elements << "\n";
    else
        cout << "The desired element is not found\n";
}

І, власне, сама проблема: якщо елемент знайдено, то працює нормально, а якщо - ні, то програма вилітає. В чому може бути причина?

82

(5 відповідей, залишених у C++)

Дякую. Знову ви мене виручили :[

83

(5 відповідей, залишених у C++)

Реалізувала таким чином:

Прихований текст
#include <iostream>
#include <stdlib.h>
#include <ctime>
 
using namespace std;
 
int main()
{
    srand(unsigned(time(0)));
 
    const int ARRAY_SIZE = 10;
 
    double *p_numbers[ARRAY_SIZE];
    for (int i = 0; i < ARRAY_SIZE; ++i)
        p_numbers[i] = new double(-5 + (double)rand() / RAND_MAX * 25);
 
 
    cout << "Array: \n";
    for(int i = 0; i < ARRAY_SIZE; ++i)
        cout << *p_numbers[i] << " ";
     cout << "\n";
 
     double min = *p_numbers[0];
     int pos_min = 0;
     for (int i = 1; i < ARRAY_SIZE; ++i)
     { if (*p_numbers[i] < min)
            min = *p_numbers[i];
            pos_min = i;
     }
     cout << "Min: " << min << "\n";
 
     *p_numbers[pos_min] = *p_numbers[ARRAY_SIZE - 1];
     *p_numbers[ARRAY_SIZE - 1] = min;
  
    cout << "Swap array: \n";
    for(int i = 0; i < ARRAY_SIZE; ++i)
        cout << *p_numbers[i] << " ";
     cout << "\n";
 
     for (int i = 0; i < ARRAY_SIZE; ++i)
        delete p_numbers[i];
 
    return 0;
}

Але тепер інша проблема: не міняються місцями елементи, а мінімальний дублюється на місці останнього, а той просто зникає. Що може бути не так?

84

(5 відповідей, залишених у C++)

Задача така: Утворити масив із 10 вказівників на динамічні дробові змінні (кожен елемент масиву вказує на одну дробову змінну). Динамічні дробові змінні проініціалізувати випадковими значеннями (або з клавіатури). Знайти найменше число серед створених динамічних змінних і поміняти його місцями з останнім числом.

І, ніби все ясно, але проблема в тому, я не знаю як оформити масив вказівників на динамічні змінні, щоб не вручну записувати всі 10 змінних.
Поясніть мені, будь ласка, як це правильно зробити.

85

(2 відповідей, залишених у C++)

дякую, вийшло

Задача: дано два паралельних одновимірних масиви: масив назв товарів(string) та масив цін. Їх потрібно паралельно заповнити і відсортувати відповідно до цін: або за спаданням, або за зростанням.
Щоб ввести рядок із пробілами (тут Name -> mas1), використовую getline, але після першого ж введення все ламається і далі вже запитує лише ціну.

Ось код введення:

template <typename T1, typename T2>
void inputGoods(T1 mas1[], T2 mas2[], int size)
{
    for (int i = 0; i < size; i++)
    {
        cout << "\n\t---Goods " << i + 1 << "---\n";
        cout << "\nName: ";
        getline(cin,mas1[i]);
        cout << "\nPrice: ";
        cin >> mas2[i];
    }
}

І ось таке в результаті:

Прихований текст

http://i.imgur.com/sTe0ygX.png?1

Що не так? Як зробити правильно?

Зрозуміла, дуже і дуже дякую

koala, я вам дуже дякую за терпіння і допомогу.
Я, здається,  зрозуміла, у внутрішньому циклі потрібно зробити так

for (int j = size - 1; j >= i + 1; j--)
koala написав:

А нащо вам swap?

Це я перевіряла одну теорію, яку знайшла в неті, і просто забула видалити. *PARDON*

koala написав:

Перевірте ще раз границі циклів. Зокрема, кінець внутрішнього.

Здається все працює. Це впорядкування елементів за зростанням, а якщо треба за спаданням, то достатньо змінити умову?

Я вас правильно зрозуміла?

Прихований текст
void stoneSort(T mas[], int size)
{
    bool swap = true;
    while (swap)
    {
        for (int i = 0; i < size - 1; i++)
        {
            swap = false;
            for (int j = size - 1; j >= i; j--)
            {
                if (mas[j - 1] > mas[j])
                {
                    T temp = mas[j];
                    mas[j] = mas[j - 1];
                    mas[j - 1] = temp;
                    swap = true;
                }
            }
        }
    }
}

Дякую. І ще питання тоді "камінець" це як? Так як "бульбашка", тільки йти від кінця масиву?

koala, дякую, я вже виправила. Це правильно?

template <typename T>
void bubbleSort(T mas[], int size)
{
    T swap;
    for (int i = 0; i < size - 1; i++)
    {
        for (int j = 0; j < size - 1 - i; j++)
        {
            if (mas[j] > mas[j + 1])
            {
                swap = mas[j];
                mas[j] = mas[j + 1];
                mas[j + 1] = swap;
            }
        }
    }
}

koala, сортування працює: масив впорядковується по-зростанню.

Прихований текст

http://i.imgur.com/EHO1LRP.png

Тільки я не знаю чи правильно зрозуміла суть алгоритму.

94

(10 відповідей, залишених у C++)

Дякую всім, хто відгукнувся на мої питання. Завдяки вашим підказкам, в мене вийшло реалізувати, хай не ідеально, гру "Хрестики-нулики".
Можливо, комусь буде цікаво, а, можливо, і корисно:

Прихований текст
/* "Гра х0. Перший гравець вибирається випадковим чином. Можна використ глоб масив." */

#include <iostream>
#include <ctime>
//#include <string>
#include <windows.h>
//#include <conio.h>
#include <cstdio>

using namespace std;

// global variables
const int FIELD_SIZE = 3, WIN_LINE_LENGTH = 3;
enum key { UP, DOWN, LEFT, RIGHT, ENTER, ESCAPE };
char game_field[FIELD_SIZE][FIELD_SIZE];
int pointer_row = 0, pointer_col = 0;

// function prototypes
char pointer(int row, int col);
void drawRow(char symbol, char pointer);
int choiceFirstPlayer();
void paintGameField();
bool movePointer(int direction);
short getKeyPressed();
bool putPlayerMark(char player_mark);
bool vitalComputerMove(char mark, char computer_mark);
void computerMove(char player_mark, char computer_mark);
bool checkFreeCorner(char computer_mark);
bool checkFreeCell(char computer_mark);
int checkWinner(char computer_mark, char player_mark);


int main()
{
    cout.sync_with_stdio(false);
    srand(unsigned(time(0)));

    for (int i = 0; i < FIELD_SIZE; i++)
        for (int j = 0; j < FIELD_SIZE; j++)
            game_field[i][j] = ' ';

    // choose first player, set marks
    int first = choiceFirstPlayer();
    char player_mark, computer_mark;
    if (first == 0)
    {
        computer_mark = 'O';
        player_mark = 'X';
    }
    else
    {
        computer_mark = 'X';
        player_mark = 'O';
        computerMove(player_mark, computer_mark);
    }

    short key;
    bool exit = false, action = false;
    int winner;
    paintGameField();
    do {
        // take keyboard input
        key = getKeyPressed();
        // do something - move_cursor, put X or O, etc.
        switch (key)
        {
        case ESCAPE:
            exit = true;
            break;
        case ENTER:
            action = putPlayerMark(player_mark);
            if (action)
            {
                winner = checkWinner(computer_mark, player_mark);
                // if not winner, computerMove()
                if (winner == -1)
                {
                    computerMove(player_mark, computer_mark);
                    winner = checkWinner(computer_mark, player_mark);
                    if (winner != -1)
                        exit = true;
                }
                else
                    exit = true;
            }
            break;
        default:
            action = movePointer(key);
        }
        if (action)
        {
            system("cls");
            paintGameField();
        }
        // continue loop if game is not finished
        Sleep(50);
    } while (!exit);
    if (winner == 0)
        cout << "\n\tYOU LOSE\n";
    else if (winner == 1)
        cout << "\n\tYUO WIN\n";
    else
        cout << "\n\tDRAW\n";
    return 0;
}

int choiceFirstPlayer()
{
    int player = rand() % 2;
    return player;
}

short getKeyPressed()
{
    if (GetAsyncKeyState(VK_UP) < 0)
        return UP;
    else if (GetAsyncKeyState(VK_DOWN) < 0)
        return DOWN;
    else if (GetAsyncKeyState(VK_LEFT) < 0)
        return LEFT;
    else if (GetAsyncKeyState(VK_RIGHT) < 0)
        return RIGHT;
    else if (GetAsyncKeyState(VK_ESCAPE) < 0)
        return ESCAPE;
    else if (GetAsyncKeyState(VK_RETURN) < 0)
        return ENTER;
    else
        return -1;
}

void drawRow(int row)
{
    for (int i = 0; i < FIELD_SIZE; i++)
        cout << " ___" << " ";
    cout << endl;
    for (int i = 0; i < FIELD_SIZE; i++)
        cout << "|" << pointer(row, i) << "  |";
    cout << endl;
    for (int i = 0; i < FIELD_SIZE; i++)
        cout << "| " << game_field[row][i] << " |";
    cout << endl;
    for (int i = 0; i < FIELD_SIZE; i++)
    cout << "|___|";
    cout << endl;
}

void paintGameField()
{
    cout << "\tNoughts and Crosses game\n\n";

    for (int i = 0; i < FIELD_SIZE; i++)
        drawRow(i);

}

bool movePointer(int direction)
{
    bool move = false;
    switch (direction)
    {
    case UP:
        pointer_row--;
        if (pointer_row < 0)
            pointer_row = FIELD_SIZE - 1;
        move = true;
        break;
    case DOWN:
        pointer_row++;
        if (pointer_row > FIELD_SIZE - 1)
            pointer_row = 0;
        move = true;
        break;
    case LEFT:
        pointer_col--;
        if (pointer_col < 0)
            pointer_col = FIELD_SIZE - 1;
        move = true;
        break;
    case RIGHT:
        pointer_col++;
        if (pointer_col > FIELD_SIZE - 1)
            pointer_col = 0;
        move = true;
        break;
    }
    return move;
}

char pointer(int row, int col)
{
    char pointer;
    if (row == pointer_row && col == pointer_col)
        pointer = '*';
    else
        pointer = ' ';
    return pointer;
} 

bool putPlayerMark(char player_mark)
{
    bool player_turn = false;
    if (game_field[pointer_row][pointer_col] == ' ')
    {
        game_field[pointer_row][pointer_col] = player_mark;
        player_turn = true;
    }
    return player_turn;
}

void computerMove(char player_mark, char computer_mark)
{
    bool computer_move = false;
    // check if computer can win with next move
    computer_move = vitalComputerMove(computer_mark, computer_mark);

    // check if computer must do a defensive move
    if (!computer_move)
        computer_move = vitalComputerMove(player_mark, computer_mark);

    //  make non-vital computer move
    if (!computer_move)
        computer_move = checkFreeCorner(computer_mark);

    if (!computer_move)
        computer_move = checkFreeCell(computer_mark);
}

/*
   Find if computer can win with next move or make a defensive move
*/
bool vitalComputerMove(char mark, char computer_mark)
{
    int count_player_mark;
    int free_col, free_row;
    bool computer_move = false;

    //check for vital computer move in rows
    for (int i = 0; i < FIELD_SIZE; i++)
    {
        count_player_mark = 0;
        free_col = -1;
        for (int j = 0; j < FIELD_SIZE; j++)
        {
            if (game_field[i][j] == mark)
                count_player_mark++;
            else if (game_field[i][j] == ' ')
                free_col = j;
        }
        if (count_player_mark == 2 && free_col != -1)
        {
            game_field[i][free_col] = computer_mark;
            computer_move = true;
            break;
        }
    }
    if (computer_move)
        return computer_move;

    //check for vital computer move in main diagonal
    count_player_mark = 0;
    for (int i = 0; i < FIELD_SIZE; i++)
    {
        free_col = -1;
        free_row = -1;
        if (game_field[i][i] == mark)
            count_player_mark++;
        else if (game_field[i][i] == ' ')
            free_row = free_col = i;
    }
    if (count_player_mark == 2 && free_col != -1 && free_row != -1)
    {
        game_field[free_row][free_col] = computer_mark;
        // exit from function, no sense to check other variants
        computer_move = true;
        return computer_move;
    }

    count_player_mark = 0;
    // check for vital computer move in side diagonal
    free_col = -1;
    free_row = -1;
    for (int i = 0; i < FIELD_SIZE; i++)
    {
        if (game_field[i][FIELD_SIZE - 1 - i] == mark)
            count_player_mark++;
        else if (game_field[i][FIELD_SIZE - 1 - i] == ' ')
        {
            free_row = i;
            free_col = FIELD_SIZE - 1 - i;
        }
    }
    if (count_player_mark == 2 && free_col != -1 && free_row != -1)
    {
        game_field[free_row][free_col] = computer_mark;
        // exit from function, no sense to check other variants
        computer_move = true;
        return computer_move;
    }

    // check for vital computer move in columns
    for (int j = 0; j < FIELD_SIZE; j++)
    {
        free_row = -1;
        count_player_mark = 0;
        for (int i = 0; i < FIELD_SIZE; i++)
        {
            if (game_field[i][j] == mark)
                count_player_mark++;
            else if (game_field[i][j] == ' ')
                free_row = i;
        }
        if (count_player_mark == 2 && free_row != -1)
        {
            game_field[free_row][j] = computer_mark;
            computer_move = true;
            break;
        }
    }
    if (computer_move)
        return computer_move;

    return computer_move;
}

bool checkFreeCorner(char computer_mark)
{
    bool computer_move = false;
    if (game_field[FIELD_SIZE / 2][FIELD_SIZE / 2] == ' ')
    {
        game_field[FIELD_SIZE / 2][FIELD_SIZE / 2] = computer_mark;
        computer_move = true;
    }
    else if (game_field[0][0] == ' ')
    {
        game_field[0][0] = computer_mark;
        computer_move = true;
    }
    else if (game_field[FIELD_SIZE - 1][FIELD_SIZE - 1] == ' ')
    {
        game_field[FIELD_SIZE - 1][FIELD_SIZE - 1] = computer_mark;
        computer_move = true;
    }
    else if (game_field[FIELD_SIZE - 1][0] == ' ')
    {
        game_field[FIELD_SIZE - 1][0] = computer_mark;
        computer_move = true;
    }
    else if (game_field[0][FIELD_SIZE - 1] == ' ')
    {
        game_field[0][FIELD_SIZE - 1] = computer_mark;
        computer_move = true;
    }

    return computer_move;
}

bool checkFreeCell(char computer_mark)
{
    bool computer_move = false;
    for (int i = 0; i < FIELD_SIZE; i++)
    {
        for (int j = 0; j < FIELD_SIZE; j++)
        {
            if (game_field[i][j] == ' ')
            {
                game_field[i][j] = computer_mark;
                computer_move = true;
                return computer_move;
            }
        }
    }
    return computer_move;
}

int checkWinner(char computer_mark, char player_mark)
{
    int winner = -1;
    char mark;
    int count_mark;

    // check winner in row
    for (int i = 0; i < FIELD_SIZE; i++)
    {
        count_mark = 1;
        mark = game_field[i][0];
        for (int j = 1; j < FIELD_SIZE; j++)
        {
            if (game_field[i][j] == mark)
                count_mark++;
            else
                break;
        }
        if (count_mark == WIN_LINE_LENGTH)
        {
            if (mark == computer_mark)
            {
                winner = 0;
                return winner;
            }
            else if (mark == player_mark)
            {
                winner = 1;
                return winner;
            }
        }
    }

    // check winner in main diagonal
    mark = game_field[0][0];
    count_mark = 1;
    for (int i = 1; i < FIELD_SIZE; i++)
    {
        if (game_field[i][i] == mark)
            count_mark++;
    }
    if (count_mark == WIN_LINE_LENGTH)
    {
        if (mark == computer_mark)
        {
            winner = 0;
            return winner;
        }
        else if (mark == player_mark)
        {
            winner = 1;
            return winner;
        }
    }

    // check winner in side diagonal
    mark = game_field[0][FIELD_SIZE - 1];
    count_mark = 1;
    for (int i = 1; i < FIELD_SIZE; i++)
    {
        if (game_field[i][FIELD_SIZE - 1 - i] == mark)
            count_mark++;
    }
    if (count_mark == WIN_LINE_LENGTH)
    {
        if (mark == computer_mark)
        {
            winner = 0;
            return winner;
        }
        else if (mark == player_mark)
        {
            winner = 1;
            return winner;
        }
    }

    // chek winner in columns
    for (int j = 0; j < FIELD_SIZE; j++)
    {
        count_mark = 1;
        mark = game_field[0][j];
        for (int i = 1; i < FIELD_SIZE; i++)
        {
            if (game_field[i][j] == mark)
                count_mark++;
            else
                break;
        }
        if (count_mark == WIN_LINE_LENGTH)
        {
            if (mark == computer_mark)
            {
                winner = 0;
                return winner;
            }
            else if (mark == player_mark)
            {
                winner = 1;
                return winner;
            }
        }
    }

    // check for a draw
    count_mark = 0;
    for (int i = 0; i < FIELD_SIZE; i++)
    {
        for (int j = 0; j < FIELD_SIZE; j++)
        {
            if (game_field[i][j] != ' ')
                count_mark++;
            else
                break;
        }
    }
    if (count_mark == FIELD_SIZE * FIELD_SIZE)
        winner = 2;

    return winner;
}

1. Поясніть, будь ласка, різницю між алгоритмами сортування "камінець" і "бульбашка". Як на мене, вони однакові, тільки один для сортування по-зростанню, а другий по-спаданню. Але викладач задав задачі, в одній потрібно використати "бульбашка" і сортувати за спаданням та зростанням, а в іншій - "камінець".
2. Я спробувала запрограмувати один алгоритм, теоретично це мав бути "бульбашка"

void bubbleSort(T mas[], int size)
{
    T swap;
    for (int i = 0; i < size - 1; i++)
    {
        for (int j = i; j < size - 1 - i; j++)
        {
            if (mas[j] > mas[j + 1])
            {
                swap = mas[j];
                mas[j] = mas[j + 1];
                mas[j + 1] = swap;
            }
        }
    }
}

Чи справді це так?

96

(10 відповідей, залишених у C++)

Я вам дуже дякую, але в мене виникло запитання: що нам дає ось цей рядок

const int watchedKeysSize = sizeof( watchedKeys ) / sizeof( watchedKeys[ 0 ] ) ;

і застосування отриманого значення в циклі?

97

(10 відповідей, залишених у C++)

Зробила таким чином:

short getKeyPressed()
{
    if (GetAsyncKeyState(VK_UP) < 0)
        return UP;
    else if (GetAsyncKeyState(VK_DOWN) < 0)
        return DOWN;
    else if (GetAsyncKeyState(VK_LEFT) < 0)
        return LEFT;
    else if (GetAsyncKeyState(VK_RIGHT) < 0)
        return RIGHT;
    else if (GetAsyncKeyState(VK_ESCAPE) < 0)
        return ESCAPE;
    else if (GetAsyncKeyState(VK_RETURN) < 0)
        return ENTER;
    else
        return -1;
}
 
int main()
{
    srand(unsigned(time(0)));

    for (int i = 0; i < FIELD_SIZE; i++)
        for (int j = 0; j < FIELD_SIZE; j++)
            game_field[i][j] = ' ';

    short key;
    bool exit = false, action = false;
    paintGameField();
    do {
        // take keyboard input
        key = getKeyPressed();
        // do something - move_cursor, put X or O, etc.
        switch (key)
        {
        case ESCAPE:
            exit = true;
            break;
        case ENTER:
            break;
        default:
            action = movePointer(key);
        }
        if (action)
        {
            system("cls");
            paintGameField();
        }
        Sleep(100);
    } while (!exit);
    return 0;
}

і все, здається, працює... Але:
1) чи можна отримати відразу, яка кнопка натиснута, а не перераховувати коди?
2) оновлення екрану дуже помітно. Як це виправити?

98

(4 відповідей, залишених у C++)

Дякую, зробила через цикл і використала cout.

99

(10 відповідей, залишених у C++)

1. Чи можна переміщати символ без перемалювання екрану?
2. Як взагалі в С++ запрограмувати реакцію на клавіатуру? Передивилась купу посилань - всі пишуть по-різному, і ніде нічого не зрозуміло.

100

(4 відповідей, залишених у C++)

Добре, cout i printf більше не змішуватиму. А щодо циклу - як??? Пробувала через sprintf - то ця функція лише з char працює, і шось ніяк не можу з циклом до толку довести:

char test[255] = "\n   |   |\
\n %c | %c | %c\
\n___|___|___\
\n   |   |\
\n %c | %c | %c\
\n___|___|___\
\n   |   |\
\n %c | %c | %c\
\n   |   |\n";
   
    for (int i = 0; i < FIELD_SIZE; i++)
        for (int j = 0; j < FIELD_SIZE; j++)
            sprintf_s(test, test, game_field[i][j]);
    printf(test);

І в результаті взагалі якась біда:

Прихований текст

http://i.imgur.com/ZvtBXYN.png?1