#c #fibonacci
#c #фибоначчи
Вопрос:
Поэтому я попытался создать программу, использующую цикл while, который просит пользователя ввести число, и это число будет использоваться для генерации последовательности Фибоначчи до этого числа. Это означает, что если пользователь вводит число 10, то на выходе должны быть числа Фибоначчи до максимального числа, которое пользователь вводит, например 0,1,1,2,3,5,8.
#include<iostream>
int main(){
int F0(0), F1(1), Fnext;
int num;
std::cout << "Enter a number:n";
std::cin >> num;
std::cout << F0 << " " << F1;
while(Fnext <= num){
Fnext = F1 F0;
F0 = F1;
F1 = Fnext;
}
std::cout << Fnext;
}
Извините, если мое форматирование странное, первый пользователь здесь, на этом сайте. Я попытался скопировать свой код, но это не сработало, поэтому приведенный выше код набран вручную.
ОБНОВЛЕНИЕ: я обновил свой код, и результат настолько близок к правильному.
#include<iostream>
int main(){
int F0(0), F1(1), Fnext(0);
int num;
std::cout << "enter a number to generate the fibonacci sequence up to that number:n"
std::cin >> num;
std::cout << F0 << " " << F1;
while(Fnext < num){
Fnext = F1 F0;
F0 = F1;
F1 = Fnext;
std::cout << " " << Fnext;
}
}
Комментарии:
1. Добро пожаловать в Stack Overflow! Похоже, вам может понадобиться научиться использовать отладчик для пошагового выполнения вашего кода. С хорошим отладчиком вы можете выполнить свою программу построчно и посмотреть, где она отклоняется от того, что вы ожидаете. Это важный инструмент, если вы собираетесь заниматься каким-либо программированием. Дальнейшее чтение: Как отлаживать небольшие программы и руководство по отладке
2. поместите свой
std::cout << Fnext;
right afterFnext = F1 F0;
в свой цикл while и посмотрите, что вы получите4. @NathanOliver «IDE», которую я использую, это repl.it и я не верю, что у него есть какие-либо средства отладки. Я подумываю о переходе на реальную среду разработки, чтобы я мог воспользоваться преимуществами функций отладки.
5. @m88 Я вижу, что он выполняется на вашем конце, за исключением того, что он включает 13 … может быть, его repl.it в чем его вина? Я проверю другую среду разработки.
Ответ №1:
- Вы не инициализировали / не определили
Fnext
, поэтому не похоже, что ваш код попадет в ваш цикл while, и он не будет отображаться. - Ваши
cout
операторы не находятся внутри вашего цикла, поэтому у вас не будет доступа к значению (конкретноFnext
), которое вы хотите отобразить. Если вы хотите отобразить содержимое поFnext
мере его «увеличения», оно должно быть внутри цикла while.
#include<iostream>
int main(){
int F0(0), F1(1), Fnext(0);
int num;
std::cout << "Enter a number:n";
std::cin >> num;
std::cout << F0 << " " << F1;
while(Fnext <= num){
Fnext = F1 F0;
F0 = F1;
F1 = Fnext;
std::cout << Fnext << " ";
}
}
Комментарии:
1. Спасибо! Я понял это немного поздно и соответствующим образом изменил свой код. Единственная проблема, с которой я столкнулся сейчас, заключается в том, что он выводит число после ввода пользователем. Вы можете увидеть, что я имею в виду в моем обновленном вопросе выше с кодом, очень похожим на ваш!
2. Это звучит как хороший вопрос для размышления за обедом. В какой момент контролируется вывод этого конечного числа? После этого … какой символ предотвратит отображение этого последнего числа? Подсказка: оба ответа находятся где-то в вашем цикле while.
3. в моем состоянии while я сделал while(Fnext <= num amp;amp; (F1 F0) <= num), я считаю, что это более приятное решение проблемы, чем использование оператора if и break; .
Ответ №2:
Во-первых, вы также должны инициализировать Fnext
переменную и попытаться добавить немного пробела или новых строк при отображении выходных данных (т.Е. cout
). Во-вторых, вам нужно разорвать while
цикл, если сумма чисел превышает ввод от пользователя (если я правильно понял ваш вопрос).
#include<iostream>
int main(){
int F0(0), F1(1), Fnext(0);
int num;
std::cout << "Enter a number:n";
std::cin >> num;
std::cout << "Initial Num: " << F0 << ", " << F1 << ", " << Fnext << ", " << num << std::endl;
while(Fnext < num){
if (F1 F0 >= num)
break;
else{
Fnext = F1 F0;
F0 = F1;
F1 = Fnext;
}
}
std::cout << "FINAL: " << Fnext << std::endl;
return 0;
}
Комментарии:
1. Ах, я вижу, что добавление оператора if-else внутри цикла помогло бы в случае, когда сумма чисел превышает число, введенное пользователем! Спасибо, я попробую сейчас.
Ответ №3:
Все ответы уже даны. Семантическая проблема была решена.
Для заинтересованных продвинутых программистов на C я покажу дополнительное решение
- использование предварительно вычисленных чисел Фибоначчи во время компиляции
- и нет цикла во время выполнения
Я сначала покажу код, а затем объясню его позже:
#include <iostream>
#include <utility>
#include <array>
#include <algorithm>
#include <iterator>
// All done during compile time -------------------------------------------------------------------
constexpr unsigned long long getFibonacciNumber(size_t index) noexcept {
unsigned long long f1{ 0ull }, f2{ 1ull }, f3{};
while (index--) { f3 = f2 f1; f1 = f2; f2 = f3; }
return f2;
}
// Some helper to create a constexpr std::array initilized by a generator function
template <typename Generator, size_t ... Indices>
constexpr auto generateArrayHelper(Generator generator, std::index_sequence<Indices...>) {
return std::array<decltype(std::declval<Generator>()(size_t{})), sizeof...(Indices) > { generator(Indices)... };
}
template <size_t Size, typename Generator>
constexpr auto generateArray(Generator generator) {
return generateArrayHelper(generator, std::make_index_sequence<Size>());
}
constexpr size_t MaxIndexFor64BitFibonacci = 93;
// This is the definition of a std::array<unsigned long long, 93> with all Fibonacci numbers in it
constexpr auto Fib = generateArray<MaxIndexFor64BitFibonacci>(getFibonacciNumber);
// End of: All done during compile time -----------------------------------------------------------
// The only code executed during runtime
int main() {
// Give instruction to user:
std::cout << "nEnter a number to generate the fibonacci sequence up to that number:n";
// Get border value from user
if (unsigned long long border{}; std::cin >> border)
// Show all Fibonacci numbers up to border value
std::copy(Fib.begin(), std::upper_bound(Fib.begin(), Fib.end(), border), std::ostream_iterator<unsigned long long>(std::cout, " "));
}
Одним из важных свойств ряда Фибоначчи является то, что значения растут сильно экспоненциально. Итак, все существующие встроенные целочисленные типы данных будут переполняться довольно быстро.
С помощью формулы Бине вы можете вычислить, что 93-е число Фибоначчи является последним, которое поместится в 64-битное значение без знака.
Вычисление для 93 значений может быть легко выполнено во время компиляции.
Мы будем использовать общий подход с функцией «генератор» и использовать эту функцию генератора для заполнения времени компиляции constexpr std::array
.
В принципе, мы можем использовать все алгоритмы чисел Фибоначчи для нашей функции генератора. Итак, давайте используем функциональность по умолчанию и используем следующую функцию constexpr:
constexpr unsigned long long getFibonacciNumber(size_t index) noexcept {
unsigned long long f1{ 0ull }, f2{ 1ull }, f3{};
while (index--) { f3 = f2 f1; f1 = f2; f2 = f3; }
return f2;
}
Чтобы constexpr std::array
заполнить число числами Фибоначчи, мы используем шаблонную функцию с переменным параметром pac. Аргументами шаблона являются функция «генератор» и a std::index_sequence
, которые дадут нам значение 0,1,2,3….
// Some helper to create a constexpr std::array initilized by a generator function
template <typename Generator, size_t ... Indices>
constexpr auto generateArrayHelper(Generator generator, std::index_sequence<Indices...>) {
return std::array<decltype(std::declval<Generator>()(size_t{})), sizeof...(Indices) > { generator(Indices)... };
}
Это вызовет нашу generator
функцию со всеми индексами и сохранит результат std::array
в этой позиции индекса.
Тип данных в std::array
будет выведен из возвращаемого типа функции генератора. Так что это довольно гибкий подход.
С помощью дополнительной шаблонной constexpr
функции мы определяем максимальный индекс в качестве аргумента. В нашем случае это будет 93.
template <size_t Size, typename Generator>
constexpr auto generateArray(Generator generator) {
return generateArrayHelper(generator, std::make_index_sequence<Size>());
}
И теперь, наконец, мы создадим наше constexpr std::array<unsigned long long, 93>
приложение, содержащее все числа Фибоначчи, соответствующие 64-битному значению.
constexpr auto Fib = generateArray<MaxIndexFor64BitFibonacci>(getFibonacciNumber);
При этом мы можем легко получить i-е число Фибоначчи с помощью простого механизма поиска. И мы можем использовать алгоритмы из стандартной библиотеки C для работы с этими числами.
Это мы можем видеть в функции main
, в которую мы используем std::copy
и std::upperbound
для копирования запрошенных чисел Фибоначчи std::cout
, без использования какого-либо цикла.
Такой подход обычно дает очень компактные и очень быстрые решения.
Описанный выше механизм генератора является очень гибким и может также использоваться для вычисления других последовательностей. Просто замените функцию генератора.
Все вышесказанное справедливо для C 17
Разработан и протестирован с помощью Microsoft Visual Studio Community 2019, версия 16.8.2
Дополнительно протестировано с gcc 10.2 и clang 11.0.1 и флагами «-Wall -Wextra -Wpedantic»