Преобразуем целые числа в строки с C++

newbie_

Опубликован:  2019-06-16T07:14:11.656383Z
Отредактирован:  2019-07-12T15:56:59.317176Z

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

Условия задачи следующие:

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

В сущности, для решения этой задачи не обязательно преобразовывать число в строку. Но поскольку мне интересен процесс преобразования, я представлю слегка избыточное решение задачи. Решать задачу я буду как обычно на базе операционной системы Debian buster. Запускаю Geany и создаю новый файл, в котором будет храниться исходный код программы.

cd ~/workspace
geany fromint.cpp &

WhieewMS0p.png

Для решения задачи мне потребуются три модуля стандартной библиотеки.

#include <iostream>
#include <string>
#include <cmath>

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

int find_o(const unsigned long n);

Функция find_o принимает в качестве аргумента заданное целое, и возвращает целое int, выражающее разрядность заданного числа, то есть количество знаков в числе.

Для преобразования числа в строку я разработаю функцию conv_n.

std::string conv_n(const unsigned long n);

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

Начнём с расчёта разрядности.

int main()
{
  unsigned long num = 54709879023UL;
  std::cout << num << std::endl;
  int order = find_o(num);
  std::cout << order << std::endl;
  return 0;
}

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

int find_o(const unsigned long n)
{
  using std::pow;
  int order = 0;
  while (!(n / pow(10, order) >= 1 and n / pow(10, order) <=9))
    order += 1;
  return order + 1;
}

Пишу код в файл и сохраняю его.

rRNanrpq06.png

Пробую скомпилировать полученную программу и исполнить её.

g++ fromint.cpp -o exe
./exe

bfkIjy1NlM.png

Отлично, программа вывела на экран терминала само заданное число и его разрядность. Имея разрядность числа, его достаточно просто преобразовать в строку, для этого я создам пустую строку.

using std::pow;
using std::string;
string r = "";

Для преобразования числа в строку мне потребуется эталонная строка, содержащая все цифры от нуля до девяти.

const string digits = "0123456789";

Имея функцию find_o я могу определить разрядность заданного целого числа.

int order = find_o(n);

Преобразование числа в строку будет выполнено простым циклом путём конкатенации полученных в теле цикла строк, найденных по вычисленному индексу на каждом шаге цикла.

for (int i = order; i > 0; i--)
{
  unsigned long k = pow(10, i);
  r += digits[(n - n / k * k) / pow(10, i - 1)];
}

Записываю этот код в тело функции conv_n.

FIfCGJbkzE.png

Теперь нужно слегка изменить код функции main для решения основной задачи.

int main()
{
  unsigned long num = 54709879023UL;
  std::cout << num << std::endl;
  int order = find_o(num);
  std::string str = conv_n(num);
  for (int i = 0; i < order; i++)
    std::cout << str[i] << ' ';
  std::cout << std::endl;
  return 0;
}

Компилирую программу и пробую её исполнить.

g++ fromint.cpp -o exe
./exe

o0p7spOdnL.png

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

Updated later: оптимизация предложенного решения рассмотрена в другом топике блога - Ещё раз о рефакторинге и оптимизации кода.

Комментарии:

newbie_

2019-06-16T07:16:22.440717Z

Код программы целиком:

#include <iostream>
#include <string>
#include <cmath>

int find_o(const unsigned long n);
std::string conv_n(const unsigned long n);

int main()
{
  unsigned long num = 54709879023UL;
  std::cout << num << std::endl;
  int order = find_o(num);
  std::string str = conv_n(num);
  for (int i = 0; i < order; i++)
    std::cout << str[i] << ' ';
  std::cout << std::endl;
  return 0;
}

std::string conv_n(const unsigned long n)
{
  using std::pow;
  using std::string;
  string r = "";
  const string digits = "0123456789";
  int order = find_o(n);
  for (int i = order; i > 0; i--)
  {
    unsigned long k = pow(10, i);
    r += digits[(n - n / k * k) / pow(10, i - 1)];
  }
  return r;
}

int find_o(const unsigned long n)
{
  using std::pow;
  int order = 0;
  while (!(n / pow(10, order) >= 1 and n / pow(10, order) <=9))
    order += 1;
  return order + 1;
}