Привет ! Меня зовут Ксавье Жувено, и это пятая часть длинной серии статей The Modern C++ Challenge. В этой статье я собираюсь объяснить, как я решил пятую задачу на C++ и как интегрировал это решение в проект Android.

Цель этой пятой задачи проста. Мы должны вывести все сексуальные пары простых чисел до предела, введенного пользователем. Решение будет вычислено на C++, а интерфейс для получения пользовательского ввода и отображения результата будет обрабатываться с помощью Android Studio Framework.

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

Сексуальные премьер-пары, какие они 🤔

Свойство сексуальной премьер-пары очень простое. Это пара простых чисел, отличающихся друг от друга на 6.

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

Решение на С++

Как я уже сказал, в предыдущей части мы реализовали возможность идентифицировать простые числа, поэтому в этом решении мы собираемся повторно использовать функцию bool isPrime(unsigned int number), реализованную ранее. повторно используйте isPrime из предыдущей задачи.

Для этого мы собираемся извлечь эту функцию из другого файла и связать ее как статическую библиотеку с предыдущей проблемой и нашим текущим решением проблемы в нашем файле CmakeLists.txt.

add_library(primeNumber STATIC primeNumber.hpp)
set_property(TARGET primeNumber PROPERTY LINKER_LANGUAGE CXX)
target_link_libraries(problem4 PRIVATE primeNumber)
target_link_libraries(problem5 PRIVATE primeNumber)

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

#include <cmath>
static const bool isSexyPrimePair(unsigned int firstNumber, unsigned int secondNumber) {
  return (std::abs(static_cast<int>(firstNumber - secondNumber)) == 6) && isPrime(firstNumber) && isPrime(secondNumber);
}

В этой функции мы проверяем, являются ли два числа простыми числами, и, используя std::abs, проверяем, составляет ли разница между ними 6.

Я не сделал эту функцию constexpr, потому что std::abs не constexpr. Мне было интересно, почему, поэтому я задаю вопрос на reddit. надеюсь, к тому времени, когда вы будете это читать, у этого ответа будет ответ, или, если вы его знаете, оставьте комментарий, чтобы все знали, почему 😉

Вы можете заметить, что у меня мог бы быть обходной путь std::abs, чтобы сделать эту функцию constexpr, но я хочу максимально использовать std (просто личное пожелание 😉)

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

std::vector<std::pair<unsigned int, unsigned int>> sexyPrimeSmallerThan (const unsigned int upperLimit) {
  std::vector<std::pair<unsigned int, unsigned int>> results;
  for(unsigned int i = upperLimit; i > 6; --i) {
    auto firstIndex = i; auto secondIndex = static_cast<unsigned int>(i-6);
    if(isSexyPrimePair(i, secondIndex)) {
      results.emplace_back(std::make_pair<unsigned int, unsigned int>(std::move(firstIndex), std::move(secondIndex)));
    }
  }
  return results;
}

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

И вуаля, у нас есть решение на C++, способное дать нам список сексуальных пар простых чисел, которые мы ищем.

Интерфейс пользовательского интерфейса в Android Studio

Пользовательский интерфейс для этой задачи аналогичен интерфейсу предыдущей задачи. Поэтому я не буду вдаваться в подробности, но я призываю вас заглянуть в мой пост об этом в блоге. 😉

Использование собственного кода C++

Чтобы связать пользовательский интерфейс и метод C++, нам нужно преобразовать результат, полученный от функции C++, во что-то, что мы можем напечатать пользователю. Для этого я решил предоставить пользовательскому интерфейсу строку, непосредственно сгенерированную в части C++ кода:

extern "C" JNIEXPORT jstring JNICALL Java_com_example_themoderncppchallenge_Problem_15_SexyPrimeSmallerThan(JNIEnv *env, jobject thiz, jint user_input) {
  auto result = sexyPrimeSmallerThan(user_input);
  std::string text;
  for(const auto& sexyPair : result) {
    text += '(' + std::to_string(sexyPair.first) + ", " + std::to_string(sexyPair.second) + "), ";
  }
  // Removes the last ", "
  text.pop_back();
  text.pop_back();
  return env->NewStringUTF(text.c_str());
}

В этом коде мы форматируем код вручную, чтобы сгенерировать строку, которую пользовательский интерфейс напечатает, как результат предыдущей задачи.

Вывод

Вуаля! Теперь у нас есть приложение, которое может решить первые четыре задачи The Modern C++ Challenge.

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

Спасибо всем за прочтение этой статьи, и до моей следующей статьи, хорошего дня 😉

Интересные ссылки

Первоначально опубликовано на http://10xlearner.com 20 апреля 2020 г.