Разбить число на байты и проверить их последовательность
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
Дано беззнаковое целое x. sizeof(x) строго меньше 256. Требуется проверить следующее утверждение: если разобрать число на байты, то они по разу примут все значения от ноля до sizeof(x)-1. Например, если sizeof(x) равно 8, то требуется проверить утверждение: x состоит из байтов, равных: 0, 1, 2, 3, 4, 5, 6 и 7. При этом порядок байтов значения не имеет.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
я бы подсказал, но мне противопоказан комп 

It's a long way to the top if you wanna rock'n'roll
Ну Ваш вариант угадать не сложно: написать функцию поиска в числе байта с заданным значением и функцию поиска в числе байта с заданным значением, начиная от заданной позиции байта, перебрать циклом байты числа, при этом найти максимальное из их значений и каждое значение поискать в числе обеими функциями. Иначе два костыля не получаются.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Ну изъясняешься ты конечно. Голову сломал, пока прочёл. Особенно последний ответ...
Как хранится число? Как массив байтов?
Просто для таких больших чисел встроенного типа нет.
Самое простое - это отсортировать байты по не убыванию qsort'ом, затем однократно пройти увеличивая счётчик и сравнивая его с текущим байтом. Если все сравнения были успешны, значит говорим да, иначе - говорим нет. Количество действий N*log(N) + 2*N + С. Итого сложность алгоритма O(N) = N*log(N). Думаю, улучшить это значение без дополнительной памяти уже не получится.
Как хранится число? Как массив байтов?
Код: Выделить всё
unsinged char number[255];
Самое простое - это отсортировать байты по не убыванию qsort'ом, затем однократно пройти увеличивая счётчик и сравнивая его с текущим байтом. Если все сравнения были успешны, значит говорим да, иначе - говорим нет. Количество действий N*log(N) + 2*N + С. Итого сложность алгоритма O(N) = N*log(N). Думаю, улучшить это значение без дополнительной памяти уже не получится.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Можно улучшить со сложностью N, т.е. однопроходно, но это в личке =)
It's a long way to the top if you wanna rock'n'roll
Нет конечно.Romeo писал(а):Как хранится число? Как массив байтов?
Восемь жалких байт - это уже большое число?Romeo писал(а):Просто для таких больших чисел встроенного типа нет.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
У меня уже получилось 3N шагов цикла в худшем случае и N+1 в лучшем.Romeo писал(а):Количество действий N*log(N) + 2*N + С. Итого сложность алгоритма O(N) = N*log(N).
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Хорошо, тогда однопроходный алгоритм, но с дополнительной памятью размера N. Решай сам, что тебе важнее: память или скорость. Я бы поставил на второе.
Код: Выделить всё
#include <iostream>
// Checks whether array contains consecutive values from 0 to nSize-1 in arbitrary order.
bool ContainsConsecutiveValues(unsigned char arrNumbers[], unsigned int nSize)
{
bool arrExists[nSize];
for (int i = 0; i < nSize; arrExists[i++] = false);
for (unsigned int i = 0; i < nSize; ++i)
{
// Value is not in range [0..nSize-1]
if (arrNumbers[i] >= nSize) return false;
if (arrExists[arrNumbers[i]])
{
// Repetition of the value
return false;
}
else
{
// Marking the value as met
arrExists[arrNumbers[i]] = true;
}
}
// If we are here, then all the checks are OK, so return true
return true;
}
int main()
{
unsigned char arrNumbers[] = { 1, 0, 3, 2 };
std::cout << (ContainsConsecutiveValues(arrNumbers, sizeof(arrNumbers)) ? "Yes" : "No") << std::endl;
return 0;
}
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
В каком месте сказано, что число на байты уже разобрано? Я даже не использую тот факт, что байты одной переменной хранятся подряд. Они так хранятся, но это не используется.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Я поэтому и спросил, первым делом, как они хранятся. А ты так и не ответил на тот вопрос. И даже сейчас ответа не дал.
Если они гарантированно хранятся подряд (а было бы странно, если бы они не подряд хранились), то просто кастишь память к unsigned char* и используешь готовую функцию.
Если они гарантированно хранятся подряд (а было бы странно, если бы они не подряд хранились), то просто кастишь память к unsigned char* и используешь готовую функцию.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.