PDA

Просмотр полной версии : [Function] Поиск значения в элементах массива



$continue$
23.07.2015, 04:13
Приветствую уважаемые пользователи Pro - Pawn!
Описание:

Ищет значение в элементах массива

Параметры:

array - Массив в котором ищем значение.
search_value - Значение которое хотим найти в массиве.
array_size - Размер массива (Вычисляется оператором sizeof, дополнительных манипуляций не требуется)


Возвращаемое значение:

Функция возвращает элемент массива в котором найдено значение, иначе -1


SearchValueInElemetsArray(array[], search_value, array_size = sizeof(array))
{
// Создадим цикл for с условиями что, пока n < размера массива, то n будет прибавляться
for (new n = 0; n < array_size; ++n)
// Если элемент массива с n'ой итерацей равен значению которое ищем в элементах массива, вернем элемент массива в котором находиться данное значение.
if (array[n] == search_value)
return n; // Описано выше
return - 1; // Вернем - 1 функцие, дабы знать, что значение в элементах массива не найдено.
}


Пример использования:


new value_array[] = { 8, 16, 24, 30, 36, 42, 38, 56, 64, 70 }; // Массив с целыми числами.



main()
{
// Переменная куда запищеться результат функций (Либо элемент в котором найдено значение, иначе - 1)
new result,
search_number = 36; // Значение которое ищем в массиве
result = SearchValueInElemetsArray(value_array, search_number); // Запишем результат выполнение функций
if(result != - 1) // Если не равно "-1", то функция нашла значение в элементах массива
printf("Значения найдено в элементе %d", result); // Выведем найденое значение на экран
else print("Значение не найдено!"); // Если значение не найдено, то выведем сообщение на экран.
}


