Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
jimmyknife
0 / 0 / 0
Регистрация: 03.03.2013
Сообщений: 19
#1

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

08.02.2014, 19:48. Просмотров 472. Ответов 7
Метки нет (Все метки)

Всем привет, возник вопрос по поводу программы "сдающий карты", программа с книги "С++ без страха", автора не помню, не столь важно)
Вот код программы
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)
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.02.2014, 19:48
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Сдающий карты. "cards_remaining--" одинаково работает и с "--", и без (C++):

В зависимости от времени года "весна", "лето", "осень", "зима" определить погоду "тепло", "жарко", "холодно", "очень холодно" - C++
В зависимости от времени года &quot;весна&quot;, &quot;лето&quot;, &quot;осень&quot;, &quot;зима&quot; определить погоду &quot;тепло&quot;, &quot;жарко&quot;, &quot;холодно&quot;, &quot;очень холодно&quot;. Я так...

Реализовать классы "Воин", "Пехотинец", "Винтовка", "Матрос", "Кортик" (наследование) - C++
Разработать программу с использованием наследования классов, реализующую классы: − воин; − пехотинец(винтовка); − матрос(кортик). ...

Заданный словарь слов. Найти в нем слова-палиндромы, то есть такие, которые одинаково читаются слева направо и наоборот, например, "АННА", "ШАЛАШ" - C++
Заданный словарь слов. Найти в нем слова-палиндромы, то есть такие, которые одинаково читаются слева направо и наоборот, например, &quot;АННА&quot;,...

Создать класс "Книга" с полями "название книги", "количество страниц", "год издания" - C++
Создать класс Книга поля: название книги,количество страниц,год издания методы: вычислить сколько лет книге и количество дней прошедших...

Создать класс "Вентилятор" содержащий в себе классы: "Двигатель", "Контроллер", "Пульт управления" - C++
Помогите с кодом написания задачи, не понимаю как написать классы в классе. Нужно создать класс &quot;вентилятор&quot; содержащий в себе классы:...

Создать абстрактный класс "Издание" и производные классы "Книга", "Статья", "Электронный ресурс" - C++
1. Создать абстрактный класс Издание с методами, позволяющими вывести на экран информацию об издании, а также определить является ли данное...

7
Eldies
90 / 82 / 28
Регистрация: 06.02.2014
Сообщений: 122
08.02.2014, 20:16 #2
1) после того, как несколько карт уже сдано, следующий выбор делается из меньшего количества карт.
если убрать --, а потом rand_0toN1 выдаст, например, два раза 51, оно вылетит.

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

то, что оно пропускает карты, я понял, но не понимаю до конца, зачем оно это делает, если Вам не сложно, распишите более подробно, что имеется в виду
0
Eldies
90 / 82 / 28
Регистрация: 06.02.2014
Сообщений: 122
08.02.2014, 20:52 #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.
0
jimmyknife
0 / 0 / 0
Регистрация: 03.03.2013
Сообщений: 19
09.02.2014, 02:16  [ТС] #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)?
0
Eldies
90 / 82 / 28
Регистрация: 06.02.2014
Сообщений: 122
09.02.2014, 02:51 #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-я карта - та, что должна быть сдана.
1
jimmyknife
0 / 0 / 0
Регистрация: 03.03.2013
Сообщений: 19
09.02.2014, 22:47  [ТС] #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, то оно будет считать за пределами массива, из-за чего выбьет ошибку, верно?
0
Eldies
90 / 82 / 28
Регистрация: 06.02.2014
Сообщений: 122
09.02.2014, 23:52 #8
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от jimmyknife Посмотреть сообщение
в 3 и 4 строке грубо говоря определяется первая не сданная карта, верно?
Верно.
Цитата Сообщение от jimmyknife Посмотреть сообщение
и еще с cards_remaining -- : смотрите, если допустим, как Вы написали в предыдущем посте, 2 раза вернёт 51, то оно будет считать за пределами массива, из-за чего выбьет ошибку, верно?
rand_0toN1(cards_remaining) может вернуть два раза 51, из-за чего будет считать за пределами массива, из-за чего вернет ошибку.
rand_0toN1(cards_remaining--) не может вернуть два раза 51, т.к. cards_remaining уменьшается при каждом вызове.
1
09.02.2014, 23:52
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.02.2014, 23:52
Привет! Вот еще темы с ответами:

Определить тип данных "Запись", имеющий поля "Фамилия", "Пол", "Зарплата" - C++
определить тип данных запись имеющий поля фамилия пол зарплата. определить массив из 10 записей. в программе ввести в массив данные и...

по строкам.замените в слове сочетание "му" на "а" , а букву "ы" на "ца". очень нужно - C++
замените в слове сочетание &quot;му&quot; на &quot;а&quot; , а букву &quot;ы&quot; на &quot;ца&quot;. очень нужно Добавлено через 21 час 4 минуты неужели никто не знает...

Создать иерархию классов "Фирма", "Бухгалтер", "Сотрудник", "Зарплата" - C++
Само по себе понятие &quot;зарплата&quot; не особенно конкретное: оно включает и почасовую, и ставочную зарплату, и комиссионные, и процент с продаж....

Реализовать структуру "Анкета" с полями "Фамилия", "Пол" и "Адрес" - C++
Здравствуйте. Проходим тему Структуры, не могу понять, как определить количество, само задание: #include &lt;iostream&gt; #include...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru