tolower -
Johhnyllll - 12.11.2016
Здравствуйте, есть вот такая функция:
PHP Code:
stock strtolower(source[])
{
for(new i; i < strlen(source); i++) switch(source[i]) {
case 168: source[i] = 184;
case 192..223: source[i] = (source[i] + 32);
default: source[i] = tolower(source[i]);
}
}
Для тех кто не понял tolower делает все буквы в маленьком реестре, тоесть:
Вводим: ААААААААААААббббббббббббб
Выдаст: ааааааааааааааббббббббббббб
Мне нужен что-бы первая буква была с большим реестре, а остальные были маленькими, тоесть:
Вводим: ААААААААААААББББББББББББ
Выдаст: Ааааааааааааааббббббббббббб
Подобная функция есть в PHP, а именно
ucfirst.
Можно ли как-то осуществить задуманное?
Re: tolower -
VVWVV - 12.11.2016
Да. Вот:
Code:
stock
ucfirst(string[])
{
string[0] = toupper(string[0]);
const dist = 'A' - 'a';
for(new i = 1, len = strlen(string), c; i < len; ++i)
{
if ('A' <= (c = string[i]) <= 'Z')
c -= dist;
string[i] = c;
}
}
P.S. Я бы ещё сделал поддержку упакованных строк...
Re: tolower -
Johhnyllll - 12.11.2016
Quote:
Originally Posted by VVWVV
Да. Вот:
Code:
stock
ucfirst(string[])
{
string[0] = toupper(string[0]);
const dist = 'A' - 'a';
for(new i = 1, len = strlen(string), c; i < len; ++i)
{
if ('A' <= (c = string[i]) <= 'Z')
c -= dist;
string[i] = c;
}
}
P.S. Я бы ещё сделал поддержку упакованных строк...
|
В каком смысле? Я о таком не слышал... Можете рассказать по подробнее?
//upd
Твоя функция делает из маленького реестра и в большую, т.е:
Вводим: aaaaaaaaaabbbbbbbbbbb
Получится: Aaaaaaaaaabbbbbbbbbbb
Мне же нужна функция каторая не зависимо от реестра работает так:
Вводим: DDDDDDDDFFFFFFFFF или dddddddddffffffffff
Мы получим на выходе: Dddddddddffffffffff
Re: tolower -
VVWVV - 12.11.2016
Quote:
Originally Posted by Johhnyllll
В каком смысле? Я о таком не слышал... Можете рассказать по подробнее?
|
В Pawn существует несколько типов хранения строк. Вы, наверное, знаете, что pawn хранит все символы строки как отдельные символы, т.е. в отдельных ячейках. Это не очень экономно. Экономнее использовать упакованные строки, которые по специальному алгоритму упаковывают четыре символа в одну ячейку. Но следует помнить, что не все функции SA-MP поддерживают их.
printf, format.
Это всего лишь оптимизация памяти, а не скорости, поэтому это на ваше усмотрение, использовать или нет.
UPD:
Re: tolower -
Johhnyllll - 12.11.2016
Спасибо
Re: tolower -
OKStyle - 13.11.2016
Просто сделай цикл не с i, а с i = 1
Re: tolower -
ZiGGi - 13.11.2016
Quote:
Originally Posted by VVWVV
Да. Вот:
Code:
stock
ucfirst(string[])
{
string[0] = toupper(string[0]);
const dist = 'A' - 'a';
for(new i = 1, len = strlen(string), c; i < len; ++i)
{
if ('A' <= (c = string[i]) <= 'Z')
c -= dist;
string[i] = c;
}
}
P.S. Я бы ещё сделал поддержку упакованных строк...
|
Что-то ты лишнего "наоптимизировал", так будет гораздо меньше действий:
PHP Code:
stock
ucfirst(string[])
{
string[0] = toupper(string[0]);
const dist = 'A' - 'a';
for (new i = 1, len = strlen(string), c; i < len; ++i)
{
if ('A' <= string[i] <= 'Z')
string[i] -= dist;
}
}
Те же два обращения к массиву, но лишь одно вычитание. Вместо двух присвоений и одного вычитания.
Re: tolower -
Richard_Gere - 13.11.2016
Почему бы не сделать просто так?
PHP Code:
stock strtolower(source[], len = sizeof(source))
{
source[0] = toupper(source[0]);
for(new i = len; --i != 0;) source[i] = tolower(source[i]);
}
Re: tolower -
Johhnyllll - 13.11.2016
Quote:
Originally Posted by ZiGGi
Что-то ты лишнего "наоптимизировал", так будет гораздо меньше действий:
PHP Code:
stock
ucfirst(string[])
{
string[0] = toupper(string[0]);
const dist = 'A' - 'a';
for (new i = 1, len = strlen(string), c; i < len; ++i)
{
if ('A' <= string[i] <= 'Z')
string[i] -= dist;
}
}
Те же два обращения к массиву, но лишь одно вычитание. Вместо двух присвоений и одного вычитания.
|
Спасибо, помогло.
Re: tolower -
ZiGGi - 13.11.2016
Quote:
Originally Posted by Richard_Gere
Почему бы не сделать просто так?
PHP Code:
stock strtolower(source[], len = sizeof(source)) { source[0] = toupper(source[0]); for(new i = len; --i != 0;) source[i] = tolower(source[i]); }
|
Потому что:
- tolower будет медленнее вычитания
- sizeof возвращает размер массива, а не длину строки
Re: tolower -
Richard_Gere - 13.11.2016
Quote:
Originally Posted by ZiGGi
Потому что:
- tolower будет медленнее вычитания
- sizeof возвращает размер массива, а не длину строки
|
Точно, что-то тупанул.
update:
PHP Code:
stock ucfirst(source[])
{
source[0] = toupper(source[0]);
for(new i = strlen(source) + 1; --i != 0;) {
source[i] = tolower(source[i]);
}
}
Выходит быстрее вычитывания, ну и поддержка русского языка есть.
Re: tolower -
VVWVV - 13.11.2016
Quote:
Originally Posted by ZiGGi
Что-то ты лишнего "наоптимизировал", так будет гораздо меньше действий:
PHP Code:
stock
ucfirst(string[])
{
string[0] = toupper(string[0]);
const dist = 'A' - 'a';
for (new i = 1, len = strlen(string), c; i < len; ++i)
{
if ('A' <= string[i] <= 'Z')
string[i] -= dist;
}
}
Те же два обращения к массиву, но лишь одно вычитание. Вместо двух присвоений и одного вычитания.
|
Как минимум, я её скопировал из своей библиотеки. Сделаю более быстрее.
Re: tolower -
Richard_Gere - 13.11.2016
PHP Code:
stock ucfirst(source[])
{
if(islower(source[0])) {
if(source[0] == \'ё\') source[0] = \'Ё\';
else source[0] -= 32;
}
for(new i = strlen(source)+1; --i != 0;) {
if(source[i] == \'Ё\') source[i] = \'ё\';
else if(isupper(source[i])) source[i] += 32;
}
}
stock isupper(c)
{
return (\'A\' <= c <= \'Z\' || \'А\' <= c <= \'Я\' || c == \'Ё\');
}
stock islower(c)
{
return (\'a\' <= c <= \'z\' || \'а\' <= c <= \'я\' || c == \'ё\');
}
Немного подумав, написал самый быстрый и правильный вариант
Re: tolower -
ZiGGi - 13.11.2016
Quote:
Originally Posted by Richard_Gere
Точно, что-то тупанул.
update:
PHP Code:
stock ucfirst(source[]) { source[0] = toupper(source[0]); for(new i = strlen(source) + 1; --i != 0;) { source[i] = tolower(source[i]); } }
Выходит быстрее вычитывания, ну и поддержка русского языка есть.
|
Ты решил проблему с длиной, но вычитание всё равно быстрее вызова функций, которая, кстати, вызывается для каждого символа.
Re: tolower -
Richard_Gere - 13.11.2016
Quote:
Originally Posted by ZiGGi
Ты решил проблему с длиной, но вычитание всё равно быстрее вызова функций, которая, кстати, вызывается для каждого символа.
|
Выше исправил. Сравнивал с той функцией, что только английский понимает, tolower оказался быстрее. Тут же наоборот.
Re: tolower -
VVWVV - 13.11.2016
Вот функция дружит с упакованными строками и русским алфавитом:
Code:
stock
ucfirst(string[])
{
const dist = \'A\' - \'a\';
new i = strlen(string),
c;
if (string{0} != 0)
{
if (0xE0 <= (c = string{0}) <= 0xFF)
string{0} += dist;
else if (c == 0xB8)
string{0} = 0xA8;
else if (\'a\' <= c <= \'z\')
string{0} += dist;
do
{
if (0xC0 <= (c = string{i}) <= 0xDF)
c -= dist;
else if (c == 0xA8)
c = 0xB8;
else if (\'A\' <= c <= \'Z\')
c -= dist;
string{i} = c;
}
while (--i != 0);
}
else
{
if (0xE0 <= (c = string[0]) <= 0xFF)
string[0] += dist;
else if (c == 0xB8)
string[0] = 0xA8;
else if (\'a\' <= c <= \'z\')
string[0] += dist;
do
{
if (0xC0 <= (c = string[i]) <= 0xDF)
c -= dist;
else if (c == 0xA8)
c = 0xB8;
else if (\'A\' <= c <= \'Z\')
c -= dist;
string[i] = c;
}
while (--i != 0);
}
}
Re: tolower -
Richard_Gere - 13.11.2016
Quote:
Originally Posted by VVWVV
Вот функция дружит с упакованными строками и русским алфавитом:
Code:
stock
ucfirst(string[])
{
const dist = \'A\' - \'a\';
new i = strlen(string),
c;
if (string{0} != 0)
{
if (0xE0 <= (c = string{0}) <= 0xFF)
string{0} += dist;
else if (\'a\' <= c <= \'z\')
string{0} += dist;
do
{
if (0xC0 <= (c = string{i}) <= 0xDF)
c -= dist;
else if (\'A\' <= c <= \'Z\')
c -= dist;
string{i} = c;
}
while (--i != 0);
}
else
{
if (0xE0 <= (c = string[0]) <= 0xFF)
string[0] += dist;
else if (\'a\' <= c <= \'z\')
string[0] += dist;
do
{
if (0xC0 <= (c = string[i]) <= 0xDF)
c -= dist;
else if (\'A\' <= c <= \'Z\')
c -= dist;
string[i] = c;
}
while (--i != 0);
}
}
|
Забыл букву \'Ё\'.
символы
Re: tolower -
VVWVV - 13.11.2016
Quote:
Originally Posted by Richard_Gere
|
Обновил предыдущую запись.
Re: tolower -
White_116 - 13.11.2016
Используете ли вы при тестах и в проекте jit compiller?
Самый быстрый вариант на тестах с jit compiller
PHP Code:
static to_lower_source[0xFF char];
to_lower_init()// в OnGameModeInit()
{
for(new i = 0; i < 256; i++)
to_lower_source{i} = tolower(i);
}
stock ucfirst(source[])
{
for(new i = strlen(source) + 1; i--;)
source[i] = to_lower_source{source[i]};
source[0] = toupper(source[0]);
}
Re: tolower -
ZiGGi - 13.11.2016
Quote:
Originally Posted by White_116
Используете ли вы при тестах и в проекте jit compiller?
|
Не.
Quote:
Originally Posted by White_116
Самый быстрый вариант на тестах с jit compiller
PHP Code:
static to_lower_source[0xFF char]; to_lower_init()// в OnGameModeInit() { for(new i = 0; i < 256; i++) to_lower_source{i} = tolower(i); } stock ucfirst(source[]) { for(new i = strlen(source) + 1; i--;) source[i] = to_lower_source{source[i]}; source[0] = toupper(source[0]); }
|
Точно, но не помешает добавить поддержку кириллицы)