[ Foro de Pascal ]

desplazar en matriz

27-Mar-2014 21:31
Invitado (loren99)
15 Respuestas

hola buenas amigos, alguien podria decirme como puedo desplazar cada elemento de una matriz ingresa por teclado, una posicion adelante. cualquier ayuda es importante para avanzar gracias


28-Mar-2014 19:48
Nacho Cabanes (+83)

Mira el apartado 4.1.6 de la nueva versión del curso:
http://www.nachocabanes.com/pascal/cupas5/cupas04.php


28-Mar-2014 20:21
Invitado (loren99)

profesor no entiendo alli se habla de insertar y borrar elementos en un vector, yo necesito es como rotar cada elemento de la matriz una posicion adelante, si puedes ayudarme u orientarme estare muy agradecida.


28-Mar-2014 23:37
Nacho Cabanes (+83)

Es que hasta ahora no habías hablado de rotar, sino de desplazar hacia adelante, que es lo que se hace cuando se inserta un valor.

En cualquier caso, las ideas básicas no son muy distintas: tendrás que llevar el elemento 2 a la posición 3 (guardando en una variable auxiliar lo que antes contenía esa posición 3), luego llevar lo de la posición 3 (que está en tu variable auxiliar) a la 4, de la 4 (ídem) a la 5, de la 5 a la 6... de la última a la primera, y de la primera a la segunda. Es un proceso claramente repetitivo, que puedes hacer con único "for" y una variable auxiliar en la que guardas cada dato que vas a sobreescribir porque otro dato anterior va a ocupar su lugar.


02-Apr-2014 17:12
Invitado (loren99)

buenas, profesor podrias indicarmelo a traves de codigo, muy amable, esperaba tu respuesta


02-Apr-2014 17:31
Invitado (loren99)

es que yo intento hacerlo convirtiendo la matriz dada en un vector y sobre el hacer la rotacion, pero queria saber si puedes facilitarme un codigo que pueda hacer las rotaciones directamente operando la matriz, sin ayuda de un vector auxiliar, ojala puedas ayudame con ello es urgente para mi, pues me preparo para un examen.gracias


02-Apr-2014 17:33
Nacho Cabanes (+83)

Dame más detalles. Pon un ejemplo de cómo sería tu matriz inicial y en qué debería convertirse tras la rotación, para que pueda ver exactamente a lo que te refieres.


02-Apr-2014 19:37
Invitado (loren99)

buenas, profesor mira un ejemplo es:


    sea la matriz  A=  1   2   3
                                  4   5   6
                                  7    8  9

el resultado debe ser la matriz :
                                   9     1    2
                                   3     4    5
                                   6     7    8

me gustaria si puediera ser operando la matriz ingresada para llegar a la matriz resultado, es decir sin utilizar quiza un vector auxiliar. gracias por que espero tu respuesta y ayuda.

               


03-Apr-2014 09:40
Nacho Cabanes (+83)

Ok, vamos a hacerlo en dos pasos. Primero, cómo sería para una matriz de una dimensión (un vector):


program RotarVector;

const
    maximo = 5;
    matriz: array[1..maximo] of integer = (5,6,7,8,9);
    
var
    i, temporal: integer;   { Contadores para bucles }
    
begin
    { Mostramos los matrizs }
    for i := 1 to maximo do
        write(matriz[i], ' ');
    writeLn;

    { Recolocamos, rotando hacia atrás }
    temporal := matriz[1];
    for i := 1 to maximo-1 do
        matriz[i] := matriz[i+1];
    matriz[maximo] := temporal;
    
    { Mostramos los matrizs nuevamente, para ver resultado }
    for i := 1 to maximo do
        write(matriz[i], ' ');
    writeLn;
end.


El resultado es


5 6 7 8 9 

6 7 8 9 5 


Fácil, ¿verdad?

Pues para una matriz bidimensional, se podría plantear exactamente de la misma forma, "pensando" con coordenadas lineales, pero convirtiendo a coordenadas bidimensionales usando "div" para adivinar la fila y "mod" para adivinar la columna:


program RotarMatriz;

