tolower
#1

Здравствуйте, есть вот такая функция:
PHP Code:
stock strtolower(source[]) 

    for(new 
istrlen(source); i++) switch(source[i]) { 
        case 
168source[i] = 184
        case 
192..223source[i] = (source[i] + 32); 
        default: 
source[i] = tolower(source[i]); 
    } 

Для тех кто не понял tolower делает все буквы в маленьком реестре, тоесть:
Вводим: ААААААААААААббббббббббббб
Выдаст: ааааааааааааааббббббббббббб

Мне нужен что-бы первая буква была с большим реестре, а остальные были маленькими, тоесть:
Вводим: ААААААААААААББББББББББББ
Выдаст: Ааааааааааааааббббббббббббб

Подобная функция есть в PHP, а именно ucfirst.
Можно ли как-то осуществить задуманное?
Reply
#2

Да. Вот:
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. Я бы ещё сделал поддержку упакованных строк...
Reply
#3

Quote:
Originally Posted by VVWVV
View Post
Да. Вот:
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
Reply
#4

Quote:
Originally Posted by Johhnyllll
View Post
В каком смысле? Я о таком не слышал... Можете рассказать по подробнее?
В Pawn существует несколько типов хранения строк. Вы, наверное, знаете, что pawn хранит все символы строки как отдельные символы, т.е. в отдельных ячейках. Это не очень экономно. Экономнее использовать упакованные строки, которые по специальному алгоритму упаковывают четыре символа в одну ячейку. Но следует помнить, что не все функции SA-MP поддерживают их.

printf, format.

Это всего лишь оптимизация памяти, а не скорости, поэтому это на ваше усмотрение, использовать или нет.

UPD:
Reply
#5

Спасибо
Reply
#6

Просто сделай цикл не с i, а с i = 1
Reply
#7

Quote:
Originally Posted by VVWVV
View Post
Да. Вот:
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 
1len strlen(string), clen; ++i)
    {
        if (
'A' <= string[i] <= 'Z')
            
string[i] -= dist;
    }

Те же два обращения к массиву, но лишь одно вычитание. Вместо двух присвоений и одного вычитания.
Reply
#8

