Почему ответ распечатывается дважды? - PullRequest
2 голосов
/ 10 мая 2010

Я создал программу, которая возвращает продукт a b c, где a, b, c - тройки Пифагора и складывают до 1000. Программа выводит правильный ответ, но делает это дважды. Мне было любопытно, почему это так. Немного поиграв с ним, я обнаружил, что он печатается, когда a = 200 b = 375 c = 425. И еще раз, когда a = 375 b = 200 c = 425.

bool isPythagTriple(int a, int b, int c);

int main()
{

    for(int a = 1; a < 1000; a++)
    {
        for(int b = 1; b < 1000; b++)
        {
            for(int c = 1; c < 1000; c++)
            {
                if( ((a+b+c)==1000) && isPythagTriple(a,b,c) )
                {
                    cout << a*b*c << " ";
                    break;
                }
            }
        }
    }

    return 0;
}

bool isPythagTriple(int a, int b, int c)
{
    if( (a*a)+(b*b)-(c*c) == 0 )
        return true;
    else
        return false;
}

Ответы [ 5 ]

9 голосов
/ 10 мая 2010

Только для того, чтобы это стоило, я написал бы эту функцию:

bool isPythagTriple(int a, int b, int c)
{
    if( (a*a)+(b*b)-(c*c) == 0 )
        return true;
    else
        return false;
}

Больше похоже на это:

bool isPythagTriple(int a, int b, int c) { 
    return a*a+b*b==c*c;
}
8 голосов
/ 10 мая 2010
В этом случае

break будет разрываться только из цикла c, а не из b и a.

Быстрое решение состоит в том, чтобы гарантировать, что вы не получите повторы, начиная каждую переменную больше или равную предыдущей (так что b никогда не меньше a и c никогда не меньше b) .

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

for (int a = 1; a < 1000; a++) {
    for (int b = a; b < 1000; b++) {
        int c = 1000 - a - b;
        if (c >= b) {
            if (isPythagTriple (a,b,c)) {
                cout << a << " " << b << " " << c << " " << a*b*c << std::endl;
            }
        }
    }
}

Общий эффект этого состоит в том, чтобы уменьшить общее число циклов с миллиарда (короткая шкала) до примерно полумиллиона, следовательно, сократить его примерно на 99,95% - что должно быть чуть-чуть быстрее: -)


И, возможно, ускорение благодаря предложению Джерри Коффина (и встроенному предложению компилятору), полной программе:

#include <iostream>

inline bool isPythagTriple(int a, int b, int c) {
    return a * a + b * b == c * c;
}

int main() {
    for(int a = 1; a < 1000; a++) {
        for(int b = a; b < 1000; b++) {
            int c = 1000 - a - b;
            if (c >= b) {
                if (isPythagTriple(a,b,c)) {
                    std::cout << a << " " << b << " " << c << " "
                        << a*b*c << std::endl;
                }
            }
        }
    }
    return 0;
}

, что занимает в среднем 0,004 секунды (система + пользователь) на моем ящике, а оригинал занимает в среднем около 2,772 секунды (по десять сэмплов каждый). Не то чтобы это действительно имело значение, если, конечно, вы не запускаете его много, много раз.

Вывод этого кода, как и ожидалось:

200 375 425 31875000
2 голосов
/ 10 мая 2010

Так работают break и continue - break выходит только из самого внутреннего цикла. Прочитайте обсуждение по этому вопросу , чтобы найти альтернативы этому.

0 голосов
/ 10 мая 2010

Чтобы избежать многократного заказа решений, убедитесь, что c >= b >= a. Вы можете сделать это, изменив нижние границы:

for(int a = 1; a < 1000; a++) {
        for(int b = a; b < 1000; b++) {
            for(int c = b; c < 1000; c++) {
0 голосов
/ 10 мая 2010

Причина, по которой это происходит, в том, что вы выходите только из внутреннего цикла (для c). Внешние петли продолжают работать и снова входят во внутренний цикл, снова удовлетворяя условиям. Есть множество значений, которые прибавляют к 1000, и вы ловите некоторые из них - вы поймали 2, как показывает ваш отпечаток. Вы можете использовать «return» вместо break, если вы хотите выводить только первую комбинацию значений.

Что касается "блока кода", я не уверен, что вы имеете в виду. Кажется, вы уже знаете, что пишете функции. Если вы имеете в виду блок контекста, то вы просто заключаете код в виде фигурных скобок -> {}

* 1005 Е.Г. *

{ int i = 0; я ++; }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...