EnzoFerber
(usa FreeBSD)
Enviado em 14/01/2015 - 09:44h
Opa,
Então, olha o código abaixo, é bem direto e a única parte mais complicada é o merge dos arrays.
Em merge_arrays, dentro dos loops, existem dois ifs(). Um para ver se o numero sendo comparado em B tem semelhante em A. Se tiver, ele quebra o loop (porque se ele é igual, não precisa ser copiado para o novo array). Já o segundo if() testa duas coisas:
1. (b[i] != a[j])
Isso testa se b[i] e a[j] são diferentes. Só que tem um problema, b[i] e a[j] podem ser diferentes, *mas b[i] e a[j+n] podem ser iguais*, o que faria o loop terminar. Então não podemos simplesmente copiar o item para o array a. Temos que saber se *todos* os elementos
de a foram comparados a b[i]. Para isso, fazemos um AND em
2. (j == ARRAY_B - 1))
Ele só vai copiar os valores se j estiver na ultima posicao de A (lembrando que indexes vão de 0 a 4 em um array com 5 elementos). Então, se o loop chegou até j == 4, significa que a primeira condicão (b[i] == a[j] -> break ) não foi satisfeita, e provavelmente agora b[i] é diferente de a[j], então um AND em duas verdades vai avaliar a if como verdadeiro e vai realizar a cópia.
*(a_ref++ ) = b[i];
E o retorno da funcão é o novo tamanho do array A. ele retorna (a_ref - a) = subtracão de dois enderecos (o resultado é o offset entre os dois enderecos, e no nosso caso, exatamente o numero de elementos do array.)
*
O método que utlizei para o merge foi o seguinte: declarei um vetor A com o *dobro* do tamanho de B. Porque? Dessa maneira não preciso declarar um terceiro vetor C para utilizar como merge-point (se A estiver totalemnte cheio e B estiver totalmente cheio, o número total de elementos nos dois arrays será 10, e esse é o tamanho de A. Utilizando o mesmo algoritmo, você pode declarar ARRAY_B como 3 e ARRAY_A com 6. Ou qualquer combinacão de dobra. )Obviamente meu método tem o problema de *perdermos os dados originais de A*, mas se isso não for um problema, torna essa abordagem perfeita para esse caso.
Esse tipo de algoritmo é mais eficiente utilizacão de memória, mas para arrays pequenos ou simples, não faz muita diferenca.
Qualquer dúvida posta denovo,
[]'s
Enzo Ferber
/* vol_forum/ordenacao_vetores.c
*
* Input: 5 numeros em vetor A[10]
* 5 numeros em vetor B[5]
*
* Output:
* Vetor A, com todos os elementos de B que foram repetidos 'merged', e
* com todos os outros elementos concatenados.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define ARRAY_A 10
#define ARRAY_B 5
/* get_array
*/
void get_arrays ( int *a, int *b ) {
/*
* o tamanho de A é tido como 10
* o tamanho de B é tido como 5
*/
register int i;
/* valores para A
*
* Uso a referencia de ARRAY_B pois ele é o menor vetor no programa
* (5 elementos). A tem 10 elementos para o caso de B nao possuir
* nenhum elemento repetido em A.
*/
for ( i = 0; i < ARRAY_B; i++ ) {
printf ( "Valor para A[%d]: ", i );
scanf ( "%d", &a[i] );
}
/* valores para B */
for ( i = 0; i < ARRAY_B; i++ ) {
printf ( "Valor para B[%d]: ", i );
scanf ( "%d", &b[i] );
}
}
/* merge_arrays
*/
int merge_arrays ( int *a, int *b ) {
/*
* parto do principio que A[] terá ARRAY_B elementos,
* (o loop de get_array() força isso).
*/
register int i, j;
int *a_ref = ( a + ARRAY_B );
for ( i = 0; i < ARRAY_B; i++ ) {
for ( j = 0; j < ARRAY_B; j++ ) {
if ( b[i] == a[j] ) break;
if ( (b[i] != a[j]) && (j == ARRAY_B - 1))
*(a_ref++ ) = b[i];
}
}
return ((a_ref) - a);
}
void print_both ( int *a, int *b ) {
register int i;
printf ( "Arrays:\n" );
for ( i = 0; i < ARRAY_B; i++ )
printf ( "A[%d]: %2d\t\tB[%d]: %2d\n", i, a[i], i, b[i] );
}
/* print_a
*/
void print_a ( int *a, int a_size ) {
register int i;
printf ( "\nArray A:\n" );
for ( i = 0; i < a_size; i++ )
printf ( "A[%d]: %d\n", i, a[i] );
return ;
}
void sort ( int *s, int size ) {
register int i, j;
int aux;
for ( i = 0; i < size; i ++ ) {
for ( j = i; j < size; j++ ) {
if ( s[j] < s[i] ) {
aux = s[j];
s[j] = s[i];
s[i] = aux;
}
}
}
}
int main ( void ) {
int a[ ARRAY_A ];
int b[ ARRAY_B ];
int merge_size;
get_arrays ( a, b );
print_both ( a, b );
merge_size = merge_arrays ( a, b );
sort ( a, merge_size );
print_a ( a, merge_size );
return 0;
}
[ vol_forum ] # ./ordenacao_vetores
Valor para A[0]: 5
Valor para A[1]: 4
Valor para A[2]: 3
Valor para A[3]: 2
Valor para A[4]: 1
Valor para B[0]: 7
Valor para B[1]: 6
Valor para B[2]: 5
Valor para B[3]: 4
Valor para B[4]: 3
Arrays:
A[0]: 5 B[0]: 7
A[1]: 4 B[1]: 6
A[2]: 3 B[2]: 5
A[3]: 2 B[3]: 4
A[4]: 1 B[4]: 3
Array A:
A[0]: 1
A[1]: 2
A[2]: 3
A[3]: 4
A[4]: 5
A[5]: 6
A[6]: 7