Припустимо, що у вас є масив даних і необхідність знайти у ньому певний елемент. Очевидним рішенням в даній ситуації, буде поступовий перебір кожного елементу масиву і порівняння його з певним еталоном. Цей алгоритм і називається лінійний пошук. Ось приклад реалізації на С++, з використанням циклу з передумовою:

const unsgined int N = 100 ; //розмір масиву даних 
char str[N] ; //наш масив даних (в даному випадку масив символів)

//заповнення масиву...

unsigned int i = 0 ; //ітератор для перебору
char c = 'a' ; //еталон пошуку 

while ( (i < N) && (str[i] != с) ) //цикл лінійного пошуку з інваріантою
{ i++ ; } //інкремент ітератора

Найперше, що викликає запитання - це визначена кількість ітерацій, тобто тут можна використати наступний цикл.

const unsgined int N = 100 ; //розмір масиву даних 
char str[N] ; //наш масив даних (в даному випадку масив символів)

//заповнення масиву...

char c = 'a' ; //еталон пошуку

for (unsigned int i=0; i<N; ++i)
{
	if (str[i]==c)
	{ break; }
}

Або ж наш цикл можна записати наступним чином:

//...

for (unsigned int i=0; (i<N) && (str[i]!=c); ++i)
{}

А якщо нам необхідно знайти не один, а усі повторення елементу в масиві? Тобто елемент у масиві може повторятися не один раз. Наприклад, в слові "програмування", букви 'р', 'н' і 'а' зустрічаються по два рази. В такому разі ми можемо інжектувати в наш цикл код обробки знайденого елементу:

const unsgined int N = 100 ; //розмір масиву даних 
char str[N] ; //наш масив даних (в даному випадку масив символів)

//заповнення масиву...

char c = 'a' ; //еталон пошуку, наприклад буква 'а'

for (unsigned int i=0; i<N; ++i)
{
	if (str[i]==c)
	{
		//код обробки знайденого елементу
	}
}

Якщо Ви бажаєте винести алгоритм у функцію чи метод класу, тоді цей метод нам не підійде. Або ж можна оголосити функцію обробки повторення і передавати вказівник на неї функції з алгоритмом пошуку:

void handle (unsigned int pos) //оголошена функція обробки входження з параметром позиції
{
	//код обробки
}

void search_algorithm (char* str, //масив даних у якому відбуватиметься пошук 
							  char c, //шуканий елемент масиву
							  void (*handler)(unsigned int) //функція обробки входження
							  )
{
    unsigned int N = strlen(str) ; //дізнаємося довжину масиву
    
    for (unsigned int i=0; i<N; ++i) //цикл пошуку
    {
	    if (str[i]==c) //перевірка еталону
	    {
		    handler(i) ; //якщо справджується умова - виконати обробку
	    }
    }
}

Найпростіша програма з використанням даного методу може виглядати наступним чином:

#include <iostream> //для виводу на екран
#include <string.h> //функція strlen
using namespace std; //використовуємо простір імен std

void handle (unsigned int pos) //оголошена функція обробки входження з параметром позиції
{
	std::cout << "знайдено за позицією: " << pos << endl ;
}

void search_algorithm (char* str, //масив даних у якому відбуватиметься пошук 
							  char c, //шуканий елемент масиву
							  void (*handler)(unsigned int) //функція обробки входження
							  )
{
    unsigned int N = strlen(str) ; //дізнаємося довжину масиву
    
    for (unsigned int i=0; i<N; ++i) //цикл пошуку
    {
	    if (str[i]==c) //перевірка еталону
	    {
		    handler(i) ; //якщо справджується умова - виконати обробку
	    }
    }
}

const char* message = "Beatifule world" ; //створений і заповнений масив

int main (int argc, char** argv) //головна функція програми
{
    char* str = (char*) message ;  
    char c = 'd' ; //еталон, себто шуканий елемент в масиві
    
    search_algorithm (str, c, &handle) ; //передаємо управління функції пошуку

    return 0 ; //вихід з програми
}

Після виконання її на комп'ютері ми отримаємо наступне:

linear_search_in_2_fcn

Але якщо ви не бажаєте працювати з вказівниками функцій або ж бажаєте створити простішу систему, можна організувати функцію пошуку, яка буде повертати замість одного значення індексу входження елемента, цілий масив індексів входжень. Проста програма з використанням даного методу:


#include  //вивід на екран
#include  //функція strlen
using namespace std; //використовуємо простір імен з iostream

unsigned int* search_algorithm (char* str, char c) //функція пошуку
{
    if (str==NULL) //перевірямо валідність вказівника
    { return NULL ; } //повертаємо вказівник NULL - ознака помилки
    
    unsigned int N = strlen(str) ; //розмір масиву даних
    
    /* Масив індексів входжень у масиві даних.
       Для безпки розглядається найгірша ситуація з точки зору використання
       пам'яті: у масиві усі елементи являються ідентичними еталону пошуку.
    */
    unsigned int *indexes = new unsigned int [N] ;
    
    //записуємо у пам'ять масиву нулі
    memset (indexes, 0, sizeof(unsigned int)) ; 
    
    unsigned int ind_pos = 0 ; /* ітератор масиву індексів */
    
    for (unsigned int i=0; i

Результат виконання програми:

linear_search_one_fcn

Якщо ми не бажаємо використовувати усі ці вказівники на масиви і спростити нашу програму, ми можемо реалізувати функцію з лінійним пошуком, яка повертає лиш індекс входження елементу, а саму функцію помістити в цикл, який буде шукати елемент далі після знайденого входження з наступної після нього позиції. Проста програма з використанням даного методу:


#include  //вивід на екран
#include  //тип string
using namespace std; //використовуємо стандартний простір імен

//проста функція лінійного пошуку повертає найперший індекс входження
//якщо виникла помилка, або елемент не знайдено - повертає 
//значення менше від нуля
int search_algorithm (string str, //наші дані 
                      int pos, //позиція, з якої починати пошук
                      char c //еталон пошуку
                      ) 
{
    if (str.size()<1) //перевіряємо заповненість масиву
    { return (-1) ; } //повертаємо значення (-1) - ознака помилки
    
    unsigned int N = str.size() ; //розмір масиву даних
    
    for (int i=pos; i= 0) //виконуємо пошук
        {
            //виводимо повідомлення
            cout << "елемент '" << c << "' знайдено у позиції " << pos << endl ;
        }
    }
    while ( (pos>=0) && (pos


Результат виконання програми:

linear_search

Час виконання даного алгоритму залежить від місця знаходження шуканого елементу і в найгіршому випадку, алгоритм буде перебирати увесь масив даних.

У бібліотеці STL існує реалізований алгоритм пошуку одного елемента в послідовності даних, у вигляді шаблонної функції. Вона знаходиться в заголовковому файлі algorithm і називається std::find.