Error number one:
for(j=0;j<N;j++) { for(i=i+1;i<N;i++)
Obviously, meant:
for(j=0;j<N;j++) { for(i=j+1;i<N;i++)
Error number two:
if (t=0) C[i-1]=j;
Both of them lead to the fact that the C[] array is not filled at all. And since it is not initialized, any garbage is removed from the stack that it contains.
The first error can be easily detected in the debugger (why don’t I ignore the debugger ??? I don’t understand): when you step through the program, you will immediately see that the loop body is not executed once.
With the second: turn on ALL warnings in the compiler and do not ignore them. For example, gcc -Wall will say:
warning: suggest parentheses around assignment used as truth value if (t=0) C[i-1]=j; ^
Some compilers will say " assignement found in boolean expression ", etc.
Plus - use the "Yoda notation". Such a construction simply will not compile:
if (0=t) C[i-1]=j;
But that is not all. After correcting these errors, the program will not work correctly. Because there are punctures in the search algorithm and in the output of the resulting array. This is how it works:
for( j = 0; j < N; j++ ) { int c = 0; for( i = 0; i < N; i++ ) { if( A[i] == A[j] && i != j ) { c = 1; break; } } if( !c ) C[t++] = A[j]; } for( i = 0; i < t; i++ ) // ограничение - не N! { std::cout << C[i] << " "; }
But keep in mind that the complexity of such an algorithm is quite high and on large volumes it will work for a long time. As an option:
inline static int compareInt( const void * a , const void * b ) { return *(int*)a - *(int *)b; } /* ... */ qsort( A, N, sizeof(A[0]), compareInt ); for( i = 0; i < N; i++ ) { if( i && A[i] == A[i-1] ) continue; if( i != N && A[i] == A[i+1] ) continue; C[t++] = A[i]; } // Всё!
The point is this. First we sort the array. Then we make only one pass on it, comparing each element with the neighbor on the left and the right (for i = 0 exclude the first comparison, for i = N second one). If the neighbors are not equal to our element - it is unique, save it in C[] .
Another option. To memory zhruchy in case of a large scatter of values, but smart.
int t, i, min, max; // Сначала нужно создать массив, в котором будем хранить // счётчики ВСЕХ возможных значений исходного массива. // Конечно, раз уж речь о C++, то можно (и даже нужно) // использовать стандартный плюсовый хэш вместо сишного массива. // Но попробуем и так. // Для начала ищем минимальный и максимальный элементы. min = max = A[0]; for( i = 1; i < N; i++ ) { if( A[i] < min ) min = A[i]; if( A[i] > max ) max = A[i]; } // В t - размер массива для сохранения значений. // Тут небольшая плюшка в случае отрицательных значений, но для // краткости кода просто не будем касаться этого варианта. t = max - min + 1; C = new int[t]; // Теперь просто проходимся по исходному массиву и // увеличиваем счётчик для каждого значения, отсчитывая базу от min: for( i = 0; i < N; i++ ) { C[A[i]-min]++; } // Если счётчик больше 1 - значение не уникально, // если 1 - уникальное, выводим (или делаем что-то ещё), // не забываем прибавить базу: for(i = 0; i < t; i++ ) { if( C[i] == 1 ) { std::cout << (i + min) << " "; } } delete [] C;
And now the same thing, but on "pure" C ++:
std::map<int,size_t> C; for( size_t i = 0; i < N; i++ ) { C[A[i]]++; } for(size_t i = 0; i < C.size(); i++ ) { if( C[i] == 1 ) { std::cout << i << ' '; } }
PS Well, I can not resist, the last algorithm is on a pearl, and for any scalars:
my @A = ( 1,2,'b',4,5,6,'a',8,3,'a',6,9,2 ); my %C; $C{$_}++ for @A; $C{$_} == 1 && print "$_\n" for keys %C; # Всё :-)
for(i=i+1;i<N;i++). Then here:if(t=0). And a hundred times a hundred times: a few knots on the keys in the debugger, and you would see it yourself. So first fix the obvious splash, then - in the debugger. - user6550