Традиционный оператор for

Задания раздела 5.4.2
5.15. Объясните каждый из следующих циклов. Исправьте все обнаруженные ошибки.
(a) for (int ix=0; ix!=sz; ++ix) {/* ... */}
if (ix!=sz)
//...
(b) int ix;
for (ix!=sz;++ix) {/* ... */}
(c) for (int ix=0; ix!=sz;++ix, ++ sz) {/* ... */}
5.16. Цикл while особенно хорош, когда необходимо выполнить некое условие; например, когда нужно читать значения до конца файла. Цикл for считают циклом пошагового выполнения: индекс проходит диапазон значений в коллекции. Напишите идиоматическое использование каждого цикла, а затем перепишите каждый случай использования в другой конструкции цикла. Если бы вы могли использовать только один цикл, то какой бы вы выбрали и почему?
5.17. Предположим, есть два вектора целых чисел. Напишите программу, определяющую, не является ли один вектор префиксом другого. Для векторов неравной длины сравнивайте количество элементов меньшего вектора. Например, если векторы содержат значения 0, 1, 1, 2 и 0, 1, 1, 2, 3, 5, 8 соответственно, ваша программа должна возвратить true.

5.4.2

Все уже про цикл for было сказано раньше. Осталось добавить. что в заголовке (то что в скобках) инициализирующий-оператор может определить больше одного объекта. Поэтому у всех переменных должен быть одинаковый базовый тип.
Так же части заголовка можно пропускать. и даже иногда нужно.

5.15. Объясните каждый из следующих циклов. Исправьте все обнаруженные ошибки.
(a) for (int ix=0; ix!=sz; ++ix) {/* ... */}
if (ix!=sz)
//...

Переменная ix видна только в цикле for, так что нужно просто переставить фигурные скобки или вынести инициализацию переменной до цикла, чтобы не нарушать течение программы.
(a1) 
for (int ix=0; ix!=sz; ++ix) {/* ... */
if (ix!=sz)
//...
}
(a2)
std::vector<int> v;
int ix=0, sz=v.size();
for ( ; ix!=sz; ++ix) {/* ... */}
if (ix!=sz)
//...

(b) int ix;
for (ix!=sz;++ix) {/* ... */}

Если инициализирующий-оператор пуст, будь добр отметить это точкой с запятой.
(b) int ix;
for ( ; ix!=sz;++ix) {/* ... */}

(c) for (int ix=0; ix!=sz;++ix, ++ sz) {/* ... */}

Здесь с точки зрения синтаксиса вроде все в порядке, кроме того что цикл будет бесконечный, если одновременно увеличивать и ix и sz.
(c) for (int ix=0; ix!=sz;++ix) {/* ... */}
Убрал ++sz и  теперь ix точно станет равна sz когда-нибудь.

5.16. Цикл while особенно хорош, когда необходимо выполнить некое условие; например, когда нужно читать значения до конца файла. Цикл for считают циклом пошагового выполнения: индекс проходит диапазон значений в коллекции. Напишите идиоматическое использование каждого цикла, а затем перепишите каждый случай использования в другой конструкции цикла. Если бы вы могли использовать только один цикл, то какой бы вы выбрали и почему?

Я понимаю что такое идиоматическое, но не понимаю как это все связано с циклом. Как писать то, чего я не понимаю? Обычно, попавшиеся на незнании студентишки, начинают юлить.
Что такое идиоматическое выражение? "black mail", "white lie" - это если на инглише. По-русски, например, "Взять себя в руки", или показать где раки зимуют. Где вообще зимуют циклы?

Если заставить цикл for быть чем-то другим. Например, если надо достичь конца файла, то управляющая переменная в инициализирующем-операторе не нужна:
for (; ix!=v.end() ; ), это то же самое что и while (ix!=v.end)
Как реализовать функционал цикла for в цикле while?
int i=0; std::vector<int> v;
while(i<10) {v.push_back(i); ++i;}
Что еще студентику можно промямлить. Ну вот, например, бесконечный цикл.
for ( ; ; )
while (true)
Чем не идиоматическое использование цикла?
Мне лично цикл for ближе. Почему? Его функционал мне кажется более широким. Как я могу об этом судить, написав половину хеловорлда?

5.17. Предположим, есть два вектора целых чисел. Напишите программу, определяющую, не является ли один вектор префиксом другого. Для векторов неравной длины сравнивайте количество элементов меньшего вектора. Например, если векторы содержат значения 0, 1, 1, 2 и 0, 1, 1, 2, 3, 5, 8 соответственно, ваша программа должна возвратить true.

Вот читаешь такие задания и чувствуешь, что над тобой издеваются. Есть два вектора целых чисел. Допустим, они одинаковые по размеру. Как может быть один вектор префиксом другого? только если они абсолютно одинаковые. Можно было написать, мол, сравните, одинаковы ли два вектора или нет. А если разная длина у векторов, то сравнивайте количество элементов меньшего вектора.

#include <iostream>
#include <string>
#include <vector>
int main()
{
std::vector<int> v, v1;
std::cout << "v: ";
for (int i=0; i<10; ++i)
{v.push_back(i); std::cout << v[i] << " ";}
std::cout << std::endl;
std::cout << "v1: ";
for (int i=0; i<10; ++i)
{v1.push_back(i); std::cout << v1[i] << " ";}
std::cout << std::endl;
auto it=v.begin();
auto it1=v1.begin();
if (v==v1 || v < v1)
{while (it!=v.end())
if (*it==*it1) {++it;++it1;
}
else {std::cout << "Not a prefix"; return(-1);
}
if (v==v1)std::cout << "v equal to v1" << std::endl;
else {std::cout << "v is a prefix to v1" << std::endl; return(true);}
}
else {while (it1!=v1.end())
if (*it==*it1) {++it;++it1;
}
else {std::cout << "Not a prefix"; return(-1);
}
{std::cout << "v1 is a prefix to v" << std::endl; return(true);}
}
return(0);
}

Программа простейшая, её даже комментировать нет смысла. Лапша из условий и циклов. Есть два условия, на которых строится ветвление, а внутри просто перебор значений до конца наименьшего вектора в цикле и сравнение соответствующих значений элементов.
Ах да, что значит возвратить true я понимаю, не понимаю только зачем.
Когда писал эту программу, я забыл что векторы можно сравнивать просто так, без доступа к элементам. В случае равенства векторов можно было бы исключить перебор элементов, но уже как написал так пусть и будет.

Я еще немного доделал программу, добавил условие для вывода и использовал условие задания:
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::vector<int> v={0,1,1,2};
std::vector<int> v1={0,1,1,2,3,5,8};
auto it=v.begin();
auto it1=v1.begin();
if (v==v1 || v < v1) {while (it!=v.end())
if (*it==*it1) {++it;++it1;}
else {std::cout << "Not a prefix"; return(-1);}
if (v==v1) {std::cout << "v equal to v1" << std::endl; return(true);}
else if (it==v.end())
{std::cout << "v is a prefix to v1" << std::endl; return(true);}}
else {while (it1!=v1.end())
if (*it==*it1) {++it;++it1;}
else {std::cout << "Not a prefix"; return(-1);}
if (it1==v1.end())
{std::cout << "v1 is a prefix to v" << std::endl; return(true);}}
return(0);
}
Понял, что вынос фигурных скобок в новую строку мне очень мешает. Скорее всего сказывается построчное чтение всю свою сознательную жизнь.  Я быстрее понимаю какая скобка к какой относится если все записано в одну строку. Надо переучиваться.

Добавить комментарий