Существует умный способ определить, к какой группе принадлежит слово.
Мы должны создать схему, в которой каждая группа однозначно идентифицируется номером. Как мы определяем и дифференцируем группу: по каким буквам она содержится. Повторяющиеся буквы не учитываются (это набор). Поэтому нам нужна формула для кодирования набора букв группы. Если мы присваиваем каждой букве число (начиная с 0
), мы получаем идентификатор с помощью суммы степеней двух (на самом деле можно выбрать любое основание, но 2
является естественным выбором для вычислений).
Например:
"abdeae"
Набор букв {'a', 'b', 'd', 'e'}
. Их соответствующие номера: {0, 1, 3, 4}
и идентификатор 2^0 + 2^1 + 2^3 + 2^4
.
Поскольку существует 26
букв, мы можем использовать 32-битное целое число для кодирования идентификатора. 2^i
соответствует биту i
, поэтому алгоритм выглядит следующим образом:
uint32_t letter_mask(char ch)
{
assert(ch >= 'a' && ch <= 'z');
return (uint32_t) 1u << (ch - 'a');
}
uint32_t word_group_id(const char * str)
{
size_t len = strlen(str);
uint32_t id = 0;
for (size_t i = 0; i < len; ++i)
{
id |= letter_mask(str[i]);
}
return id;
}
Теперь, когда у нас есть простой способ определить группу слова, вам нужно создать упрощенную версию карта, куда положить слова.
Это моя простая быстрая реализация. Отказ от ответственности: не проверено. Вы также должны улучшить его, добавив проверки для malloc и realloc.
typedef struct Word_map_bucket
{
uint32_t id;
char** words;
size_t words_size;
} Word_map_bucket;
void init_word_map_bucket(Word_map_bucket* bucket, uint32_t id)
{
bucket->id = id;
bucket->words = NULL;
bucket->words_size = 0;
}
typedef struct Word_map
{
Word_map_bucket* buckets;
size_t buckets_size;
} Word_map;
void init_word_map(Word_map* map)
{
map->buckets = NULL;
map->buckets_size = 0;
}
Word_map_bucket* find_bucket(Word_map map, uint32_t id)
{
for (size_t i = 0; i < map.buckets_size; ++i)
{
if (map.buckets[i].id == id)
return &map.buckets[i];
}
return NULL;
}
Word_map_bucket* add_new_bucket(Word_map* map, uint32_t id)
{
map->buckets = realloc(map->buckets, map->buckets_size + 1);
map->buckets_size += 1;
Word_map_bucket* bucket = &map->buckets[map->buckets_size + 1];
init_word_map_bucket(bucket, id);
return bucket;
}
void add_word(Word_map* map, const char* word)
{
// get to bucket
uint32_t id = word_group_id(word);
Word_map_bucket* bucket = find_bucket(*map, id);
if (bucket == NULL)
bucket = add_new_bucket(map, id);
// increase bucket->words
bucket->words = realloc(bucket->words, bucket->words_size + 1);
bucket->words_size += 1;
// push word into bucket
bucket->words[bucket->words_size - 1] = malloc(strlen(word));
strcpy(bucket->words[bucket->words_size - 1], word);
}
if(!is_numeric($quantity == 0)){
//redirect($data['referurl']."/badinput");
echo "is not numeric";
Что Вы имеете, вот два вложенных условия. Скажем, $quantity равняется 1.
Первое условие оценивает 1 == 0 и возвращает FALSE. Второе условие проверяет, является ли ЛОЖЬ числовой и возвращает FALSE, потому что ЛОЖЬ не является числовой.
просто запись:
if (!is_numeric($quantity))
{
echo 'is not numeric';
}
Необходимо ли, вероятно, объяснить, под чем Вы подразумеваете "числовой" - интеграл, плавающая точка, экспоненциальное представление и т.д.? is_numeric()
примет все их.
Если Вы хотите проверить, что строка ничего не содержит кроме цифр, то Вы могли использовать регулярное выражение, например.
/^\d+$/
Если Вы соберетесь использовать фактическое значение, как будто это было целое число, Вы, вероятно, захотите передать его через intval()
так или иначе, который возвратится 0
если значение не может быть проанализировано - если 0
допустимое значение, затем необходимо будет, вероятно, обработать это в некотором роде, возможно, путем ограничения более низкого диапазона значения.
Могло бы также быть мудро сделать некоторую клиентскую проверку входа с помощью JavaScript.
Распространение в прямом и обратном направлениях к серверу и назад является длинным для того, что могло бы составить опечатку, и Вы уменьшите сервер наверху, заставляя клиентский браузер сделать немного гарантия качества заранее.
Проверьте is_int и is_numeric. Существуют примеры в каждой из ссылок. Если бы Вы нуждаетесь в большем количестве помощи, я отправил бы данные, у Вас есть проблемы с и пример кода.
Править:
$quantity == 0
всегда будет числовым, так как это возвратит булево значение (1 или 0). Корректная вещь сделать это:
if ( is_numeric( $quantity ) ) {
...
}
или
if ( is_int( $quantity ) ) {
...
}
Что сказал Rob, хотя вместо регулярных выражений для проверки на цифры я буду использовать ctype_digit
tharkun имеет лучший ответ до сих пор. Если Вы задаете вопрос как это, это - мое предположение, что Вы действительно не хотите начинать бездельничать с reg-exp's просто все же.
Заново продумайте свою логику. Почему Вы хотите проверить, чтобы видеть, является ли $quantity == 0 числовым результатом? Если Вы стараетесь избегать ошибок b/c, Вы думаете, что для количества возможно не иметь присвоенное значение, Вы проверяете немного поздно. Это - очень общее (и низкий) дыра в системе безопасности в Вашем приложении - если $quantity получили значение вообще от ввода данных пользователем, удостоверьтесь, что санировали вход, прежде чем это достигнет этой точки в выполнении. Как меньшая часть проблемы, Вы не должны будете присваивать значение по умолчанию, потому что Вы санировали свой вход ранее (и та санитизация - то, где Вы не справились бы с 'никаким входом' ситуация).
Удачи!