На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! Правила ЧаВО (FAQ) разделов Паскаля
В этом разделе разрешено создавать только темы, в которых описано РЕШЕНИЕ какой-либо общей проблемы, или описание какого-либо аспекта языка Паскаль.
Обсуждение уже созданных тем разрешено, но только конструктивное, например указание на ошибку или уточнение имеющегося текста.

Стоит почитать Структуры данных
Модераторы: volvo877, Romtek
  
> Задачи по матрицам, Практикум
    Как поменять местами элементы матрицы относительно главной диагонали?

    Вот полностью коментированая программа, выполняющая нужные нам действия.
    В ней сначала пользователю предлагается ввести значения элементов матрицы, а затем программа меняет элементы местами. И в конце она выводит результат (матрицу) на экран.
    ExpandedWrap disabled
      const {Объявим константы}
        n=4; {Размер матрицы}
      var {Объявим переменные}
        m:array[1..n,1..n] of integer;
        {Матрица m - двухмерный массив с шириной и высотой n
         каждый элемент - переменная типа integer}
       
        i,j:byte;
        {Переменные счётчики по вертикали и по горизонтали
         Будут использоваться для заполнения, обмена и вывода элементов матрицы
         тип - byte, потому что матрица не будет больше чем 255x255}
       
        k:integer;
        {Временная переменная k, будет использована для обмена значений элементов
         матрицы}
       
      {---------Начало программы---------}
      begin
        {Сначала заполним матрицу числами}
        for j:=1 to n do {Перебираем строки матрицы}
        for i:=1 to n do {Перебираем столбцы матрицы}
        begin
          write('Введите m(',i,',',j,'): '); {Выводим запрос пользователю}
          readln(m[i,j]); {Читаем с клавиатуры число, и ложим его в соотв. ячейку}
        end;
       
        {Теперь обменяем значения элементов матрицы относительно главной диагонали}
        for j:=1 to n do {Перебираем строки матрицы}
        for i:=1 to j-1 do {Перебираем столбцы матрицы}
        begin {j-1 потому что нам не нужны элементы самой главной диагонали}
          k:=m[i,j]; {Запоминаем значение из нижней левой части матрицы}
          m[i,j]:=m[j,i]; {Меняем его на значение из соотв. верхней правой части}
          m[j,i]:=k; {Меняем значение из верхней правой части на раннее сохранённое}
        end;
       
        {Наконец выведем содержимое матрицы на экран}
        for j:=1 to n do {Перебираем строки матрицы}
        begin
          for i:=1 to n do {Перебираем столбцы матрицы}
            write(m[i,j]:5); {Выведем текущий элемент, расширив его до 5 символов}
          writeln; {Перейдём на новую строку}
        end;
      end.


    А вот та же программа, но в ней пользователю не предлагается ввести значения элементов. За него это делает сама программа с помощью генератора случайных чисел.
    ExpandedWrap disabled
      const {Объявим константы}
        n=4; {Размер матрицы}
      var {Объявим переменные}
        m:array[1..n,1..n] of integer;
        {Матрица m - двухмерный массив с шириной и высотой n
         каждый элемент - переменная типа integer}
       
        i,j:byte;
        {Переменные счётчики по вертикали и по горизонтали
         Будут использоваться для заполнения, обмена и вывода элементов матрицы
         тип - byte, потому что матрица не будет больше чем 255x255}
       
        k:integer;
        {Временная переменная k, будет использована для обмена значений элементов
         матрицы}
       
      {---------Начало программы---------}
      begin
        randomize; {Инициализируем генератор случайных чисел}
       
        {Сначала заполним матрицу числами}
        for j:=1 to n do {Перебираем строки матрицы}
        for i:=1 to n do {Перебираем столбцы матрицы}
          m[i,j]:=random(100); {Генерируем случайное число от 0 до 99, и заносим его в матрицу}
       
        {Теперь обменяем значения элементов матрицы относительно главной диагонали}
        for j:=1 to n do {Перебираем строки матрицы}
        for i:=1 to j-1 do {Перебираем столбцы матрицы}
        begin {j-1 потому что нам не нужны элементы самой главной диагонали}
          k:=m[i,j]; {Запоминаем значение из нижней левой части матрицы}
          m[i,j]:=m[j,i]; {Меняем его на значение из соотв. верхней правой части}
          m[j,i]:=k; {Меняем значение из верхней правой части на раннее сохранённое}
        end;
       
        {Наконец выведем содержимое матрицы на экран}
        for j:=1 to n do {Перебираем строки матрицы}
        begin
          for i:=1 to n do {Перебираем столбцы матрицы}
            write(m[i,j]:5); {Выведем текущий элемент, расширив его до 5 символов}
          writeln; {Перейдём на новую строку}
        end;
      end.
    Сообщение отредактировано: romtek -
      Удаление из матрицы строки или столбца


      Ужасные и злобные преподы опять задали неразрешимую задачу? Они угрожающе намекают вам, что без решения задачи с таким условием уже можно просыпаться утром пораньше, чтобы внимательно изучать почитаемую всеми профессию дворника ?
      Тогда эта тема для вас %))))

      Итак вам нужно удалить из матрицы строку или столбец. Как это сделать?

      Для начала мы определимся, как будет задана у нас матрица.
      Тут есть два явных варианта:
      Первый
      для особо непридирчивых преподов, если вы скажем учитесь на сварщика, и задачу подобного плана вы не увидите больше никогда в жизни, разве что в кошмарах. Тогда мы будем задавать статическую матрицу.
      Обычно в таких задачах указан размер матрицы. Иногда она бывает квадратной, и её размер часто в условии указывают буквой N. Это число обозначает количество элементов по горизонтали и по вертикали. Бывает также, что матрица не квадратная. Тогда тем или иным способом у вас должно быть в условии указаны размеры по горизонтали и по вертикали матрицы. В общем если эти размеры есть, то у вас с вероятностью 80% матрица должна быть объявлена статически.
      Я опущу в этой теме вопросы заполнения матрицы числами, и вывод данных на экран. Об этом можно будет (позже) почитать в одной из тем этого раздела.
      Сразу перейду к способу удаления элемента матрицы:
      Допустим матрица у нас задана как m:array[1..7,1..5] of real;
      Сначала мы должны узнать, какую строку (или столбец) нам следует удалить.
      Попросим пользователя ввести этот номер в переменную k.
      Удаляя строку мы должны добраться до нужной строки в матрице, и все последующие строки после нужной мы будем смещать назад.
      Например были строки такие:
      Цитата
      m 12345
      1 11111
      2 22222
      3 33333
      - эту строку будем удалять
      4 44444
      5 55555
      6 66666
      7 77777

      И нужно удалить строку номер 3.
      Тогда мы переместим данные из строки 4 в строку 3, затем из строки 5 в строку 4, затем из строки 6 в строку 5, после этого из строки 7 в строку 6. И всё. У нас удалятся все данные в строке 3, а все остальные строки сдвинутся. получится так:
      Цитата
      m 12345
      1 11111
      2 22222
      3 44444
      4 55555
      5 66666
      6 77777
      7 77777
      - эти данные нам уже на самом деле не нужны. Но они остались

      После этого размер матрицы по вертикали станет меньше. И поэтому нам нужно при выводе вывести столбцы с первого по 6 а не по 7. Чтобы отслеживать, что у нас уже только 6 столбцов, лучше завести переменную, которая вначале была бы равна размеру матрицы по вертикали, а при удалении строки уменьшалась бы на 1. Таким образом можно удалить из матрицы несколько строк, несколько раз уменьшив эту переменную. И тогда при выводе на экран мы сможем используя эту переменную вывести нужное количество строк.
      Как видно, данные перемещаются по алгоритму - "Переместить из следующей в предыдущую, перейти в следующую. Повторить пока есть следующая".
      Такой алгоритм легко реализовать циклом. Вот реализация:
      ExpandedWrap disabled
        const
          xsize:byte=5;
          ysize:byte=7;
        var
          k:byte;
          m:array[1..ysize,1..xsize] of real;
          ys:byte; {Нам она нужна, чтобы изменить размер матрицы после удаления}
        begin
          write('Введите номер строки, который удалять: ');
          readln(k);
          ... {тут вводим данные матрицы}
          ys:=ysize; {Установим начальное значение для количества строк в матрице}
          for o:=k+1 to ys do {Будем перебирать все строки после удаляемой}
          for p:=1 to xsize do m[o-1,p]:=m[o,p]; {Каждый элемент строки переносим на один вверх}
          dec(ys); {Укажем, что матрица уже на одну строку меньше}
          ... {Тут выводим матрицу}
        end.

      Для удаления столбца из матрицы, я надеюсь, вы уже догадались, нужно сделать тоже самое.
      Тоесть вот такой код:
      ExpandedWrap disabled
        const
          xsize:byte=5;
          ysize:byte=7;
        var
          k:byte;
          m:array[1..ysize,1..xsize] of real;
          xs:byte; {Нам она нужна, чтобы изменить размер матрицы после удаления}
        begin
          write('Введите номер столбца, который удалять: ');
          readln(k);
          ... {тут вводим данные матрицы}
          xs:=xsize; {Установим начальное значение для количества столбцов в матрице}
          for o:=1 to ysize do {Будем перебирать все строки}
          for p:=k+1 to xs do m[o,p-1]:=m[o,p]; {элемент из каждого столбца переносим на один влево}
          dec(xs); {Укажем, что матрица уже на один столбец меньше}
          ... {Тут выводим матрицу}
        end.

      Оба алгоритма можно легко комбинировать, для того, чтобы удалить и строку, и столбец.

      Второй
      для тех преподов, которые почти всегда ходят в шапочке чтобы никто не видел рожек, пробивающихся у них под волосами.
      Такие часто водятся в кафедрах, связанных с компьютерными технологиями, часами сидят под радиационным облучением мониторов, и мутируют, в результате чего приобретают крайне злобное и дотошное отношение к студентам, и их задачам.

      Для таких лучше всего выполнить задачу по полной программе, учитывая все нюансы, связанные с постановкой условия задачи. Так, если в условии написано (цитирую) "удалить из матрицы строку (столбец)...", то мы должны буквально понять это задание, и действительно удалить эту злосчастную строку или столбец. А чтобы можно было именно удалять, нужно матрицу задавать не статически, а динамически.
      Динамическая матрица состоит не из элементов - цифр, как обычная матрица, а из динамически выделяемых в памяти компьютера объектов, которые часто называют нодами. Все эти ноды зацеплены друг за друга, чтобы по одной ноде можно было бы найти следующую. Про ноды скоро можно будет почитать в нашем FAQ в теме Связаные списки В связи с такой организацией матрицы можно действительно удалять отдельные элементы, строки или столбцы матрицы, именно так, как указано в условии задачи.
      Следует заметить, что матрица, организованная на основе связанных списков не является двумерным массивом в понимании языка Pascal (то есть не объявляется как array[1..n,1..k]). Она является лишь образным представлением матрицы, реализованной связанными списками. На этом нюансе садюги-преподы часто заваливают бедного студента. И поэтому им нужно чётко и ясно пояснить, что вы верно выбрали тип организации матрицы, именно потому, что в условии было сказано "удалить строку(столбец)", прибавив, что в статической матрице удалить на самом деле ничего нельзя, так как в действительности строк или столбцов меньше не станет.

      Ну... в общем я уже устал, и не намерен углубляться в структуру связанных списков, и слишком сильно расписывать реализацию удаления строки или столбца из матрицы в этом варианте. Скажу лишь, что основной принцип в том, что нужная строка или столбец действительно удаляются, а связи между элементами матрицы формируются таким образом, как будто удалённой строки или столбца и не было вообще в природе.
      Вот код рабочей программы:
      Цитата
      Нужно составить матрицу , а затем удалить
      из неё i-ю строку и j-столбец.
      ExpandedWrap disabled
        type
          pnode=^tnode;
          tnode=record
           val:integer;
           next:pnode;
          end;
          prow=^trow;
          trow=record
           row:pnode;
           next:prow;
          end;
        var
          matr:prow;
          temprow:prow;
          tempcolumn:pnode;
          xsize,ysize:byte;
          x,y:byte;
         
        procedure showmatrix(matr:prow);
        var temp:pnode;
        begin
          while matr<>nil do
          begin
           temp:=matr^.row;
           while temp<>nil do
           begin
             write(temp^.val:5);
             temp:=temp^.next;
           end;
           writeln;
           matr:=matr^.next;
          end;
        end;
         
        begin
          matr:=nil;
          write('Введите ширину матрицы:');
          readln(xsize);
          write('Введите высоту матрицы:');
          readln(ysize);
          {Формируем динамическую матрицу}
          for y:=1 to ysize do
          begin
           if matr=nil then
           begin
             new(matr);
             temprow:=matr;
           end else
           begin
             new(temprow^.next);
             temprow:=temprow^.next;
           end;
           temprow^.row:=nil;
           for x:=1 to xsize do
           begin
             if temprow^.row=nil then
             begin
               new(temprow^.row);
               tempcolumn:=temprow^.row;
             end else
             begin
               new(tempcolumn^.next);
               tempcolumn:=tempcolumn^.next;
             end;
             tempcolumn^.val:=random(100)-50;
           end;
           tempcolumn^.next:=nil;
          end;
          temprow^.next:=nil;
          writeln('Вот получившаяся матрица:');
          showmatrix(matr);
          writeln('Удалим из неё строку и столбец.');
          write('Введите номер столбца, который следует удалить:');
          readln(xsize);
          write('Введите номер строки, которую следует удалить:');
          readln(ysize);
          {Уберём их}
          y:=1;
          if ysize=1 then matr:=matr^.next;
          temprow:=matr;
          while temprow<>nil do
          begin
           if xsize=1 then temprow^.row:=temprow^.row^.next;
           x:=1;
           tempcolumn:=temprow^.row;
           while tempcolumn<>nil do
           begin
             if x=xsize-1 then
             begin
               tempcolumn^.next:=tempcolumn^.next^.next;
               break;
              end else tempcolumn:=tempcolumn^.next;
             inc(x);
           end;
           if y=ysize-1 then
           begin
             temprow^.next:=temprow^.next^.next;
             inc(y);
           end;
           temprow:=temprow^.next;
           inc(y);
          end;
          writeln('Вот получившаяся матрица:');
          showmatrix(matr);
        end.
      Сообщение отредактировано: volvo877 -
        ExpandedWrap disabled
          { From : Vadim Serov   26.10.97
           Subj : Определение Седловой Точки в Матрице
          }
          const
           MAX=20;
           
          type
           line=Array[1..MAX] of Extended;
           
          var
           smin:Extended;
           imin:Integer;
           i,j,n,m:Integer;
           x:Array[1..MAX] of line;
           buf:line;
           juf:Array[1..MAX] of Integer;
           inp:Text;
           
          begin
           Assign(inp,'matrix.txt');
           Reset(inp);
           Read(inp,n,m);{количество стpок и столбцов}
           if (MAX<n) or (MAX<m) then
            Write('нежелаю считать! ')
           else begin
            for i:=1 to n do
             for j:=1 to m do
              Read(inp,x[i][j]);
           
            for i:=1 to n do begin
             buf[i]:=x[i][1];
             juf[i]:=1;
             for j:=2 to m do
              if buf[i]<x[i][j] then begin
               buf[i]:=x[i][j];
               juf[i]:=j
              end
            end;
            smin:=buf[1];
            for i:=2 to n do begin
             if smin>buf[i] then begin
              smin:=buf[i];
              imin:=i
             end
            end;
           
            Writeln;
            Write('Седловая точка x=',juf[imin],'  y=',imin)
           end;
           Close(inp)
          end.


        == matrix.txt ==
        ExpandedWrap disabled
          5 6
          7 6 6 5 7 15
          6 3 5 1 2 9
          10 5 9 2 3 19
          5 8 1 3 5 6
          10 9 5 6 9 10
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script Execution time: 0,1204 ]   [ 17 queries used ]   [ Generated: 21.10.19, 10:05 GMT ]