Вот мои пять центов. :)
#include <stdio.h>
int main(void)
{
int a[] = { 1, 3, 5, 3, 7, 9, 10, 5, 6, 7, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t first = 0, last = 0;
for ( size_t i = 0; i < N - ( last - first ); i++ )
{
size_t j = N;
while ( --j != i && a[j] != a[i] );
if ( j != i )
{
if ( last - first < j - i )
{
first = i;
last = j;
}
}
}
if ( first != last )
{
printf( "%d: ( %zu, %zu )\n", a[first], first, last );
}
return 0;
}
Вывод программы:
1: ( 0, 10 )
Циклы могут быть более оптимизированы, если включить следующее условие
if ( i == 0 || a[i] != a[last] )
для пропуска уже рассмотренных значений.
Вот программа с этим оператором if.
#include <stdio.h>
int main(void)
{
int a[] = { 1, 3, 5, 3, 7, 9, 10, 5, 6, 7, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t first = 0, last = 0;
for ( size_t i = 0; i < N - ( last - first ); i++ )
{
if ( i == 0 || a[i] != a[last] )
{
size_t j = N;
while ( --j != i && a[j] != a[i] );
if ( j != i )
{
if ( last - first < j - i )
{
first = i;
last = j;
}
}
}
}
if ( first != last )
{
printf( "%d: ( %zu, %zu )\n", a[first], first, last );
}
return 0;
}
Вот та же программа, в которую вставлен тестовый вывод для отображения как часто выполняется внутреннее l oop.
#include <stdio.h>
int main(void)
{
int a[] = { 1, 1, 1, 1, 2, 2, 2, 2, 2, 3 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t first = 0, last = 0;
for ( size_t i = 0; i < N - ( last - first ); i++ )
{
if ( i == 0 || a[i] != a[last] )
{
printf( "Inner loop for %d\n", a[i] );
size_t j = N;
while ( --j != i && a[j] != a[i] );
if ( j != i )
{
if ( last - first < j - i )
{
first = i;
last = j;
}
}
}
}
if ( first != last )
{
printf( "%d: ( %zu, %zu )\n", a[first], first, last );
}
return 0;
}
Выход программы:
Inner loop for 1
Inner loop for 2
2: ( 4, 8 )
Таким образом, внутреннее l oop выполняется только два раза.