| 
 
 
	
		
		
			| [ЗАДАЧА] Кол-во чисел в строке и их сумма |  |  |  | 
| _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 |  |   
|  |  | Сообщений: 737 Репутация: 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 |  |   
|  |  | Сообщений: 737 Репутация: 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 |  |   
|  |  | Сообщений: 737 Репутация: 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 |  |   
|  |  | Сообщений: 943 Репутация: 137 [ +/- ]
 |  | Цитата 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. Иначе будет ошибка (да и условию неповторяемости это не соответствует).
 | Гости не могут скачивать файлы | 
 
 
 Сообщение отредактировал BarD - Пятница, 10.06.2016, 11:18:08 |  |  |  |  |  | 
| Scarface_slv | Дата: Пятница, 10.06.2016, 12:25:30 | Сообщение # 8 |  |   
|  |  | Сообщений: 737 Репутация: 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 - количество чисел, которые нужно сгенерировать.
 Запускал через комманду, аргументы у которой - левая и правая границы соответственно.
 ВНИМАНИЕ: Это ПСЕВДОрандом, т.е. он генерирует числа не совсем рандомно. Это видно, если присмотреться к цифрам на скрине. Делал чисто ради забавы)
 
 Такое решение НЕ ПРИМЕНИМО на практике, лучше используйте вариант с сортировкой
 
 
 | Гости не могут скачивать файлы | 
 
 
 Сообщение отредактировал GodlikE145 - Воскресенье, 12.06.2016, 11:45:04 |  |  |  |  |  
 |