На самом деле, я ответил другим (несколько смешным) ответом, который использовал абсолютно огромный массив для поиска в таблице, но, оглядываясь назад, это не так уж и плохо, если вы ограничите размер таблицы.
Следующие функции компенсируют пространство для времени.Как и во всех оптимизациях, вы должны сами их профилировать в целевой среде.
Первая (элегантная) рекурсивная версия:
unsigned int getSum (unsigned int val) {
static const unsigned char lookup[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // 0- 9
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10- 19
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, // 20- 29
:
18, 19, 20, 21, 22, 23, 24, 25, 26, 27 // 990-999
};
return (val == 0) ? 0 : getSum (val / 1000) + lookup[val%1000];
}
В основном она разделяет число на трехзначные группировки с фиксированнойпоиск для каждой возможности.Это может легко обработать 64-битное значение без знака с глубиной рекурсии в семь кадров стека.
Для тех, кто даже не доверяет , что небольшое количество рекурсии (и вы должны, так какобычные программы идут так глубоко и даже без рекурсии), вы можете попробовать итеративное решение:
unsigned int getSum (unsigned int val) {
static const unsigned char lookup[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // 0- 9
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10- 19
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, // 20- 29
:
18, 19, 20, 21, 22, 23, 24, 25, 26, 27 // 990-999
};
unsigned int tot = 0;
while (val != 0) {
tot += lookup[val%1000];
val /= 1000;
}
return tot;
}
Это, вероятно, в три раза быстрее, чем однозначное решение за счет стоимоститысячи байтов данных.Если вы не против использования 10K или 100K, вы можете увеличить скорость до четырех или пяти раз, но вы можете написать программу для генерации оператора статического массива, приведенного выше: -)
Как и при любой оптимизацииварианты, мера, не угадай!
Я сам предпочитаю более элегантное рекурсивное решение, но я также один из тех, кто предпочитает загадочные кроссворды.Читайте в это, что вы будете.