const
    maximo = 3;
    matriz: array[1..maximo,1..maximo] of integer = (
        (1,2,3),
        (4,5,6),
        (7,8,9)
    );
    
var
    i, temporal: integer;   { Contadores para bucles }
    fila, columna, fila2, columna2: integer;   { Para conversion a 2D }
    
begin
    { Mostramos los datos }
    for fila := 1 to maximo do
        begin
        for columna := 1 to maximo do
            write(matriz[fila,columna], ' ');
        writeLn;
        end;

    { Recolocamos, rotando hacia atrás }
    temporal := matriz[1,1];
    for i := 1 to maximo*maximo-1 do
        begin
        fila := i div maximo;
        columna := i mod maximo;
        fila2 := (i+1) div maximo;
        columna2 := (i+1) mod maximo;
        matriz[fila, columna] := matriz[fila2, columna2];
        end;
    matriz[maximo,maximo] := temporal;
    
    { Mostramos los datos nuevamente, para ver resultado }
    for fila := 1 to maximo do
        begin
        for columna := 1 to maximo do
            write(matriz[fila,columna], ' ');
        writeLn;
        end;
end.


El resultado es


1 2 3 
4 5 6 
7 8 9 

2 3 4 
5 6 6 
7 8 1 


La alternativa es llenar el programa de múltiples "if" para avanzar "a mano" a la posición [2,1] después de la [1,3], pero resultaría mucho menos legible. Es preferible familiarizarse con "div" y "mod".

En tu caso, quieres rotar "hacia delante", no hacia atrás", pero eso ya casi lo tienes: basta con que memorices el elemento de la posición [3,3] para finalmente guardarlo en la [1,1] y que a cada valor intermedio le asignes el que tenía su posición precedente (i-1), en vez de la posterior.


03-Apr-2014 23:00
Invitado (loren99)

hola profesor, gracias ante todo, disculpa un poco que no me aclaro en dos cosas:
1. en este caso se esta rotando cada elemento , es que no entiendo por que en tu ejemplo de solucion te da:

                                 2 3 4
                                 5 6 6
                                 7 8 1

no deberia ser:

                                2  3  4
                                5  6  7
                                8  9  1

ahora si estoy en lo correcto en este caso estaria solo la primera pasada, pues segun mi seguimiento serian en total 8 pasads hasta llegar  ala matriz final donde cada elemento ha sido "rotado", como podria hacer para hacer las restantes 7 pasadas, que me sugieres.
ahora bien hablamos de rotar pero en verdad seria desplazar por que rotar y me corriges seria en caso que se hiciera en base a algun eje no se, agradezco todo lo que me puedas ayudar para entender y culminar el ejercicio.


04-Apr-2014 00:51
Nacho Cabanes (+83)

Es cierto, deformación profesional, por trabajar sobre todo con lenguajes "tipo C", en los que se empieza a contar en 0, de modo que en la posición "2" (la tercera, al final de la primera fila) se obtiene que "n div 3" vale 0 (la primera fila) y "n mod 3" vale 2 (la tercera columna).

Para Pascal, empezando a contar en 1, habría que sumar 1 a la fila y la columna obtenida, y, en ese caso, empezar a contar en 0.

El fuente quedaría así:


program RotarMatriz;

const
    maximo = 3;
    matriz: array[1..maximo,1..maximo] of integer = (
        (1,2,3),
        (4,5,6),
        (7,8,9)
    );
    
var
    i, temporal: integer;   { Contadores para bucles }
    fila, columna, fila2, columna2: integer;   { Para conversion a 2D }
    
begin
    { Mostramos los datos }
    for fila := 1 to maximo do
        begin
        for columna := 1 to maximo do
            write(matriz[fila,columna], ' ');
        writeLn;
        end;

    { Recolocamos, rotando hacia atrás }
    temporal := matriz[1,1];
    for i := 0 to maximo*maximo-2 do
        begin
        fila := i div maximo + 1;
        columna := i mod maximo + 1;
        fila2 := (i+1) div maximo + 1;
        columna2 := (i+1) mod maximo + 1;
        writeLn('Pasada ',i,': ',  { Info de depuracion }
            'moviendo a ',fila,' ',columna, 
            ' desde ',fila2, ' ',columna2);
        matriz[fila, columna] := matriz[fila2, columna2];
        end;
    matriz[maximo,maximo] := temporal;
    
    { Mostramos los datos nuevamente, para ver resultado }
    for fila := 1 to maximo do
        begin
        for columna := 1 to maximo do
            write(matriz[fila,columna], ' ');
        writeLn;
        end;
