Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.03.2023, 16:22   #31
Damyen
Пользователь
 
Регистрация: 14.03.2022
Сообщений: 32
По умолчанию

Помогите разобраться с участком кода. Вот пример из книги. Пользователь вводит цифрой количество карт, которые ему нужно выдать, и программа выдает ему эти карты. Мне все понято, кроме одного. Кроме функции "int celectnext(int n)". По книге эта функция должна пропускать вытянутые карты, и выдавать только новые карты. Но я все равно никак не могу понять, как это происходит. Вот код.

Код:
#include <iostream>
#include <math.h>
#include <time.h>
#include <stdlib.h>
using namespace std;
int random(int n);
void cards();
const char*suits[4]={"heats", "diamonds", "spades", "clubs"};
const char*ranks[13]={"ace", "two", "three", "four", "five", "six", "seven", 
                        "eight", "nine", "ten", "jack", "queen", "king"};
int selectnext(int n);
int cardsdrawn[52];
int cardsremai=52;
int main()
{
    int n, i;
    srand(time(NULL));
    cout<<"Enter the number of combinations and press enter ";
    cin>>n;
    for(i=1; i<=n; i++)
    cards();
    return 0;
}
void cards()
{
    int s,r,ca,n;
    n=random(cardsremai--);
    ca=selectnext(n);
    s=ca/13;
    r=ca%13;
    cout<<ranks[r]<<" "<<suits[s]<<endl;
}
int selectnext(int n)
{
    int i=0;
    while(cardsdrawn[i])
    i++;
    while(n-->0)
    {
        i++;
        while(cardsdrawn[i])
        i++;
    }
        cardsdrawn[i]=true;
        return i;
}
int random(int n)
{
    return rand()%n;
}
Сначала мы вводим количество комбинаций (количество карт). Потом мы переходим в фунцию void_cards(), получаем случаное число n(которое находится в диапазоне до 52). А потом переходим в функцию "int selectnext". Которая якобы должна пропускать все вытянутве карты. И как это происходит?
Damyen вне форума Ответить с цитированием
Старый 10.03.2023, 16:53   #32
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от Damyen Посмотреть сообщение
Код:
cardsdrawn[i]=true;
А разве это не должно быть в цикле while
Код:
int selectnext(int n)
{
    int i=0;
    while(n-- > 0)
    {
        while(i< 52 && cardsdrawn[i]) // Пропускаем все выданные карты
          i++;
        if (i == 52) break; // Чтобы не выйти за границы массива
        cardsdrawn[i]=true; // Помечаем очередную карту выданной
    }
    return i; // Возвращает индекс только последней выданной карты. Чтобы вернуть все, тогда надо индексы собрать в массив. А вот если карт в массиве нету, тогда возвращает индекс за его пределами (52)
}
macomics вне форума Ответить с цитированием
Старый 10.03.2023, 17:10   #33
Damyen
Пользователь
 
Регистрация: 14.03.2022
Сообщений: 32
По умолчанию

Ну в моем коде пока еще нет "защиты от выхода за границы массива". Вот эта переменная "n", которая используется в функции "selectnext" - это же n, которая была получена в функции cards? То есть она обозначает случайное число, до 52? А не число карт, которое мы обозначили тоже как n, которое мы вводили в первой функции.
Damyen вне форума Ответить с цитированием
Старый 10.03.2023, 17:14   #34
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Тогда функция сама по себе написана не верно. Достаточно проверить выдана ли карта с этим индексом и вернуть в ответ да или нет.
Код:
int selectnext(int n)
{
    return (n < 52 && !cardsdrawn[n]) ? 1 : 0;
}
ADD: А даже если посмотреть функцию cards, то и в ней ошибка. Вы уменьшаете cardsremai, и в результат n у вас будет все меньше и меньше, хотя в хвосте массива могут остаться карты.

