Форум программистов, компьютерный форум CyberForum.ru

Сдающий карты. "cards_remaining--" одинаково работает и с "--", и без - C++

Восстановить пароль Регистрация
 
jimmyknife
0 / 0 / 0
Регистрация: 03.03.2013
Сообщений: 19
08.02.2014, 19:48     Сдающий карты. "cards_remaining--" одинаково работает и с "--", и без #1
Всем привет, возник вопрос по поводу программы "сдающий карты", программа с книги "С++ без страха", автора не помню, не столь важно)
Вот код программы
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
int rand_0toN1(int n);
void draw_a_card();
int select_next_available(int n);
int card_drawn[52];
int cards_remaining=52;
char *suits[4] = {"hearts", "diamonds", "spades", "clubs"};
char *ranks[13]={"ace", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "jack", "queen", "king"};
int main(){
    srand(time(NULL));
    int n;
    while(1){
        cout<<"Enter some n. or press 0 to EXIT";
        cin>>n;
        if(n==0)
            break;
        for(int i=1;i<=n;i++){
            draw_a_card();
        }
    }
    return 0;
}
void draw_a_card(){
        int r,s,card,n;
        n=rand_0toN1(cards_remaining--);
        card=select_next_available(n);
        r=card%13;
        s=card/13;
        cout<<ranks[r]<<" of "<<suits[s]<<endl;
}
int select_next_available(int n){
    int i=0;
        while(card_drawn[i])
        i++;
    while(n-- >0){
        i++;
        while(card_drawn[i])
            i++;
    }
    card_drawn[i]=true;
    return i; 
}
int rand_0toN1(int n){
    return rand()%n;
}
Есть несколько вопросов по данной программе :
1)в функции void draw_a_card() не понятно, почему
C++
1
n=rand_0toN1(cards_remaining--);
вот тут берут cards_remaining--, а не просто cards_remaining. Пробовал стирать без --, всё вродь так же выходило, но в примере программы оно написано.
2)в функции int select_next_available непонятно вот эти строки :
C++
1
2
while(card_drawn[i])
        i++;
. Зачем сначала делать эту проверку, если она делается далее вот в этом цикле :
C++
1
while(n-- >0)
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.02.2014, 19:48     Сдающий карты. "cards_remaining--" одинаково работает и с "--", и без
Посмотрите здесь:

Замените в слове "му" на "а", а букву "ы" на "ца". C++
C++ Заменитье буквы "a" и "o" в слове на "A" и "O".
C++ Замените буквы "а" и "о" в слове на "А" и "О".
C++ Не работает "setlocale( LC_ALL,"Russian" )"
C++ Заданный словарь слов. Найти в нем слова-палиндромы, то есть такие, которые одинаково читаются слева направо и наоборот, например, "АННА", "ШАЛАШ"
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Eldies
89 / 80 / 28
Регистрация: 06.02.2014
Сообщений: 119
08.02.2014, 20:16     Сдающий карты. "cards_remaining--" одинаково работает и с "--", и без #2
1) после того, как несколько карт уже сдано, следующий выбор делается из меньшего количества карт.
если убрать --, а потом rand_0toN1 выдаст, например, два раза 51, оно вылетит.

2)
C++
1
2
3
 
while(card_drawn[i])
        i++;
Этот цикл пропускает уже сданные карты.
Сданные карты могут быть и до первой несданной.
jimmyknife
0 / 0 / 0
Регистрация: 03.03.2013
Сообщений: 19
08.02.2014, 20:37  [ТС]     Сдающий карты. "cards_remaining--" одинаково работает и с "--", и без #3
ну если 2 раза ввести 51, то оно вылетит и с --, так как сама программа не рассчитана на больше карт, чем 52, в след. пункте книги потом этот недостаток убирают, но не в этом дело

то, что оно пропускает карты, я понял, но не понимаю до конца, зачем оно это делает, если Вам не сложно, распишите более подробно, что имеется в виду
Eldies
89 / 80 / 28
Регистрация: 06.02.2014
Сообщений: 119
08.02.2014, 20:52     Сдающий карты. "cards_remaining--" одинаково работает и с "--", и без #4
Цитата Сообщение от jimmyknife Посмотреть сообщение
ну если 2 раза ввести 51, то оно вылетит и с --, так как сама программа не рассчитана на больше карт, чем 52, в след. пункте книги потом этот недостаток убирают, но не в этом дело
C -- функция rand_0toN1 не может вернуть два раза 51, т.к. максимальное значение, которое она возвращает, это cards_remaining - 1.

Цитата Сообщение от jimmyknife Посмотреть сообщение
то, что оно пропускает карты, я понял, но не понимаю до конца, зачем оно это делает, если Вам не сложно, распишите более подробно, что имеется в виду
В массиве card_drawn для карт, которые уже сданы, стоит значение true, для несданных - false.
Изначально массив заполнен значениями false:
false, false, false, false ...
Пусть, к примеру, rand_0toN1 вернуло 1. Массив станет:
false, true, false, false...
Карта 1 не может быть сдана еще раз, следовательно карты надо перенумеровать.
Если, например, rand_0toN1 вернет снова 1, то сдать надо не карту 1, а карту 2.
jimmyknife
0 / 0 / 0
Регистрация: 03.03.2013
Сообщений: 19
09.02.2014, 02:16  [ТС]     Сдающий карты. "cards_remaining--" одинаково работает и с "--", и без #5
Цитата Сообщение от Eldies Посмотреть сообщение
C -- функция rand_0toN1 не может вернуть два раза 51, т.к. максимальное значение, которое она возвращает, это cards_remaining - 1.



