Как перенести первую цифру в конец числа в С++?

Вот код:

#include <iostream>
using namespace std;

int main ()
{
    int n;
    cin >> n;
    int first = n;

    while (first>=10)
    {
      first/=10;
    }

    cout << first << endl;
}

В приведенном выше коде, который я попытался получить первую цифру положительного числа, я хочу, чтобы положить его после последней цифры, например: 1934 -> 9341.

Ответ 1

Преобразуйте число в строку с помощью std:: to_string, выполните левое вращение, используя std:: rotate и конвертировать обратно в число, используя std:: stoull:

std::string s = std::to_string(n);
std::rotate(s.begin(), s.begin() + 1, s.end());
n = std::stoull(s);

Со всеми включенными заголовками:

#include <iostream>
#include <string>
#include <algorithm>

int main() {
    unsigned long long n = 1934;
    std::string s = std::to_string(n);
    std::rotate(s.begin(), s.begin() + 1, s.end()); // left rotation
    n = std::stoull(s);
    std::cout << n; // 9341
}

Ответ 2

Вот простое решение, которое не использует строки или функции с плавающей запятой/арифметику. Использование таких функций, как pow(), может столкнуться с проблемами, описанными в в этом вопросе.

 #include <iostream>

 int main()
 {
    unsigned long long n = 1934L;

    // save the original
    unsigned long long final_number = n;

    // multiplying factor
    unsigned long long mult = 1;

    // start by making sure we do not loop one too many times to 
    // calculate the multiplier
    n /= 10;

    while (n > 0)
    {
        // determines the multiplication factor after the loop 
        mult *= 10; 

        // strip off digit from number
        n /= 10;
    }

    // create the final number from the original and the multiplication factor
    final_number = (final_number % mult) * 10 + final_number / mult;
    std::cout << final_number << "\n";
}

Живой пример

В основном мы подсчитываем количество цифр путем циклирования и в то же время увеличиваем коэффициент умножения на 10. Затем, после цикла, число создается с использованием модуля, умножения, деления и сложения.

Так, например, после цикла, final_number будет

(1934 % 1000) * 10 + 1934 / 1000 =
934 * 10 + 1934 / 1000 = 
9340 + 1934 / 1000 =
9340 + 1 =
9341

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

Ответ 3

Вы можете изменить свой цикл, чтобы не только получить первую цифру, но и вычислить количество цифр в одно и то же время (это число итераций цикла). Затем используйте % и * 10, чтобы изменить n.

Ответ 4

поскольку там уже много решений с std::string, я пытался сделать это с этим, вот мои результаты. Надеюсь, это поможет.

#include <iostream>
#include <cmath>
using namespace std;

int removeFirst(int n)
{
    int tmp(0);
    for (int i(0);; ++i)
    {
        int m = n % 10;
        n /= 10;
        if (n != 0)
        {
            tmp += pow(10, i) * m;
        }
        else
        {
            break;
        }
    }
    return tmp;
}

int main()
{
    int input, first, withoutFirst;
    cin >> input;
    withoutFirst = removeFirst(input);

    while (input >= 10)
    {
        input /= 10;
    }
    first = input;

    cout << withoutFirst << first << endl;
}

Справка: пытается удалить первую цифру любого номера

С уважением.

Ответ 5

Предположим, что в качестве ввода мы имеем положительное целое число.

  • Получить наиболее значимую цифру

    MSD=floor(X/pow(10,floor(log10(X))));
    
  • Получить оставшуюся часть номера

    Rest=X%pow(10,floor(log10(X)));
    
  • Подведение остальных к соответствующему значению

    Rest=Rest*10;
    
  • Добавление первой наиболее значащей цифры

    Y=Rest+MSD.
    

Исправленный пример:

X=54321;                             // 54321
                         log10(X)    // 4.734...
                   floor(...     )   // 4
            pow(10,...            )  // 10000
          X/...                      // 5.4321
MSD=floor(...                      );// 5
           pow(10,floor(log10(X))    // 10000
         X%...                       // 4321
      10*...                         // 43210
Y=MSD+...                        ;   // 43215

Ответ 6

Решение, которое не использует строки. Он использует std::stack, и он может не выиграть награды за эффективность, но это должно быть довольно простым и понятным.

#include <stack>
#include <iostream>

int main()
{
    int num = 1934;
    std::stack<int> digits;

    // Break the number into digits, pushing them onto a stack
    while (num)
    {
        auto digit = num % 10;
        digits.push(digit);
        num /= 10;
    }

    // Get the first digit from the top of the stack and save it
    auto first = 0;
    if (!digits.empty())
    {
        first = digits.top();
        digits.pop();
    }

    // Pop the remaining digits off the stack and print them
    while (!digits.empty())
    {
        std::cout << digits.top();
        digits.pop();
    }

    // Print the first digit on the end
    std::cout << first << '\n';
}

EDIT: Исправлена ​​ошибка, если num == 0. Обратите внимание, что отрицательные числа обрабатываются неправильно, но я не уверен, какое желательное поведение было бы для этого случая. Использование unsigned вместо int может быть хорошей идеей.

Ответ 7

Я начну, сказав, что я не программист на С++; поэтому я не говорю, что этот код хорош, просто он работает, и он следует вашему подходу!

Я расскажу вам, как до того, как я покажу вам минимальное редактирование вашего кода, чтобы получить то, что вы хотите, с примером: предположим, вы хотите преобразовать 2345 в 3452

  • Вы начали с поиска наиболее значимой цифры (first) вашего ввода (n)
  • Теперь вам нужно удалить эту цифру с фронта. Это легко:
    • У нас уже есть цикл, в котором мы делим first на 10, поэтому давайте его повторно использовать
    • создайте число (мы будем называть его bigness), которое начинается с 1, и каждый цикл умножает его на 10.
  • Теперь у вас есть 3 номера:
    • n= 2345
    • first= 2
    • bigness= 1000

Это все, что вам нужно!

Вы можете вычесть first * bigness из n, чтобы удалить номер с фронта - 345

Вы можете умножить это на 10 и добавить first, чтобы поместить номер в конец - 3452

Здесь конечный код:

#include <iostream>
using namespace std;

int main ()
{
    int n;
    cin >> n;
    int first = n;
    int bigness = 1;

    while (first >= 10)
    {
        first /= 10;
        bigness *= 10;
    }

    n = n - (first * bigness);
    n = (n * 10) + first;

    cout << n;
}

Обратите внимание, что это оставит проблемы для чисел типа 20000 - они станут 2, потому что наш код не знает, что мы хотим 00002. Это легко исправить, используя что-то вроде printf для поддержания количества цифр, но это будет означать другую переменную в вашем цикле, начиная с 1, подсчитывая количество цифр, которое нам нужно.

Ответ 8

Поскольку целые числа С++ имеют не более дюжины цифр, код может использовать простое рекурсивное решение:

unsigned reverse_helper(unsigned x) {
  if (x < 10) {
    return x;
  }
  unsigned last = reverse_helper(x/10);
  cout << x%10;
  return last;
}

void reverse(unsigned x) {
  cout << reverse_helper(x)) << endl;
}

Тестовый код

int main(void) {
  reverse(0);
  reverse(9);
  reverse(10);
  reverse(1934);
  reverse(1234567890);
}

0
9
01
9341
2345678901

Ответ 9

Здесь версия без использования строк.

//There also a builtin log10 function but you can write your own if you want to:
int log10(int nbr) {
    return log(n) / log(10);
}

//....
int first_digit = n / (int)pow(10, log10(n));
int everything_else = n % (int)pow(10, log10(n));

Обязательно включите math.h

Он использует тот факт, что преобразование float -> int всегда округляется до нуля в С++. Итак, (int)log10(101) вернет 2, а pow(10, (log10(n))) будет округлять каждое число, округленное до 10/100/1000/etc. Остальное просто простое разделение и по модулю.

Ответ 10

Это типичный элемент программирования и математического программирования, поэтому я не дам полного ответа, но я скажу, что:

  • Использование строк - это, безусловно, не самое эффективное эффективное решение с процессором.
  • У вас уже есть первая (самая значительная) цифра. Изменив код в своем вопросе, вы можете вычислить соответствующую мощность 10 для вычитания первой цифры из исходного номера.
  • Обратите внимание, что n * 10 сдвигает число слева и оставляет "отверстие", которое вы можете позже заполнить по мере необходимости. (Извините, если это очевидно для вас.)
  • Вы можете делать все, используя только целые операции, без поплавков, без функций (log, exp). Другие решения уже показывают полные алгоритмы; Я подчеркиваю, что вы можете обойтись без поплавков и журналов.
  • Будьте осторожны с 0 и отрицательными номерами.

Ответ 11

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

#include <iostream>
#include <math.h>
using namespace std;

int main ()
{
    int n, digits, firstDigit, firstDigitToLast;
    cin >> n;

    digits = (int)log10(n);
    firstDigit = (int)(n / pow(10, digits));
    firstDigitToLast = n % ((int) pow(10, digits));
    firstDigitToLast *= 10;
    firstDigitToLast += firstDigit;

    cout << firstDigitToLast << endl;
}

Ответ 12

std::string s = std::to_string(n);
s += s.front();
s.erase(0, 1);
n = std::stoull(s);

Это:

  • Преобразует число в строку.
  • Добавляет первый символ в конец.
  • Удаляет первый символ.
  • И преобразует результат обратно в unsigned long long.

Живой пример

Ответ 13

Я использовал бы log10 и %.

int num = 8907;

int num_digits = log10(num); // Value of 3 for 8907
int pwr = pow(10, num_digits); // Value of 1000 for 8907
int ones_place = num % 10; // 7
int bigs_place = num / pwr; // 8

int cur_msd = bigs_place * pwr; // 8000
int new_msd = ones_place * pwr; // 7000

num -= cur_msd;
num += new_msd;
num -= ones_place;
num += bigs_place;
cout << num << endl;

Этот код выводит для меня 7908.


Edit

Я неправильно прочитал сообщение. Я думал, что вы хотите, чтобы LSB и MSB менялись местами, а не вращались.

Замените последние 4 строки на

num -= cur_msd;
num *= 10;
num += bigs_place;

Ответ 14

Хотя циклы и строки могут быть очень эффективными, в этом случае они совершенно не нужны.
Все, что вам нужно, это немного математики:

#include <math.h>       // log10, pow, floor
#include <stdio.h>      // printf
int main ()
{
  int n = 6945;
  int p = pow(10,floor(log10(n)));
  int output = (n - ((n/p)%10)*p)*10+((n/p)%10);
  printf("%i",output);       // outputs 9456
}

Идея состоит в том, чтобы сначала узнать, сколько цифр число (floor(log10(n))), а затем получить самую значительную цифру, разделив вход на 10, поднятый до этой мощности (pow(10,floor(log10(n)))) по модулю 10. Мы сохраним это в int, называемом p.

В этом случае это дает нам 6. Затем мы вычитаем 6 раз p из n, чтобы получить оставшиеся цифры (945 в нашем случае), которые затем умножим на десять и добавим 6 to, получив наш окончательный ответ 9456