Пожалуйста, помогите: & quot; если & quot; заявление в переполнении стека

Следующий код печатает один и тот же результат — дважды (!) (С использованием Microsoft Visual C ++ 2010 IDE). Я также напечатал окончательные значения каждой переменной, чтобы увидеть, что происходит, и в действительности есть два набора значений, которые удовлетворяют if условие выписки.

Мой вопрос так как инструкция была break; если условие оценивается как ИСТИНА, может кто-нибудь любезно объяснить, как / почему я получаю оба результата, когда я не просил об этом (не то, что это плохо, просто пытаюсь понять)? Является ли эта часть if построить или это как-то связано с циклами? Кажется, что что-то знает, что нужно возвращать несколько решений, если условие оценивается как ИСТИНА более одного раза, я просто не понимаю, как оно может это сделать, когда в инструкциях явно не говорится, что это нужно (если только что-то не создано. в этом я не знаю).

По сути, почему цикл не заканчивается на break; как только условие выполнено или я думаю об этом неправильно?

Опять же, если кто-то знает или я что-то здесь упускаю, пожалуйста, дайте мне знать! Я новичок в C ++, поэтому просто пытаюсь учиться, заранее спасибо.

Вот код:

#include "stdafx.h"#include <iostream>

int main()
{
for (int a = 1; a < 500; ++a)
{
for (int b = 1; b < 500; ++b)
{
for (int c = 1; c < 500; ++c)
{
if ((a + b + c) == 1000 && ((a*a + b*b) == (c*c)))
{
cout << "The product abc = " << a*b*c << endl << "a = " << a << ", b = " << b << ", c = " << c << endl;
break;
}
}
}
}
cout << endl << "Loop terminated";

char d;
cin >> d;
return 0;
}

Вывод консоли следующий:

Продукт abc = 31875000

а = 200, б = 375, с = 425

Продукт abc = 31875000

а = 375, б = 200, с = 425

Цикл прекращен

3

Решение

Ваш break только вырывается из внутренний цикл, поэтому внешний цикл продолжает выполняться.

Одна из возможностей — переместить этот код в отдельную функцию и вернуться из функции, когда вы найдете совпадение в первый раз. Тогда (если вы не вызовете функцию снова) выполнение этого кода полностью прекратится.

Я бы также исключил петлю c полностью. Единственное значимое значение для c является 1000 - (a+b)так что вы могли бы просто вычислить его напрямую, вместо того, чтобы просмотреть 500 различных значений, чтобы найти его.

5

Другие решения

Итак — вы слышали это break; это не решение — но что есть?

Если вы сделаете свой предел (в настоящее время 500) для каждого цикла переменной, скажем

int myLim = 500;

И заменить каждый из for условия цикла с

