Хобрук: Ваш путь к мастерству в программировании

Попытка проекта Euler Three

Я хочу начать с того, что я еще не очень хорошо разбираюсь в программировании и, возможно, есть лучший способ делать то, что я хочу. Если вас раздражает взгляд на такие откровенно плохие вещи, продолжайте.

Я пытался ответить на третий вопрос Project Euler: «Найдите наибольший простой делитель числа 600851475143». Сначала я сделал что-то, что вычисляет множители числа. (Извините за названия, я ничего не мог придумать.)

#include <iostream>

using namespace std;

void Factor (double dFactorer)
{
    long dUpperlimit;
    dUpperlimit = (int)dFactorer/2;
    float fnumTouse;
    fnumTouse = 1;
    int nCounter;
    nCounter = 0;
    while (fnumTouse <= dUpperlimit)
    {
        if ((long)dFactorer % (long)fnumTouse == 0)
        {
            cout << fnumTouse << endl;
            fnumTouse++;
            nCounter++;
        }
        else
        {
            fnumTouse++;
        }
    }
    cout << dFactorer << endl;
    cout << "There are " << nCounter + 1 << " factors in this number";
}

int main()
{
    double dNumtofac;
    cout << "Enter a number to factor: ";
    cin >> dNumtofac;
    cout << endl;
    Factor (dNumtofac);
    return 0;
}

Итак, я знаю, что это действительно дрянная работа, и со всеми кастингами, которые мне пришлось сделать, чтобы некоторые вещи работали. Он работает с меньшими числами, но что-то около 100 миллионов заставляет его выводить только определенное количество факторов, прежде чем полностью остановиться. Я попробовал номер задачи, и его вывод был самим числом, говорящим, что в этом 600851475143 есть только один фактор. Я хотел бы знать, почему он говорит это, это как-то связано с ограничениями переменных, которые я использовал ? Что-то другое? У меня недостаточно знаний, чтобы разобраться в этом.

24.10.2013

  • Не уверен, почему за это проголосовали, но я думаю, что этот вопрос может лучше подойти для, возможно, codereview.stackexchange.com 24.10.2013
  • @EdChum Я так не думаю. У него есть специфическая проблема: он не дает правильного ответа. 24.10.2013
  • Максимальное значение для переменной int составляет 2147483647 на 32-разрядной платформе, поэтому не ожидайте, что ваш код будет обрабатывать большие числа. 24.10.2013
  • @PatNak Вы используете слишком много типов чисел (я вижу все int, float, long, double). Вам нужен только один тип, и это должен быть целочисленный тип. Кроме того, введенный номер не будет соответствовать 32-битному типу. Подозреваю, что это намеренно. (На большинстве платформ int является 32-битным. Поэкспериментируйте с sizeof, который возвращает размер в байтах. Попробуйте long.) 24.10.2013
  • Кроме того, пораньше избавьтесь от вредных привычек, прочитав это и это. 24.10.2013
  • @BoBTFish Хорошо, я постараюсь привести все к long и проверить размеры. Спасибо! 24.10.2013
  • @BoBTFish Я только что проверил размеры для моих int и long, они оба 4 байта, поэтому изменение int на long что-нибудь даст? Я посмотрел на график и увидел, что мне потребуется по крайней мере 8-байтовая переменная, чтобы соответствовать номеру задачи (для меня это double). Единственное, что с этим связано, это то, что я почти уверен, что по модулю нельзя использовать с double. 24.10.2013
  • Вам также необходимо тщательно продумать, что пытается сделать ваша функция. Вы хотите, чтобы он печатал все факторы? или все основные факторы. Ваш текущий код не делает ни того, ни другого; если вы остановитесь на полпути, вы не сможете получить все множители и можете получить не простые множители. Я предлагаю начать с 2 подсчета. Когда вы найдете фактор, разделите его и продолжайте. Убедитесь, что вы получили любой фактор, который может появляться несколько раз (20=2*2*5). Это даст вам простые числа. Вы можете установить верхний предел на квадратный корень из входных данных, и если вы нажмете его до того, как ваши входные данные будут уменьшены до 1, входные данные будут простыми. 24.10.2013
  • @PatNak А, хорошо. Вам нужен 64-битный целочисленный тип. Лучше всего #include <cstdint> использовать std::int64_t. Вы включаете C++11? Если это так, это должно работать. Если нет, попробуйте <stdint.h> и просто int64_t. 24.10.2013
  • @BoBTFish Спасибо за всю помощь (комментарии и эти две статьи). Я пересмотрю и учту то, что вы сказали. 24.10.2013
  • @PatNak Нет проблем. Я пытаюсь помочь вам разобраться, а не просто дать вам кусок рабочего кода (который мне пришлось бы переписывать с нуля, так как мои PE-решения дома). 24.10.2013
  • @BoBTFish Да, этот метод помогает больше, чем просто дать мне правильный код, я узнаю больше, и я ценю это. Я попробую еще раз утром, когда высплюсь, и посмотрю, как все пойдет. 24.10.2013
  • @BoBTFish Еще раз спасибо за всю помощь, которую вы оказали, у меня все заработало правильно, приняв во внимание то, что вы сказали. Я не делал этого в течение очень долгого времени, и я действительно ценю помощь, как это. 25.10.2013
  • На самом деле я только что понял, что моя рекомендация была чушью. Если вы уменьшите целевое число и увеличите его до исходного квадратного корня, вы можете пропустить один (самый большой) простой множитель. 25.10.2013

