Заказать Сервер Заказать Плагин Контакты Поиск

[ вход ]
[ последние сообщения ]

Страница 1 из 11
Форум » SourceMod - Counter Strike Source && CS GO » Уроки/Статьи/Функции/Задачи » [ЗАДАЧА] Кол-во чисел в строке и их сумма
[ЗАДАЧА] Кол-во чисел в строке и их сумма
_wS_ Дата: Вторник, 21.05.2013, 09:31:23 | Сообщение # 1
Код
public OnPluginStart()
{
     new const String:text[] = "_gV3_82*d,H1_f4_18_f3";

     // Задача: узнать сколько чисел в строке и их общую сумму
     // Примечание: вы не знаете что строка равна "_gV3_82*d,H1_f4_18_f3", вам лишь известна переменная "text"
}

Задачка несложная, просто для примера даю.
 
Scarface_slv Дата: Вторник, 21.05.2013, 10:18:12 | Сообщение # 2
Сообщений: 749
Репутация: 61 [ +/- ]
Так?
Код

public OnPluginStart()
{   
        new const String:text[] = "_gV3_82*d,H1_f4_18_f3";
        new amount, sum, String:number[2];
        for (new i = 0; i < strlen(text); i++)
        {
                if (IsCharNumeric(text[i]))
                {
                      strcopy(number, 2, text[i]);
                      sum = sum + StringToInt(number); amount++;
                }
        }   
       PrintToServer("amount: %d sum: %d", amount, sum);
}


Сообщение отредактировал Scarface_slv - Вторник, 21.05.2013, 10:19:14
 
_wS_ Дата: Вторник, 21.05.2013, 10:49:11 | Сообщение # 3
Да, но я бы наверно сделал не strcopy, а Format и там "%c". Просто если бы ты размер не 2 поставил, была бы ошибка, но с 2 оно правильно обрезает, так что твой вариант наверно даже лучше, т.к. strcopy быстрее, чем Format.

Только i < strlen(text)
Думаю лучше перед циклом сделать new xz = strlen(text); и в условии уже i < xz
 
Scarface_slv Дата: Вторник, 21.05.2013, 13:26:17 | Сообщение # 4
Сообщений: 749
Репутация: 61 [ +/- ]
Цитата (_wS_)
new xz = strlen(text);

Я сначала так и сделал, но подумал что тут главное решение)
 
GodlikE145 Дата: Четверг, 09.06.2016, 08:13:37 | Сообщение # 5
Сообщений: 33
Репутация: 9 [ +/- ]
Можно и без строк) Сложность алгоритма: O(N)
Код

decl String:text[] = "_gV3_82*d,H1_f4_18_f3";
new len = strlen(text), sum = 0, count = 0, locsum = 0, loccount = 0;
for(new i = 0; i<len; i++)
{
    if(IsCharNumeric(text[i]))
    {
        locsum = locsum*10+(text[i]-48);
        loccount++;
        if(i == len-1)
        {
            sum+=locsum;
            count++;
        }
    }
    else
    {
         count+=(loccount > 0);
         sum+=locsum;
         locsum = 0;
         loccount = 0;
    }
}
PrintToServer("Sum: %d\n Total numbers: %d", sum, count);


Сообщение отредактировал GodlikE145 - Четверг, 09.06.2016, 08:14:39
 
Scarface_slv Дата: Четверг, 09.06.2016, 22:22:51 | Сообщение # 6
Сообщений: 749
Репутация: 61 [ +/- ]
GodlikE145, Я до сих пор не понял как ты это сделал, особенно это locsum*10+(text[i]-48); точней text[i]-48
где ты это откопал или сам додумался я хз.
А сможешь написать алгоритм рандома, например цифр всего 50 - сделать так что бы они ни разу не совпали?


Сообщение отредактировал Scarface_slv - Четверг, 09.06.2016, 22:23:56
 
BarD Дата: Пятница, 10.06.2016, 05:05:37 | Сообщение # 7
Сообщений: 944
Репутация: 132 [ +/- ]
Цитата Scarface_slv ()
text[i]-48

Это перевод из ASCII в обычные цифры. Символ "1" имеет код 49. Т.е. надо отнять 48, чтобы получить цифру в числовом формате. На С++ прокатывает. Вот таблица ASCII символов:

Цитата Scarface_slv ()
А сможешь написать алгоритм рандома, например цифр всего 50 - сделать так что бы они ни разу не совпали?

Вот такой вариантик есть. Сложность алгоритма O(right-left+amount+SortRandom).
Код