for (int a = 1; a < myLim; ++a)
{
for (int b = 1; b < myLim; ++b)
{
for (int c = 1; c < myLim; ++c)
{

Тогда вместо break ты говоришь myLim = -1 — и ты вырвешься из всех петель.

Обратите внимание — некоторые компиляторы будут недовольны вашей настройкой a=500 а также b=500 когда if условие выполнено, так как вы модифицируете переменную цикла; но никто не будет возражать, если вы измените условие. Это немного чище, чем добавить флаг, но все же немного взломать.

0

В вашем коде вы применили только один разрыв. Таким образом, внутренний цикл for будет прерван, а другой внешний цикл продолжится.

Таким образом, вы должны определить переменную флага, чтобы разорвать все циклы.

#include "stdafx.h"#include <iostream>
int main()
{
bool flag = 0; //Set the flag
for (int a = 1; a < 500 && !flag; ++a) //Check flag condition
{
for (int b = 1; b < 500  && !flag; ++b) //Check flag condition
{
for (int c = 1; c < 500 && !flag; ++c) //Check flag condition
{
if ((a + b + c) == 1000 && ((a*a + b*b) == (c*c)))
{
cout << "The product abc = " << a*b*c << endl << "a = " << a << ", b = " << b << ", c = " << c << endl;
flag= 1; //Set the flag true
break;
}
}
}
}
cout << endl << "Loop terminated";

char d;
cin >> d;
return 0;
}
0

break оператор разрывает только самый внутренний цикл, и вам может понадобиться использовать флаг для выхода из других циклов в случае разрыва

#include "stdafx.h"#include <iostream>

int main()
{
bool flag = false;
for (int a = 1; a < 500; ++a)
{
for (int b = 1; b < 500; ++b)
{

for (int c = 1; c < 500; ++c)
{
if ((a + b + c) == 1000 && ((a*a + b*b) == (c*c)))
{
cout << "The product abc = " << a*b*c << endl << "a = " << a << ", b = " << b << ", c = " << c << endl;
flag = true;
break;
}
}

if(flag)
{ break; }
}

if(flag)
{ break; }
}
cout << endl << "Loop terminated";

char d;
cin >> d;
return 0;

}

0

break ты использовал просто ломает самое внутреннее for цикл не все петли.

Используйте флаг и and это к for условия:

bool found = false;
for (int a = 1; a < 500 && !found; ++a)
{
for (int b = 1; b < 500 && !found; ++b)
{
for (int c = 1; c < 500 && !found; ++c)
{
if ((a + b + c) == 1000 && ((a*a + b*b) == (c*c)))
{
cout << "The product abc = " << ....
found = true;
}
}
}
}

или даже вы можете использовать goto вежливо !

for (int a = 1; a < 500; ++a)
{
for (int b = 1; b < 500; ++b)
{
for (int c = 1; c < 500; ++c)
{
if ((a + b + c) == 1000 && ((a*a + b*b) == (c*c)))
{
cout << "The product abc = " << ...
goto break_all;
}
}
}
}
break_all:

«Это последний оставшийся оплот для использования goto»

0

Как уже говорили многие люди, break вырывается только из самой внутренней петли.

Некоторые языки позволяют решить эту проблему. Ада определенно имеет способ назвать каждую петлю, и ее ближайший эквивалент, чтобы сломать, exit when <condition>;также может быть написано exit <loopname> when <condition>;, IIRC C # также может иметь специальный синтаксис для этого.

В C ++ ваши варианты …

  1. использование goto скорее, чем break, Поместите метку цели сразу после самой внешней петли.

  2. throw исключение для выхода из цикла, когда все вложенные циклы вложены в try блок.

  3. Не вырваться из цикла вообще. Вместо этого есть флаг, done или аналогичный, чтобы указать, когда вы закончите. Проверьте это в условиях всех петель.

  4. Как Джерри Гроб сказал, используйте переместить петли в отдельную функцию и использовать return (не знаю, как я пропустил это!).

Пуристы, вероятно, предпочтут 3, с опцией 2. В частности, единственная опция, которая не нарушает «принцип единого выхода» из структурированного программирования, это (3), но break также нарушает этот принцип в любом случае. Лично я бы предпочел 1, поскольку он генерирует меньше беспорядка, поэтому (при условии, что функция, в которой вы его используете, мала, и goto визуально очевидно) это более читабельно.

С помощью goto как правило, избегается по уважительной причине. Многие люди полностью их запрещают, что менее оправдано, но эти люди, вероятно, break а также continue быть «скрытым gotos» и запретить их тоже (за исключением break в switch заявления, конечно). Во всяком случае, в результате вы можете даже не знать, что goto возможно.

Там есть описание синтаксиса для goto Вот — в принципе goto <labelname>; а также labelname:,

0

Ваш код будет очень медленным, если вы попытаетесь проверить немного больший диапазон чисел. Вы на самом деле пробуете все значения для c от 1 до 500 и проверяете, является ли a + b + c = 1000. Очевидно, что сумма равна только 1000, если c = 1000 — a — b. Так что вы можете просто написать

int c = 1000 - a - b;
if ((c >= 1 && c < 500) && (a*a + b*b == c*c)) ...

Это будет работать примерно в 500 раз быстрее …

Теперь вам не нравится, что печатается a = 200, b = 375 и a = 375, b = 200. Вы можете подумать об операторе break, но это может привести к ошибке: существует множество случаев, когда есть несколько решений, которые тривиально не связаны, как здесь.

Вам нужно избегать печати решений, где a> b, потому что если (a, b, c) является решением, то (b, a, c) также является решением. Простой способ сделать это — написать

for (int b = a; b < 500; ++b) ...

Когда a = 375, только значения от 375 до 499 проверяются для b, что позволяет избежать печати a = 375, b = 200.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector