Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[44.200.122.214] |
|
Сообщ.
#1
,
|
|
|
Как поменять местами элементы матрицы относительно главной диагонали?
Вот полностью коментированая программа, выполняющая нужные нам действия. В ней сначала пользователю предлагается ввести значения элементов матрицы, а затем программа меняет элементы местами. И в конце она выводит результат (матрицу) на экран. 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. А вот та же программа, но в ней пользователю не предлагается ввести значения элементов. За него это делает сама программа с помощью генератора случайных чисел. 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. |
Сообщ.
#2
,
|
|
|
Удаление из матрицы строки или столбца
Ужасные и злобные преподы опять задали неразрешимую задачу? Они угрожающе намекают вам, что без решения задачи с таким условием уже можно просыпаться утром пораньше, чтобы внимательно изучать почитаемую всеми профессию дворника ? Тогда эта тема для вас %)))) Итак вам нужно удалить из матрицы строку или столбец. Как это сделать? Для начала мы определимся, как будет задана у нас матрица. Тут есть два явных варианта: Первый для особо непридирчивых преподов, если вы скажем учитесь на сварщика, и задачу подобного плана вы не увидите больше никогда в жизни, разве что в кошмарах. Тогда мы будем задавать статическую матрицу. Обычно в таких задачах указан размер матрицы. Иногда она бывает квадратной, и её размер часто в условии указывают буквой 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. Таким образом можно удалить из матрицы несколько строк, несколько раз уменьшив эту переменную. И тогда при выводе на экран мы сможем используя эту переменную вывести нужное количество строк. Как видно, данные перемещаются по алгоритму - "Переместить из следующей в предыдущую, перейти в следующую. Повторить пока есть следующая". Такой алгоритм легко реализовать циклом. Вот реализация: 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. Для удаления столбца из матрицы, я надеюсь, вы уже догадались, нужно сделать тоже самое. Тоесть вот такой код: 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-столбец. 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. |
Сообщ.
#3
,
|
|
|
{ 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 == 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 |