Ответы:


1
#include <iostream>

using namespace std;

int main()
{
long long n=0;
//to do: verify that the number is positive and below the limit of long long
cout <<"The number to factor : ";
cin  >>n;
long long aux = n%2==0 ? 2 : 1;
for (long long i=3;i<=n/2;i+=2)
    if(n%i==0)
         aux = aux>n/i ? aux : n/i;
cout<<"Greatest factor = "<<aux;
return 0;
}

Конечно, вы можете значительно улучшить это, заставив for двигаться от максимума к минимуму и останавливаться при первом появлении фактора. Не забудьте проверить, является ли n/2 четным или нечетным. (Код не проверял).

20.11.2013
Новые материалы

Краткое руководство для начинающих по простому сквозному тестированию с помощью Cypress
Автоматизированное тестирование, требующее только базовых навыков JavaScript. Цель этой статьи - показать, как с минимальными усилиями вы можете добавить полезные сквозные (E2E) тесты в свой..

Руководство по быстрой разработке рекомендательной системы промышленного уровня
В этой статье я намерен предоставить краткий обзор методов, которые можно использовать для разработки хорошо работающей рекомендательной системы. Я начал работать над Recommender Systems около 6..

Arshaw FullCalendar для AngularJS — проблемы, с которыми столкнулись, и найденные решения для их устранения
Arshaw FullCalendar — это полноразмерный календарь событий с возможностью перетаскивания, использующий jQuery. Подробнее об этом можно узнать здесь . Директива ui-calendar — это полная..

Простое руководство по Redux для разработчиков React
Понимание строительных блоков Redux Redux — это инструмент управления состоянием, который чаще всего используется с React или React Native. Когда я впервые начал использовать его год назад,..

присоединение к атрисмаркетингу
присоединение к атрисмаркетингу И много дополнительных привилегий. маркетинг — реклама-хорошие отзывы клиентов-доверие-счастье-лояльность и опытные сотрудники устойчивые лесозаготовительные..

КОВАРИАНТНОСТЬ И КОРРЕЛЯЦИЯ
ВВЕДЕНИЕ В этом посте мы обсудим ковариацию и корреляцию. Это играет важную роль при выборе функций. Статистические корреляции говорят нам как о силе связи между двумя переменными, так..

Использование матриц Вигнера в случаях машинного обучения, часть 8
Равномерный локальный закон для матриц Вигнера (arXiv) Автор: Джорджо Чиполлони , Ласло Эрдеш , Доминик Шредер . Аннотация: Мы доказываем общий локальный закон для матриц Вигнера, который..