Ejercicios de Vectores con Aritmética de Punteros
Insertar Elemento por Posición: Supongamos que tenemos el vector vec, donde cantE es la cantidad total de elementos cargados, TAM es el tamaño máximo del vector, y luego vienen el dato que quiero insertar y la posición.
int cantE = sizeof(vec1)/sizeof(vec1[0]); insertarElem(vec,&cantE,TAM,181,4);
Voy a recibir: vec como puntero, cantE como puntero porque voy a modificarlo, sino se haria una copia y elem y pos como solo voy a usarlos y no necesito modificarlos los paso por copia.
Como voy a insertar en una posición, en el caso de que la cantidad de Elementos que tenga es igual al TAM, voy a perder un elemento, se va a caer del vector.
Entonces, lo que voy a hacer es posicionar el puntero del vector al final, en el caso de que cantE sea igual a TAM lo posiciono uno menos y sino me quedo con la cantE.
Luego hago un for desde el final del vector ( *cantE ) hasta pos-1 decrementando y copiando en vec lo que hay en vec -1 y finalmente copio en vec el elemento que estoy insertando y aumento cantE.
int insertarElem(int *vec,int *cantE,int tam,int elem,int pos)
{
int i;
vec+=(*cantE==tam)?(*cantE)--:*cantE;
for(i=*cantE; i>pos-1; i--)
{
*(vec)=*(vec-1);
vec--;
}
*cantE+=1;
*vec=elem;
return 1;
}
---- es equivalente
int insertarElem(int *vec,int *cantE,int tam,int elem,int pos)
{
int i;
if((*cantE)==tam) // si es igual al tam max significa que voy a descartar uno
{
vec+=(*cantE)-1; // posiciono el puntero del vector en la posicion final
*cantE -= 1; //decremento cantE porque luego voy a incrementarlo al insertarlo
}
else
{
vec+=*cantE; // si no es igual significa que no se va a caer del vector no voy a descartar ninguno
}
for(i=*cantE; i>pos-1; i--)
{
*(vec)=*(vec-1);
vec--;
}
*cantE+=1;
*vec=elem;
return 1;
}
Insertar Elementos de Forma Ordenada
int insertarElemOrd(int *vec,int *cantE,int tam,int elem)
{
int *vecI=vec;
if(*cantE==0)
{
*vecI=elem;
*cantE+=1;
return 1;
}
if(*cantE==tam && elem>=*(vec+*cantE-1))
return 0;
vec+=(*cantE==tam)?--(*cantE):*cantE;
while(elem<*(vec-1) && vecI<vec)
{
*vec=*(vec-1);
vec--;
}
*vec=elem;
*cantE+=1;
return 1;
}
Eliminar Ocurrencias:
printf("Se eliminar %d veces el %d\n",eliminarOcurrencias(vec1,&cantE,3),3);
int eliminarOcurrencias(int *vec,int *cantE,int elim)
{
int *pEsc=vec,*pLec=vec,resto=0;
while((pEsc-vec)<*cantE)
{
while(*pLec==elim)
{
pLec++;
resto++;
}
*pEsc=*pLec;
pEsc++;
pLec++;
}
*cantE-=resto;
return resto;
}
- En insertar por posición, primero fijás el puntero (
vec += ...) y luego ajustás*cantE. Elforse encarga de hacer el corrimiento. - En insertar ordenado, el ajuste de
*cantEtiene que hacerse antes de avanzar el puntero, porque la posición a la que apuntás depende directamente de esa cantidad.
Por eso:
- En un caso (
insertarElem) usás post-incremento de la cantidad, porque lo ajustás al final. - En el otro (
insertarElemOrd) usás pre-decremento, porque necesitás que el nuevo valor ya esté disponible en la expresión del desplazamiento.
Ejercicios:
- Eliminar un elemento de una posición.
- Eliminar la primera aparición.
- Eliminar todas las apariciones.
- Insertar al principio.
- Insertar al final.
- Buscar ordenado.
- Ordenar
int insertarAlPrincipio(int *vec, int *cantE, int tam, int elem) {
int *p;
// Si está lleno, se descarta el último
if (*cantE == tam) {
*cantE -= 1;
}
// p apunta a la última posición ocupada/libre
p = vec + *cantE;
// Corrimiento hacia la derecha
while (p > vec) {
*p = *(p - 1);
p--;
}
// Insertar en la primera posición
*vec = elem;
*cantE += 1;
return 1;
}
int insertarAlFinal(int *vec, int *cantE, int tam, int elem) {
// Si está lleno, descartar el último (opcional: podrías devolver 0)
if (*cantE == tam) {
*cantE -= 1; // hago espacio
}
// Posicionar puntero en la primera posición libre
int *p = vec + *cantE;
// Insertar el elemento
*p = elem;
// Actualizar cantidad
*cantE += 1;
return 1;
}