Почему бы не сделать просто так?
PHP Code:
stock strtolower(source[], len sizeof(source))
{
    
source[0] = toupper(source[0]);
    for(new 
len; --!= 0;) source[i] = tolower(source[i]);

Reply
#9

Quote:
Originally Posted by ZiGGi
View Post
Что-то ты лишнего "наоптимизировал", так будет гораздо меньше действий:
PHP Code:
stock
    ucfirst
(string[])
{
    
string[0] = toupper(string[0]);
    const 
dist 'A' 'a';
    for (new 
1len strlen(string), clen; ++i)
    {
        if (
'A' <= string[i] <= 'Z')
            
string[i] -= dist;
    }

Те же два обращения к массиву, но лишь одно вычитание. Вместо двух присвоений и одного вычитания.
Спасибо, помогло.
Reply
#10

Quote:
Originally Posted by Richard_Gere
View Post
Почему бы не сделать просто так?
PHP Code:
stock strtolower(source[], len sizeof(source))
{
    
source[0] = toupper(source[0]);
    for(new 
len; --!= 0;) source[i] = tolower(source[i]);

Потому что:

- tolower будет медленнее вычитания

- sizeof возвращает размер массива, а не длину строки
Reply
#11

Quote:
Originally Posted by ZiGGi
View Post
Потому что:

- tolower будет медленнее вычитания

- sizeof возвращает размер массива, а не длину строки
Точно, что-то тупанул.


update:
PHP Code:
stock ucfirst(source[])
{
    
source[0] = toupper(source[0]);
    for(new 
strlen(source) + 1; --!= 0;) {
        
source[i] = tolower(source[i]);
    }

Выходит быстрее вычитывания, ну и поддержка русского языка есть.
Reply
#12

Quote:
Originally Posted by ZiGGi
View Post
Что-то ты лишнего "наоптимизировал", так будет гораздо меньше действий:
PHP Code:
stock
    ucfirst
(string[])
{
    
string[0] = toupper(string[0]);
    const 
dist 'A' 'a';
    for (new 
1len strlen(string), clen; ++i)
    {
        if (
'A' <= string[i] <= 'Z')
            
string[i] -= dist;
    }

Те же два обращения к массиву, но лишь одно вычитание. Вместо двух присвоений и одного вычитания.
Как минимум, я её скопировал из своей библиотеки. Сделаю более быстрее.
Reply
#13

PHP Code:
stock ucfirst(source[])
{
    if(
islower(source[0])) {
        if(
source[0] == \'ё\'source[0] = \'Ё\';
        else 
source[0] -= 32;
    }
    for(new 
strlen(source)+1; --!= 0;) {
        if(
source[i] == \'Ё\'source[i] = \'ё\';
        else if(
isupper(source[i])) source[i] += 32;
    }
}
stock isupper(c)
{
    return (
\'A\' <= <= \'Z\' || \'А\' <= <= \'Я\' || == \'Ё\');
}
stock islower(c)
{
    return (
\'a\' <= <= \'z\' || \'а\' <= <= \'я\' || == \'ё\');

Немного подумав, написал самый быстрый и правильный вариант
Reply
#14

Quote:
Originally Posted by Richard_Gere
View Post
Точно, что-то тупанул.


update:
PHP Code:
stock ucfirst(source[])
{
    
source[0] = toupper(source[0]);
    for(new 
strlen(source) + 1; --!= 0;) {
        
source[i] = tolower(source[i]);
    }

Выходит быстрее вычитывания, ну и поддержка русского языка есть.
Ты решил проблему с длиной, но вычитание всё равно быстрее вызова функций, которая, кстати, вызывается для каждого символа.
Reply
#15

Quote:
Originally Posted by ZiGGi
View Post
Ты решил проблему с длиной, но вычитание всё равно быстрее вызова функций, которая, кстати, вызывается для каждого символа.
Выше исправил. Сравнивал с той функцией, что только английский понимает, tolower оказался быстрее. Тут же наоборот.
Reply
#16

Вот функция дружит с упакованными строками и русским алфавитом:
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);
	}
}
Reply
#17

Quote:
Originally Posted by VVWVV
View Post
Вот функция дружит с упакованными строками и русским алфавитом:
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);
	}
}
Забыл букву \'Ё\'. символы
Reply
#18

Quote:
Originally Posted by Richard_Gere
View Post
Забыл букву \'Ё\'. символы
Обновил предыдущую запись.
Reply
#19

Используете ли вы при тестах и в проекте jit compiller?

Самый быстрый вариант на тестах с jit compiller
PHP Code:
static to_lower_source[0xFF char];
to_lower_init()// в OnGameModeInit()
{
    for(new 
0256i++)
    
to_lower_source{i} = tolower(i);
}
stock ucfirst(source[])
{
    for(new 
strlen(source) + 1i--;)
    
source[i] = to_lower_source{source[i]};
    
source[0] = toupper(source[0]);

Reply
#20

Quote:
Originally Posted by White_116
View Post
Используете ли вы при тестах и в проекте jit compiller?
Не.

Quote:
Originally Posted by White_116
View Post
Самый быстрый вариант на тестах с jit compiller
PHP Code:
static to_lower_source[0xFF char];
to_lower_init()// в OnGameModeInit()
{
    for(new 
0256i++)
    
to_lower_source{i} = tolower(i);
}
stock ucfirst(source[])
{
    for(new 
strlen(source) + 1i--;)
    
source[i] = to_lower_source{source[i]};
    
source[0] = toupper(source[0]);

Точно, но не помешает добавить поддержку кириллицы)
Reply


Forum Jump:


Users browsing this thread: 6 Guest(s)