end.


y su resultado, con más información en pantalla, para que veas los pasos que da, sería:


1 2 3 
4 5 6 
7 8 9 
Pasada 0: moviendo a 1 1 desde 1 2
Pasada 1: moviendo a 1 2 desde 1 3
Pasada 2: moviendo a 1 3 desde 2 1
Pasada 3: moviendo a 2 1 desde 2 2
Pasada 4: moviendo a 2 2 desde 2 3
Pasada 5: moviendo a 2 3 desde 3 1
Pasada 6: moviendo a 3 1 desde 3 2
Pasada 7: moviendo a 3 2 desde 3 3
2 3 4 
5 6 7 
8 9 1 

04-Apr-2014 09:57
Invitado (loren99)

estupendo profesor nacho, bien una cosa final profesor, deberia realizar un for mas externo para las demas pasadas? o un repeat con que condicion? pues recuerda que al resultado final que se desea llegar es a:
                                  9     1    2
                                  3     4    5
                                  6     7    8

mil gracias por estar en esta labor tan digna de enseñar.


05-Apr-2014 14:16
Nacho Cabanes (+83)

No necesitas nada más. Si "piensas en coordenadas lineales", te basta con un único "for", como en mi ejemplo. Sólo necesitas mover en el sentido contrario al que yo lo he hecho, pero eso ya es fácil. ;-)


08-Apr-2014 15:09
Invitado (loren99)

hola profesor, mira es que intento hacer las modificaciones que me indicaste pero el resultado no es satisfactorio y te pido el favor me indiques mis errores pues los mensajes de movimientos si que me salen correctos pero en la impresion de la matriz no me resulta.


program RotarMatriz;
 uses crt;
const
    maximo = 3;
    matriz: array[1..maximo,1..maximo] of integer = (
        (1,2,3),
        (4,5,6),
        (7,8,9)
    );
 
var
    i, temporal: integer;   { Contadores para bucles }
    fila, columna, fila2, columna2: integer;   { Para conversion a 2D }
 
begin
clrscr;
    { Mostramos los datos }
    for fila := 1 to maximo do
        begin
        for columna := 1 to maximo do
            write(matriz[fila,columna], ' ');
        writeLn;
        end;
 
    { Recolocamos, rotando hacia atrás }
    temporal := matriz[maximo,maximo];
    for i := 0 to maximo*maximo-2 do
        begin
        fila := (i+1) div maximo+1  ;
        columna := (i+1) mod maximo+1 ;
        fila2 := (i) div maximo+1 ;
        columna2 := (i) mod maximo+1 ;
        writeLn('Pasada ',i,': ',  { Info de depuracion }
            'moviendo a ',fila,' ',columna, 
            ' desde ',fila2, ' ',columna2);
        matriz[fila, columna] := matriz[fila2, columna2];
        end;
    matriz[1,1] := temporal;
 
    { Mostramos los datos nuevamente, para ver resultado }
    for fila := 1 to maximo do
        begin
        for columna := 1 to maximo do
            write(matriz[fila,columna], ' ');
        writeLn;
        end;
readln;		
end.



10-Apr-2014 09:36
Nacho Cabanes (+83)

No puedo probarlo ahora, que no tengo una computadora delante, sino un tablet, pero ten en cuenta que no podrás "mover datos hacia la derecha" a la vez que avanzas hacia la derecha, porque de lo contrario, el dato [1,1] destruirá el dato [1,2] y luego el [2,3] y así sucesivamente.

Si mueves datos hacia la derecha, deberías usar un "for" descendente, para retroceder desde el final del array.

Ante la duda, prueba primero con un vector unidimensional, para ayudarte a entender los pasos que estás dando y lo que provocan.


10-Apr-2014 10:50
Invitado (loren99)

ok, gracias profesor






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)