Смотрите: Если при первом срабатывании cardsremai = 52 и n примет значения от 0 до 51.
Скажем что выпало n = 5, тогда cardsremai = 51 и выдали карту с индексом 5.
Тогда при втором срабатывании cardsremai = 51 и n примет значения уже от 0 до 50 (51 ещё не выдана, но её индекс уже не будет выбран).
Скажем что теперь выпало n = 50, тогда cardsremai = 50 и выдали карту с индексом 50.
А теперь при третьем срабатывании cardsremai = 50 и n примет значения от 0 до 49 (51 ещё не выдана, но её индекс уже не будет выбран, хотя 50 карта уже выдана и её индекс уже не нужен).
Скажем опять выпало n = 5, тогда карта не будет выдана повторно, хотя сама функция cards этого не учитывает.

Последний раз редактировалось macomics; 10.03.2023 в 17:22.
macomics вне форума Ответить с цитированием
Старый 10.03.2023, 17:16   #35
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,429
По умолчанию

Код:
int selectnext(int n)
{
    int i = 0;
    while (cardsdrawn[i]) // этим циклом пропускаем все уже выданные карты из начала
        i++;
    while (n-- > 0) // если n больше нуля, то...
    {
        i++; // переходим к следующей карте
        while (cardsdrawn[i]) // этим циклом пропускаем все уже выданные карты
            i++;
    }
    cardsdrawn[i] = true;
    return i;
}
Циклом "while (n-- > 0)" пересчитываются только те карты, которые еще не выданы, т.к. цикл "while (cardsdrawn[i]) i++;" проматывает выданные.
Цитата:
Сообщение от macomics Посмотреть сообщение
Не стоит на это полагаться.
Так если по стандарту должны быть нули, то это уже забота компилятора под определённую ОС, добавлять ли специальный код для инициализации или разместить переменную в правильной секции. Про неочевидные ошибки согласен - лучше стараться использовать локальные переменные и явно их инициализировать.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 10.03.2023 в 17:26.
BDA вне форума Ответить с цитированием
Старый 10.03.2023, 17:24   #36
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

BDA, я не читал весь код. Только функцию, которая была указана.
macomics вне форума Ответить с цитированием
Старый 10.03.2023, 17:26   #37
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,429
По умолчанию

Цитата:
Сообщение от macomics Посмотреть сообщение
Тогда функция сама по себе написана не верно.
В функции cards выбирается "новый" индекс (только среди невыбранных), который с помощью selectnext преобразуется в "старый" индекс (среди всех существующих карт).
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 10.03.2023, 17:28   #38
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
В функции cards выбирается "новый" индекс (только среди невыбранных), который с помощью selectnext преобразуется в "старый" индекс (среди всех существующих карт).
А стоило прочитать весь текст программы.

Последний раз редактировалось macomics; 10.03.2023 в 17:34.
macomics вне форума Ответить с цитированием
Старый 11.03.2023, 12:19   #39
Damyen
Пользователь
 
Регистрация: 14.03.2022
Сообщений: 32
По умолчанию

Ну вот сам код программы из книги. Допустим мы ввели любое число комбинаций, пусть будет 10. Для каждого числа просчитывается своя комбинация. Допустим мы вычислили случайное число от 0 до 52. Пусть это будет 20. Потом эта 20 передается в функцию selext_next_available.
Эта функция начинается с цикла while. Так как i=0. То функция while(card_drawn[i]) начинает опрос нулевого элемента массива card_drawn. Но, так как этот массив является глобальным, этот нулевой элемент массива равняется нулю. Поэтому получаем while(0) и сразу переходим в while(n-->0). А зачем нам отнимать единицу от случайного числа 20? Все равно не могу понять, как это поможет "отметить" эту карту уже вытянутой.
Изображения
Тип файла: jpg Вопрос4.jpg (115.3 Кб, 1 просмотров)
Damyen вне форума Ответить с цитированием
Старый 11.03.2023, 13:13   #40
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Я вот тоже, прочитав код только одной функции, не разобрался в чем тут дело.
Совет: возьмите отладчик и пройдите программу по шагам, наблюдая за всеми переменными на каждом шаге. Так вы наглядно сможете увидеть что происходит и разобраться в значениях.
macomics вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопросы по C и C++ jonikster Общие вопросы C/C++ 25 17.11.2017 09:10
Вопросы Ilai Помощь студентам 5 29.10.2014 21:35
Вопросы по БД Rost93 PHP 9 28.06.2011 22:18
Вопросы по С++ Fantazerishka Общие вопросы C/C++ 2 19.05.2010 06:52