//nums - массив, в котором будут рандомные числа
//amount - количество чисел в массиве
//left - от скольки будет рандомизироваться число (левая граница промежутка)
//right - до скольки будет рандомизироваться число (правая граница промежутка)
stock RandomNums(nums[], amount, left, right)
{
    new rnd[right-left];
    for (new i=0;i<right-left;i++)  rnd[i] = i+left; //заполняем массив числами от left до right
    
    SortIntegers(rnd, right-left, Sort_Random); //Сортируем рандомно

    for (new i=0;i<amount;i++) nums[i] = rnd[i]; //заполняем наш массив рандомными числами из первого массива
}

Примечание: left-right должен быть больше или равен amount. Иначе будет ошибка (да и условию неповторяемости это не соответствует).

Прикрепления: 5977012.png(6Kb)


Сообщение отредактировал BarD - Пятница, 10.06.2016, 11:18:08
 
Scarface_slv Дата: Пятница, 10.06.2016, 12:25:30 | Сообщение # 8
Сообщений: 749
Репутация: 61 [ +/- ]
BarD, Спасибо, а это можешь объяснить? nums[x%10]++; точней это x%10; что означает?
 
GodlikE145 Дата: Пятница, 10.06.2016, 13:00:19 | Сообщение # 9
Сообщений: 33
Репутация: 9 [ +/- ]
Цитата Scarface_slv ()
BarD, Спасибо, а это можешь объяснить? nums[x%10]++; точней это x%10; что означает?

Это означает "Остаток от деления x на 10". Т.е. мы прибавляем единицу к элементу nums, индекс которого - последняя цифра числа x. В дальнейшем, мы делим x на 10, чтобы убрать эту цифру.
Ты чуть-чуть темой ошибся, это было в теме "[ЗАДАЧА] Изменить число")


Сообщение отредактировал GodlikE145 - Пятница, 10.06.2016, 13:01:12
 
хвостег Дата: Пятница, 10.06.2016, 13:15:09 | Сообщение # 10
Сообщений: 161
Репутация: 53 [ +/- ]
Цитата Scarface_slv ()
а это можешь объяснить? nums[x%10]++; точней это x%10; что означает?

% - деление с остатком.
При делении числа 59 на 10 получаем неполное частное 5 и остаток 9.
 
GodlikE145 Дата: Пятница, 10.06.2016, 13:19:33 | Сообщение # 11
Сообщений: 33
Репутация: 9 [ +/- ]
Цитата Scarface_slv ()
А сможешь написать алгоритм рандома, например цифр всего 50 - сделать так что бы они ни разу не совпали?

Решил подумать над этой задачей и придумал алгоритм, работающий быстрее, чем сортировка рандомом. Написал через рекурсию вот таким образом:
Код

#define COUNT 15

stock RandomTest(left, right)
{
       new gr = GetRandomInt(left, right-1);
       interval1 = (right-left)/COUNT;
       Rec(left, gr);
       Rec(gr+1, right);    
    
       for(new i = 0; i<COUNT; i++) PrintToServer("%d: %d", i, nums[i]);
}

stock Rec(left, right)
{
       new rand = GetRandomInt(left, right-1);
       if(count<COUNT)
       {
            if(left == right)
            {
                   if(loccount%interval1==0)
                   {
                          nums[count] = rand;
                          count++;
                   }
                   loccount++;
            }
            else
            {
                   new psevd = GetRandomInt(0, 1000);
                   if(GetRandomInt(0, 1000)<psevd)
                   {
                           Rec(rand+1, right);
                           Rec(left, rand);
                   }
                   else
                   {
                           Rec(left, rand);
                           Rec(rand+1, right);
                   }
            }
      }
}


Это, по идее, должно работать быстрее, чем сортировка. Сложность примерно O(2N), где N - количество чисел, которые нужно сгенерировать.
Запускал через комманду, аргументы у которой - левая и правая границы соответственно.
ВНИМАНИЕ: Это ПСЕВДОрандом, т.е. он генерирует числа не совсем рандомно. Это видно, если присмотреться к цифрам на скрине. Делал чисто ради забавы)

Такое решение НЕ ПРИМЕНИМО на практике, лучше используйте вариант с сортировкой


Прикрепления: 4486675.jpg(17Kb) · 0935182.jpg(15Kb) · 3981670.jpg(14Kb)


Сообщение отредактировал GodlikE145 - Воскресенье, 12.06.2016, 11:45:04
 
Форум » SourceMod - Counter Strike Source && CS GO » Уроки/Статьи/Функции/Задачи » [ЗАДАЧА] Кол-во чисел в строке и их сумма
Страница 1 из 11
Поиск: