воскресенье, мая 6

Научим компьютер читать стихи

Есть такой забавный стишок:
    99 bottles of beer on the wall, 
99 bottles of beer.
Take one down and pass it around,
98 bottles of beer on the wall.

98 bottles of beer on the wall,
98 bottles of beer.
Take one down and pass it around,
97 bottles of beer on the wall.

<...>

1 bottle of beer on the wall,
1 bottle of beer.
Take one down and pass it around,
No more bottles of beer on the wall.

No more bottles of beer on the wall,
No more bottles of beer.
Go to the store and buy some more,
99 bottles of beer on the wall.

Переводиться на русский язык это стихотворение вот так:
    99 бутылок пива на стене, 
99 бутылок пива!
Возьми одну, пусти по кругу,
98 бутылок пива на стене!

98 бутылок пива на стене,
98 бутылок пива!
Возьми одну, пусти по кругу,
97 бутылок пива на стене!

<...>

1 бутылка пива на стене,
1 бутылка пива!
Возьми одну, пусти по кругу,
Никаких бутылок пива на стене.

Никаких бутылок пива на стене!
Никаких бутылок пива!
Пойди в магазин и купи еще,
99 бутылок пива на стене!

Научим компьютер читать такой стишок. Нет ничего проще, вот текст программы.

#include <iostream>
int main()
{
std::cout << " 99 bottles of beer on the wall, \n";
std::cout << " 99 bottles of beer. \n";
std::cout << " Take one down and pass it around, \n";
std::cout << " 98 bottles of beer on the wall. \n\n";

std::cout << " 98 bottles of beer on the wall, \n";
std::cout << " 98 bottles of beer. \n";
std::cout << " Take one down and pass it around, \n";
std::cout << " 97 bottles of beer on the wall. \n\n";

/*---*/

std::cout << " 1 bottle of beer on the wall, \n";
std::cout << " 1 bottle of beer.\n";
std::cout << " Take one down and pass it around, \n";
std::cout << " No more bottles of beer on the wall.\n\n";

std::cout << " No more bottles of beer on the wall, \n";
std::cout << " No more bottles of beer.\n";
std::cout << " Go to the store and buy some more, \n";
std::cout << " 99 bottles of beer on the wall.\n\n";

std::cin.get();

return 0;
}

Я, естественно, не стал приводить полностью текст программы. Программа работает и это самое главное. Но у нее есть небольшой минус: текст программы огромный. Это черевато вот чем. Предположим, мы решим стишок показать детям, и захотим сделать детский вариант, заменив пиво на молоко. Нам придется перелапативать весь текст. Как пели в фильме Айболит 66: «нормальные герои всегда идут в обход». Существует такое понятие как цикл. Мы попросим компьютер повторить стишок 99 раз, изменяя только число.

#include <iostream>
int main()
{
int i = 99;
while (i > 2)
{
std::cout << " "<< i <<" bottles of beer on the wall, \n";
std::cout << " "<< i <<" bottles of beer. \n";
std::cout << " Take one down and pass it around, \n";
std::cout << " "<< i - 1 <<" bottles of beer on the wall. \n\n";

i--;
}

std::cout << " 2 bottles of beer on the wall, \n";
std::cout << " 2 bottles of beer. \n";
std::cout << " Take one down and pass it around, \n";
std::cout << " 1 bottle of beer on the wall. \n\n";

std::cout << " 1 bottle of beer on the wall, \n";
std::cout << " 1 bottle of beer.\n";
std::cout << " Take one down and pass it around, \n";
std::cout << " No more bottles of beer on the wall.\n\n";

std::cout << " No more bottles of beer on the wall, \n";
std::cout << " No more bottles of beer.\n";
std::cout << " Go to the store and buy some more, \n";
std::cout << " 99 bottles of beer on the wall.\n\n";

std::cin.get();

return 0;
}

Цикл формируется с помощью ключевого слова while. В общем виде он выглядит вот так:

while (/*условие*/)
{
/*список действий*/
}

В начале пишется ключевое слово while, потом в скобках условие, при котором цикл должен выполняться, и далее (в фигурных скобках) список действий.

Такой список действий иногда называют «телом цикла».


Компьютер будет выполнять тело цикла до тех пор пока будет истинно условие цикла.

В нашем случае, в случае со стишком, условие такое — i > 2, в фигурных скобках мы выводим текст стишка и после этого уменьшаем значение переменной i на единичку с помощью команды i--. Перед циклом while мы заводим переменную i с типом int и присваиваем этой переменной значение 99.

Тип int это тип целого числа. В переменных такого типа могут храниться целые числа. Например: 0, 1, 2, 100, -20.


Тут можно выделить три основных момента это инициализация (int i = 99), условие при котором тело цикла выполняется (i < 2), и способ изменения состояния цикла (i--). Очень часто программисты забывают какой либо из этих моментов, например, я часто забываю последний момент (i--). Для таких склеротиков как я, придумали цикл for. В общем виде он выглядит вот так:

for (/*инициализация*/; /*условие*/; /*изменение состояния цикла*/)
{
/*список действий */
}

Все основные моменты цикла находятся в одном месте и перечисленны через точку с запятой. Вот текст программы с использованием цикла for:

#include <iostream>
int main()
{
for (int i = 99; i > 2; i--)
{
std::cout << " "<< i <<" bottles of beer on the wall, \n";
std::cout << " "<< i <<" bottles of beer. \n";
std::cout << " Take one down and pass it around, \n";
std::cout << " "<< i - 1 <<" bottles of beer on the wall. \n\n";
}

std::cout << " 2 bottles of beer on the wall, \n";
std::cout << " 2 bottles of beer. \n";
std::cout << " Take one down and pass it around, \n";
std::cout << " 1 bottle of beer on the wall. \n\n";

std::cout << " 1 bottle of beer on the wall, \n";
std::cout << " 1 bottle of beer.\n";
std::cout << " Take one down and pass it around, \n";
std::cout << " No more bottles of beer on the wall.\n\n";

std::cout << " No more bottles of beer on the wall, \n";
std::cout << " No more bottles of beer.\n";
std::cout << " Go to the store and buy some more, \n";
std::cout << " 99 bottles of beer on the wall.\n\n";

std::cin.get();
return 0;
}

Литература: статья на Википедии «99 бутылок пива».