Например, на вход в функцию поступает число 12345. Результатом будет 5. Даже если число отрицательное, например, -1234567, то результатом будет 7.
Asked
Active
Viewed 3,885 times
0
-
на какой вход ? Если это поток, то можно даже не считать число. – AR Hovsepyan May 18 '22 at 18:04
-
@ARHovsepyan а если это бинарное представление в потоке а не десятчиное? – Владимир Клыков May 18 '22 at 18:04
-
@ARHovsepyan, в метках же написано алгоритм и функции – Pingvy May 18 '22 at 18:08
-
@Владимир Клыков, вы лучше не повторяйте чужие ответы. А число 12345 никак не бинарное представление.(а если так, то и ваш ответ не верный, потому что пока нет числа) – AR Hovsepyan May 18 '22 at 18:11
-
@Pingvy, И что?... любое решение можно выполнить в функции.... – AR Hovsepyan May 18 '22 at 18:13
5 Answers
4
int length(int n) {
if (n == 0) return 1;
int l = 0;
while(n) {
l++;
n /= 10;
}
return l;
}
Или так:
int length(int n) {
int l = 1;
for(; n/=10; ++l);
return l;
}
Mikhajlo
- 12,592
-
Простите что так нагло утащил ваш код, но имхо - do while красивше :) – Владимир Клыков May 18 '22 at 18:02
-
-
-
-
4
int length(int n) {
int l = 0;
do {
l++;
n /= 10;
} while(n);
return l;
}
Владимир Клыков
- 4,312
- 3
- 27
- 43
-
-
@avp Да =) уже додумался до такого :) но через for как в примере выше - красивше – Владимир Клыков May 18 '22 at 18:57
2
Для работы с log10 и abs необходимо подключить библиотеку math.h (Для типа int работает корректно)
int lenNum(int value)
{
return (value != 0) ? (int)(log10(abs(value))) + 1 : 1;
}
Если же входные данные типа long или long long, то лучше обойтись обычным же стопудовым вариантом - через циклы. (Выше коллеги представили множество подобных решений).
int lenNumLL(long long value)
{
int len = 0;
do
{
value /= 10;
len++;
} while (value);
return len;
}
Artyomka
- 145
-
Спасибо! Я думаю, это самое оптимизированное решение с наименьшей вычислительной сложностью. – Pingvy May 18 '22 at 18:11
-
3@Pingvy, нет, это наоборот _ сложнее и не без побочных эффектов. Если вы не пишете цикл, это еще не значит, что выполняется быстрее. – AR Hovsepyan May 18 '22 at 18:18
-
1Неоправданное привлечение арифметики с плавающей точкой в целочисленную задачу. На некоторых входных данных ответ неверен. – wololo May 18 '22 at 18:30
-
-
2@wololo Мне тоже не нравится дробный
log10, но, справедливости ради, в ответе стоитint, а в своем примере вы его поправили наlong. – HolyBlackCat May 18 '22 at 18:39 -
@HolyBlackCat,
intтакже не даёт гарантий получения корректного результата. Просто я, к сожалению, не могу найти онлайн-компилятор, имеющий те же проблемы с реализацией математических функций, что и в этом вопросе. – wololo May 18 '22 at 18:55 -
- Да, вариант с логарифмом проигрывает по производительности способу с циклом. Тест-1, тест-2. 2)
– wololo May 18 '22 at 21:11Для типа int работает корректноНа некоторых входных данных ответ для типаintтакже неверен. - Да, вариант с логарифмом проигрывает по производительности способу с циклом. Тест-1, тест-2. 2)
1
Еще есть варианты:
size_t foo1(const int n)
{ return std::to_string(n).size() - size_t(n < 0); }
size_t foo2(const int n)
{
std::ostringstream out;
out << n;
return out.str().size() - size_t(n < 0);
}
//...
Но лучше с делением на основание.
AR Hovsepyan
- 15,934
-
2Еще в одну строчку:
std::snprintf(nullptr, 0, "%d", std::abs(n)). – HolyBlackCat May 18 '22 at 19:20 -
@HolyBlackCat, не просто так я поставил многоточие. Верно _ вариантов много. – AR Hovsepyan May 18 '22 at 19:23
1
Перевожу свой комментарий в ответ:
int n = 42;
int len = std::snprintf(nullptr, 0, "%d", n) - (n < 0);
HolyBlackCat
- 27,445
- 3
- 27
- 40
-
– wololo May 18 '22 at 20:54std::snprintf ... не требует выделения памяти в кучеНе помешает какой-нибудь пруф. Здесь не столь категоричны. 2) UB, еслиn == INT_MIN. -
(1) Эксперимент показывает что не требует: https://gcc.godbolt.org/z/v6j6EMMq9 , но фразу из ответа лучше уберу. Так-то и
std::to_stringнаверное не требует, строка-то короткая... (2) Починил. – HolyBlackCat May 19 '22 at 06:26