В массиве card_drawn для карт, которые уже сданы, стоит значение true, для несданных - false.
Изначально массив заполнен значениями false:
false, false, false, false ...
Пусть, к примеру, rand_0toN1 вернуло 1. Массив станет:
false, true, false, false...
Карта 1 не может быть сдана еще раз, следовательно карты надо перенумеровать.
Если, например, rand_0toN1 вернет снова 1, то сдать надо не карту 1, а карту 2.
это я уже понял, но уже совсем запутался во всем
зачем тогда в функции select_next_available в цикле while(n-- >0) цикл n раз выполнять? Обьясните, если Вам не тяжело, эту функцию(select_next_available)?
Eldies
89 / 80 / 28
Регистрация: 06.02.2014
Сообщений: 119
09.02.2014, 02:51     Сдающий карты. "cards_remaining--" одинаково работает и с "--", и без #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
int select_next_available(int n){
    int i=0;
        while(card_drawn[i])
        i++;
    while(n-- >0){
        i++;
        while(card_drawn[i])
            i++;
    }
    card_drawn[i]=true;
    return i; 
}
Функция возвращает номер карты, которая является n-ной из не сданных.
в 3-4 строках http://www.cyberforum.ru/cgi-bin/latex.cgi?i увеличивается, чтобы пропустить уже сданные карты.
В результате, при, например, http://www.cyberforum.ru/cgi-bin/latex.cgi?n=0 и нескольких уже сданных картах из самого начала массива, сдана будет первая из не сданных карт.
Цикл на строке 5-9 нужен потому, что пропустить надо еще и http://www.cyberforum.ru/cgi-bin/latex.cgi?n не сданных карт, и сдать ту, которая первой после всех этих пропусков попадется.

Пример:
массив {1,1,0,0,0,1,0,1,0,...}
n = 4
Тогда, в строках 3-4 пропускаются первые две карты (0,1),
следующие три карты (2,3,4) уменьшают n на 3,
следующая (5) пропускается в цикле 7-8,
следующая (6) уменьшает n на 1,
следующая (7) пропускается в цикле 7-8,
и, наконец, 8-я карта - та, что должна быть сдана.
jimmyknife
0 / 0 / 0
Регистрация: 03.03.2013
Сообщений: 19
09.02.2014, 22:47  [ТС]     Сдающий карты. "cards_remaining--" одинаково работает и с "--", и без #7
Цитата Сообщение от Eldies Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
int select_next_available(int n){
    int i=0;
        while(card_drawn[i])
        i++;
    while(n-- >0){
        i++;
        while(card_drawn[i])
            i++;
    }
    card_drawn[i]=true;
    return i; 
}
Функция возвращает номер карты, которая является n-ной из не сданных.
в 3-4 строках http://www.cyberforum.ru/cgi-bin/latex.cgi?i увеличивается, чтобы пропустить уже сданные карты.
В результате, при, например, http://www.cyberforum.ru/cgi-bin/latex.cgi?n=0 и нескольких уже сданных картах из самого начала массива, сдана будет первая из не сданных карт.
Цикл на строке 5-9 нужен потому, что пропустить надо еще и http://www.cyberforum.ru/cgi-bin/latex.cgi?n не сданных карт, и сдать ту, которая первой после всех этих пропусков попадется.

Пример:
массив {1,1,0,0,0,1,0,1,0,...}
n = 4
Тогда, в строках 3-4 пропускаются первые две карты (0,1),
следующие три карты (2,3,4) уменьшают n на 3,
следующая (5) пропускается в цикле 7-8,
следующая (6) уменьшает n на 1,
следующая (7) пропускается в цикле 7-8,
и, наконец, 8-я карта - та, что должна быть сдана.
очень большое вам спасибо, понял всё, хотел бы уточнить некие моменты :
C++
1
2
3
4
5
6
7
8
9
10
11
12
int select_next_available(int n){
    int i=0;
        while(card_drawn[i])
        i++;
    while(n-- >0){
        i++;
        while(card_drawn[i])
            i++;
    }
    card_drawn[i]=true;
    return i; 
}
в 3 и 4 строке грубо говоря определяется первая не сданная карта, верно?
и еще с cards_remaining -- : смотрите, если допустим, как Вы написали в предыдущем посте, 2 раза вернёт 51, то оно будет считать за пределами массива, из-за чего выбьет ошибку, верно?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.02.2014, 23:52     Сдающий карты. "cards_remaining--" одинаково работает и с "--", и без
Еще ссылки по теме:

C++ Переменные "емкость", "Галлон", "Бензин"
Патерн "прототип" не работает, выдаёт ошибку "недопустимый вызов нестатической ф-ции", где я в коде ошибка? C++
C++ Почему не работает "system("pause")"?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Eldies
89 / 80 / 28
Регистрация: 06.02.2014
Сообщений: 119
09.02.2014, 23:52     Сдающий карты. "cards_remaining--" одинаково работает и с "--", и без #8
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от jimmyknife Посмотреть сообщение
в 3 и 4 строке грубо говоря определяется первая не сданная карта, верно?
Верно.
Цитата Сообщение от jimmyknife Посмотреть сообщение
и еще с cards_remaining -- : смотрите, если допустим, как Вы написали в предыдущем посте, 2 раза вернёт 51, то оно будет считать за пределами массива, из-за чего выбьет ошибку, верно?
rand_0toN1(cards_remaining) может вернуть два раза 51, из-за чего будет считать за пределами массива, из-за чего вернет ошибку.
rand_0toN1(cards_remaining--) не может вернуть два раза 51, т.к. cards_remaining уменьшается при каждом вызове.
Yandex
Объявления
09.02.2014, 23:52     Сдающий карты. "cards_remaining--" одинаково работает и с "--", и без
Ответ Создать тему
Опции темы

Текущее время: 09:17. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru