Как перенести первую цифру в конец числа в С++?
Вот код:
#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