P.S: Не советуется использовать для больших массивов, т.к такой метод для них не эффективен!
Автор: Bublik_Public (http://pro-pawn.ru/member.php?3392-Bublik_Public)

Специально для Pro-Pawn.ru (http://pro-pawn.ru)
Копирование данной статьи на других ресурсах без разрешения автора запрещено.

MR_BEN
23.07.2015, 11:23
а разве значение в массиве не может быть отрицательным?

NewGreen
23.07.2015, 14:13
а разве значение в массиве не может быть отрицательным?
Она возвращает не значение, а индекс значения в массиве.
Значение в самом массиве может быть любым.
Опасность здесь в том, что, в Pawn массивы начинаются с 0 до n-1 (так называемый способ «индекс с началом с нуля»), поэтому если пренебречь проверкой на -1 при выполнении функции, может произойти ошибка времени выполнения скрипта в процессе работы вирт. машины Pawn, с сообщением: Run time error 4: "Array index out of bounds"

Daniel_Cortez
23.07.2015, 18:43
Ищет значения в элементах массива
Значения?


search_value - Значение которое хотим найти в массиве.
Парой строк выше вы писали, что функция ищет "значения", т.е. их подразумевалось несколько. Что-то здесь не стыкуется.


дополнительных манипуляций не требуется
Каких ещё манипуляций?


Функция возвращает элемент массива в котором найдено значение, иначе - 1
"Иначе возвращает 1"? И да, элемент - это ячейка массива. Вернуть можно либо её номер, либо хранящееся в ней значение. Что именно возвращает ваша функция?



Если не равно "-1", то функция нашла значение в элементах массива
Определитесь уже, 1 или -1.



элемент массива с n'ой итерацей
"Элемент массива с итерацией"?



result = SearchValueInElemetsArray(value_array, search_number); // Запишем результат выполнение функций
"Функций"? Я вижу тут только одну...


Не советуется
Функция с кем-то должна советоваться?
Обычно, когда нужно проинформировать о чём-то нежелательном, говорят "не рекомендуется".


функцие

запищеться
И всё это вкупе с названиями на кривом английском. Честно, не знаю даже, что и сказать...

Хотя нет, знаю. Один совет: в следующий раз, когда будете что-то выкладывать, дайте проверить свой текст кому-нибудь, кто более-менее знает правила орфографии и пунктуации.
Ну несерьёзно это, публиковать статью, в которой ошибок больше, чем самих слов.

$continue$
23.07.2015, 18:52
Значения?


Парой строк выше вы писали, что функция ищет "значения", т.е. их подразумевалось несколько. Что-то здесь не стыкуется.


Каких ещё манипуляций?


"Иначе возвращает 1"? И да, элемент - это ячейка массива. Вернуть можно либо её номер, либо хранящееся в ней значение. Что именно возвращает ваша функция?


Определитесь уже, 1 или -1.


"Элемент массива с итерацией"?

Элемент массива с nой итерацией, что означает что цикл пройдется по всему массиву.
-1 возвращает, это по-момему явно, не? (Если в элементах массива, не найдено число, которое хотим найти.)
Возвращает элемент массива где хранится, искаемое число

Daniel_Cortez
23.07.2015, 19:07
Элемент массива с nой итерацией, что означает что цикл пройдется по всему массиву.
У элементов массива есть индекс. Понятие "итерация" применимо к циклам, но никак не к массивам.


-1 возвращает, это по-момему явно, не?
Я-то понимаю, но поймут ли другие, кого вы запутаете своим описанием?
И в чём вообще смысл отделять "-" и "1" пробелом? От этого текст должен выглядеть как-то красивее, или что-то ещё?


Возвращает элемент массива где хранится, искаемое число
Опять вы "элемент". Индекс элемента или его значение?

$continue$
23.07.2015, 19:25
У элементов массива есть индекс. Понятие "итерация" применимо к циклам, но никак не к массивам.
А ничего, что цикл есть в функции, Вы не думали что это как раз и применяться к циклу. Цикл сканирует элементы массива, то есть nая итерация, это означает что a[0], оно же может быть и a[10], по-любому, оно не известно программе в каком элементе лежит значение.

Опять вы "элемент". Индекс элемента или его значение?
Что, простите? Возвращает элемент в котором лежит значение, переданное функции.
То есть, например:


a[10] = 36; // Где: a - массив, 10 - элемент массива, не?

Отойдем от Pawn не много:
В С++, sizeof - возвращает не количество элементов, а байты. Что бы, получить количество элементов нужно сделать следующие:


sizeof(array) / sizeof(array[0]) // это приемлемо только для char и стринговых значении. В итоге мы получим количество элементов в массиве.

NewGreen
23.07.2015, 20:38
А ничего, что цикл есть в функции, Вы не думали что это как раз и применяться к циклу. Цикл сканирует элементы массива, то есть nая итерация, это означает что a[0], оно же может быть и a[10], по-любому, оно не известно программе в каком элементе лежит значение.
Что, простите? Возвращает элемент в котором лежит значение, переданное функции.
То есть, например:


a[10] = 36; // Где: a - массив, 10 - элемент массива, не?


"a[0],a[10]" - это два элемента/значения массива,
"0, 10" - это два индекса массива,
"Итерация" - это один шаг цикла, термин применяется только к циклам (в рамках программирования), в области видимости цикла.


...
new a[10];
for(new i = 0; i < 10; i++)
{ // Начало области видимости цикла
printf("Элемент массива- %d, индекс массива - %d",a[i],i); // Функция будет вызвана 10 раз, т.е. циклом будет совершено 10 шагов/итераций
} // Конец области видимости цикла
...

При выполнении пример выше выведет 10 строк, каждая строка - это одна итерация.



Отойдем от Pawn не много:
В С++, sizeof - возвращает не количество элементов, а байты. Что бы, получить количество элементов нужно сделать следующие:


sizeof(array) / sizeof(array[0]) // это приемлемо только для char и стринговых значении. В итоге мы получим количество элементов в массиве.

Что Вы хотели этим сказать ?!

Daniel_Cortez
23.07.2015, 21:17
А ничего, что цикл есть в функции, Вы не думали что это как раз и применяться к циклу. Цикл сканирует элементы массива, то есть nая итерация, это означает что a[0], оно же может быть и a[10], по-любому, оно не известно программе в каком элементе лежит значение.
Ок, посмотрим ещё раз:


Если элемент массива с n'ой итерацей равен значению которое ищем в элементах массива, вернем элемент массива в котором находиться данное значение.
По всем правилам русского языка, слова "итерацией" здесь относится к словосочетанию "элемент массива". Слова "цикл" в предложении нет.
Очевидное решение: просто выражайтесь правильно, здесь нет телепатов, чтобы угадывать, что вы имели в виду на самом деле.
Ещё раз, итерации - к циклам, индексы - к массивам. Не скрещивайте тапки с тараканами.


Что, простите? Возвращает элемент в котором лежит значение, переданное функции.
Элемент - это понятие абстрактное. Это составляющая структуры данных, своего рода контейнер, содержащий значение и имеющий идентификатор (в массиве этим идентификатором является индекс). Ваша же функция возвращает число - индекс элемента в массиве.
Ну хорошо, если, с ваших слов, "функция возвращает элемент массива", как вы представляете, чтобы функция возвращала весь контейнер? Она должна возвращать сразу 2 значения (индекс и значение, хранящееся в элементе) или указатель на элемент?


Отойдем от Pawn не много:
В С++, sizeof - возвращает не количество элементов, а байты. Что бы, получить количество элементов нужно сделать следующие:


sizeof(array) / sizeof(array[0]) // это приемлемо только для char и стринговых значении. В итоге мы получим количество элементов в массиве.

И что вы хотите этим сказать?



a[10] = 36; // Где: a - массив, 10 - элемент массива, не?
a[10] - элемент массива a.
10 - индекс элемента, 36 - его значение после присваивания.
Выучите термины, а потом уже беритесь что-то доказывать.
Вот несколько полезных ссылок:

https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%81%D1%81%D0%B8%D0%B2_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)
https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81_(%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2)
https://ru.wikipedia.org/wiki/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F

MR_BEN
23.07.2015, 21:26
Функция возвращает не элемент массива, а его индекс

$continue$
24.07.2015, 02:31
То есть, тут тоже не верно выведено сообщение на экран? Именно, элемент
http://i.imgur.com/S82gsP9.png
:rtfm::shock::crazy:

Daniel_Cortez
24.07.2015, 03:18
То есть, тут тоже не верно выведено сообщение на экран? Именно, элемент
http://i.imgur.com/S82gsP9.png
:rtfm::shock::crazy:
Скорее всего, просто забыли знак "№" или "#".
Либо пропустили специально, чтобы не путать новичков, и без того слабо разбирающихся в синтаксисе языка (хотели, как лучше, а получилось...)

Mazzilla
24.07.2015, 07:30
Вопрос к знатокам:
будет ли плох вариант с рекурсией?

SearchValueInElemetsArray(array[], search_value, i = 0, array_size = sizeof(array))
{
if(i >= 0 && i < array_size)
{
if(array[i] == search_value)
return i;
else
return SearchValueInElemetsArray(array, search_value, i+1, array_size);
}
else
return -1;
}

Daniel_Cortez
24.07.2015, 17:38
Вопрос к знатокам:
будет ли плох вариант с рекурсией?

SearchValueInElemetsArray(array[], search_value, i = 0, array_size = sizeof(array))
{
if(i >= 0 && i < array_size)
{
if(array[i] == search_value)
return i;
else
return SearchValueInElemetsArray(array, search_value, i+1, array_size);
}
else
return -1;
}

А вы думаете, вариант с насилованием стека должен быть чем-то лучше?

Во-первых, рекурсия в Pawn не нужна абсолютно. Даже компилятор не полностью умеет с ней работать и не способен определить управляемость рекурсии и рассчитать требуемый размер стека.

Во-вторых, сам стек не резиновый, и если не использовать быдлокодерскую #pragma dynamic, его размер так и будет 16Кб (а компилятор и вовсе останется в пролёте: как я уже говорил, он не умеет рассчитывать требования к стеку при рекурсии).
При каждом вызове функции расходуется как минимум 3 ячейки (12 байт) в стеке: передаётся точка возврата (CIP+cellbits/charbits), текущее значение указателя на начало фрейма стека (регистр FRM) и суммарный размер аргументов функции (чем-то напоминает конвенцию вызова cdecl).
Прибавим 4 аргумента из вашей функции и получим 3+4 = 7 ячеек (28 байт).
А теперь рассчитаем максимальное количество рекурсивных вызовов.
Представим, что ваша функция вызывается прямиком из функции main, там всегда самый наименьший расход стека: всего 2 ячейки (8 байт) - функция не принимает аргументов, а потому суммарный размер аргументов не сохраняется в стеке (по сути для main действует отдельная конвенция вызова, по этой же причине это единственная функция, в которой для возврата используется инструкция ret вместо retn).
Итого получаем: (16384 - 8) / 28 = 584 рекурсивных вызова.
Если в массиве будет больше 584 элементов, ваша рекурсия сфейлится из-за переполнения стека.

В-третьих, тратится лишнее время на копирование аргументов через стек и вызов функции из самой себя.
Некоторые компиляторы высокоуровневых языков (MSVC и Clang, например) умеют заменять рекурсию на цикл, но такой фичи нет в компиляторе Pawn. Этот компилятор разрабатывался всего одним человеком и, на момент выхода версии 3.2.3664, всё ещё находился по развитию на уровне 90-х годов. Все его возможности оптимизации ограничены простым asshole peephole optimizer, который заменяет по нескольку инструкций, и то лишь в пределах одного выражения. Говорить об автоматической замене одних конструкций языка другими здесь и вовсе нет смысла.