Wear a helmet. Even when coding.

exercises > unsorted-array-search

Exercise #5: Finding a Value in an Unsorted Array
by Zoran Horvat @zoranh75
April 21, 2013

Problem Statement

Given an unsorted array of N integers (N > 0) and an integer value v, write the function that returns zero-based index in the array at which the value v is located. Function should return negative value if array does not contain v. In case that there are multiple occurrences of v within the array, return smallest index at which v occurs.

Example 1: Suppose that array is: 7, 2, 6, 1, 8, 4, 5. For v=6 function returns 2. For v=3, function returns negative value (e.g. -1).

Keywords: Array search, index of value, index in array.

Problem Analysis

Searching through an unsorted array looks like a simple task - we just iterate through the array and return an element index as soon as the match is found. Alternatively, if end of array is reached, failure status is returned. Here is the pseudocode of the function:

function Search(a, v)
    a - array containing n elements
    v - value to be found in the array

    for i = 0 to n - 1
        if a[i] = v then
            return i

    return -1


Now that we have the straight-forward solution, we can think of some improvements. To see the enhancement, we should observe the loop, which is the most demanding part of the function. Try to count operations that must be executed in order to complete the loop.

Here is the loop from the function above, stripped to the level of most basic instructions:

i = 0
loop: if i >= n then jump out
      if a[i] != v then jump next
      return i
next: i = i + 1
      jump loop
out:  return -1

This reveals that loop consists of two conditional jumps, one unconditional jump, one increment operation and one return statement. Note that return statement is executed at most once, so it can be dropped from this analysis. The heaviest instructions in the loop are three jumps and the increment operation. Now we should figure out how to eliminate at least one of these instructions. First conditional jump tests whether end of the array has been reached. Second conditional jump tests whether requested element was found in the array. Increment instruction is executed in order to move forward through the array. Finally, unconditional jump is executed to return back to the beginning of the loop block. Which one can be removed?

Increment operation cannot be removed simply because we have to progress through the array, as well as the unconditional jump at the end of the loop block. Conditional jump which tests array elements is also mandatory because we do not know which element equals the requested value, if any. Finally, conditional jump which tests whether we have stepped out of the array is the last resort. That statement is present because we do not know whether we are still within bounds of the array or not. In order to remove that statement from the array, we must ensure that we never exit the array, which can only happen if requested value exists somewhere inside it - condition which is not guaranteed in advance. However, we can fix that condition: just put the requested value at the end of the array and we have eliminated the need to test whether we have iterated outside bounds of the array. Here is the modified implementation:

tmp = a[n - 1]
a[n - 1] = v

pos = 0
while a[pos] != v
    pos = pos + 1

a[n - 1] = tmp

if a[pos] = v then
    return pos
return -1

In this way, we have tweaked the system which we are examining (array in this case). Modified system better suits our needs and lets us write more efficient solution. However, once the loop is executed, we must return the array in the original state. Only after that is accomplished can we test whether the requested element was found in the array or not and, depending on the outcome, return one result or the other.


Here is the C# implementation of enhanced searching function:

int Search(int[] array, int v)

    int tmp = array[array.Length - 1];
    array[array.Length - 1] = v;

    int pos = -1;

    while (array[++pos] != v);

    array[array.Length - 1] = tmp;

    if (array[pos] == v)
        return pos;
    return -1;


This function is faster than the simple implementation:

int SearchSlow(int[] array, int v)
    for (int i = 0; i < array.Length; i++)
        if (array[i] == v)
            return i;
    return -1;

When performance of these two functions is compared on very large arrays, containing millions of numbers, the first implementation runs in time by 25% shorter than time required by the "slow" function to complete. Same results are obtained when value is present in the array, as well as in cases when array does not contain the requested value. This proves the thesis that we have actually saved one out of four instructions in the loop by removing the array bounds test.


Here is the complete console application which can be used to demonstrate how Search function works:

using System;

namespace ArraySearch
    class Program
        static Random _rnd = new Random();

        static int[] Generate(int n)
            int[] a = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = _rnd.Next(100);
            return a;

        static int Search(int[] array, int v) { ... }

        static void Main(string[] args)
            while (true)
                int n = int.Parse(Console.ReadLine());
                if (n <= 0) break;

                int v = int.Parse(Console.ReadLine());

                int[] a = Generate(n);
                int pos = Search(a, v);

                if (pos < 0)
                    Console.Write("{0} not found in array ", v);
                    Console.Write("{0} found at position {1} in array ", v, pos);

                for (int i = 0; i < a.Length; i++)
                    Console.Write("{0,5}", a[i]);



            Console.Write("Press ENTER to continue... ");


And here is the output produced when this application was run:

10 not found in array    19    0   12   18    9   18   14    9    1   11
12 found at position 13 in array     0   13    9    4   19   17    9    5   10   15
                                    15    9    6   12   17    5   17
19 found at position 12 in array    13   13   11   17    3    4    3    2    4    5
                                    18    9   19    0
18 found at position 2 in array    11   12   18   18   17    9
14 not found in array     0    3   11   13    5    3    0    1    5
17 not found in array     0   10    4   16   18
Press ENTER to continue...

See also:

Published: Apr 21, 2013


Zoran is software architect dedicated to clean design and CTO in a growing software company. Since 2014 Zoran is an author at Pluralsight where he is preparing a series of courses on object-oriented and functional design, design patterns, writing unit and integration tests and applying methods to improve code design and long-term maintainability.

Follow him on Twitter @zoranh75 to receive updates and links to new articles.

Watch Zoran's video courses at (requires registration):

Making Your C# Code More Object-Oriented

This course will help leverage your conceptual understanding to produce proper object-oriented code, where objects will completely replace procedural code for the sake of flexibility and maintainability. More...

Advanced Defensive Programming Techniques

This course will lead you step by step through the process of developing defensive design practices, which can substitute common defensive coding, for the better of software design and implementation. More...

Tactical Design Patterns in .NET: Creating Objects

This course sheds light on issues that arise when implementing creational design patterns and then provides practical solutions that will make our code easier to write and more stable when running. More...

Tactical Design Patterns in .NET: Managing Responsibilities

Applying a design pattern to a real-world problem is not as straight-forward as literature implicitly tells us. It is a more engaged process. This course gives an insight to tactical decisions we need to make when applying design patterns that have to do with separating and implementing class responsibilities. More...

Tactical Design Patterns in .NET: Control Flow

Improve your skills in writing simpler and safer code by applying coding practices and design patterns that are affecting control flow. More...

Writing Highly Maintainable Unit Tests

This course will teach you how to develop maintainable and sustainable tests as your production code grows and develops. More...

Improving Testability Through Design

This course tackles the issues of designing a complex application so that it can be covered with high quality tests. More...

Share this article