Помощь - Поиск - Пользователи - Календарь
Полная версия: Перестановка столбцов
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Определение столбца.............
Помогите пожалуйста
Вот такая задача
Я нашел число нулевых элементов в каждом столбце(ch[j])
И теперь мне надо найти столбец в котором больше всего нулевых элементов.?
Дож
Допустим вот так:


Var i,max,temp : integer;
.......................
.......................
i:=0{или -1, с чего начинается твой массив?}
While i<>columnNum do begin
i:=i+1;
If ch[i]>temp then begin
temp:=ch[i];
max:=i;
end;
end;



А вообще про массивы написано в FAQ.
Serega18
подЗадача:Поставить на первое место столбец с наименьшим количеством нулевых элементов .
Есть матрица A[i,j] и число нулевых элементов в столбце пусть num[j]
Вот как сделал я
Код
Procedure resort(var a:matrix;var num:integer);
Var i,j:integer;
Begin
for i:=1 to 5 do
 Begin
  For j:=1 to 5 do
   Begin
    IF num[1]>num[j]
     A[i,1]:=A[i,j];
     A[i,j]:=A[1,1];
   end;
  end;
end;

Что здесь не так?
volvo
:no: Ты должен сначала определить, в каком столбце число нулевых элементов минимально, а уже потом менять этот столбец с первым...

Чтобы это сделать одним оператором, нужно определить матрицу по-другому: FAQ: Как задать матрицу чтобы ...
Serega18
Faq прочел ниче не понял.
А чтобы найти столбец с наименьшим число нулевых элементов пойдет вот так:

Код
Procedure(var A:matrix,var num:integer);
var i,j:integer;
  begin
   j:=0
     for i:=1 to 5 do
      begin
        for j:=1 to 5 do
          begin
            if num[j]<min then
               min:=num[j];
            end;
        end;
  end;
volvo
Не пойдет... У тебя это даже не скомпилируется ... Ты передаешь Num как Integer, а внутри процедуры обращаешься к нему как к массиву... Это как понять?
Serega18
FА если у меня num будет одномерным массивом

Код
Procedure(var A:matrix,var num:odn);
var i,j:integer;
 begin
  j:=0
    for i:=1 to 5 do
     begin
       for j:=1 to 5 do
         begin
           if num[j]<min then
              min:=num[j];
           end;
       end;
 end;
volvo
Function min_nulls(var A:matrix): integer;
var
i, j: integer;
min, indx, count: integer;
begin
min := 5;
for i := 1 to 5 do begin
count := 0;
for j := 1 to 5 do
if A[j, i] = 0 then inc(count)
if min > count then begin
min := count; indx := i
end;
end;
min_nulls := indx
end;

Эта функция возвращает номер столбца, в котором число нулевых элементов минимально... И не надо ничего делать перед этим, никаких подсчетов :P
Serega18
count,indx -а что это такое?
volvo
Переменные, что еще? blink.gif Count считает сколько в текущем столбце нулевых элементов, indx - запоминает номер того, где их меньше... В результате в indx и остается индекс столбца с минимальным количеством нулей ...
Serega18
Значит при перестоновке поставить indx



Код
Procedure resort(var a:matrix;var num:integer);
Var i,j:integer;
Begin
 for i:=1 to 5 do
  Begin
    For j:=1 to 5 do
     Begin
       IF num[1]>num[j]
         A[i,1]:=A[i,indx];
         A[i,indx]:=A[1,1];
    end;
 end;
end;
volvo
Да что тебя так тянет на этот NUM?
Procedure resort(var a:matrix; indx: integer);
Var i, T:integer;
Begin
if indx <> 1 then
for i := 1 to 5 do begin
T := a[i, 1]; a[i, 1] := a[indx, 1]; a[indx, 1] := T
end;
end;

Вот и все...
и вызывать вот так:
begin
...
resort(A, min_nulls(A)); { это вся работа }
end.

После этого только распечатать...
Serega18
Спасибо :molitva: (А как во внутренней спецификации описать Т unsure.gif )
volvo
Цитата(Serega18 @ 15.05.05 23:09)
А как во внутренней спецификации описать Т

Во внутренней спец... чего? blink.gif Ты с кем это разговаривал в предыдущем посте? Какая еще внутренняя спецификация?

"Т" у меня - буферная переменная для обмена значений...
Serega18
Появился еще один вопрос:
А что если после нахождения столбца с наименьшим количеством нулевых элементов мне надо менять элементы в столбце,а не менять местами столбцы,
например поставить все нули в конец столбца .
Мой вариант:
Код
Procedure t(var a:matrix; indx:integer);
Var i,n:integer;
Begin
n:=0
for i:=1 to 5 do
   Begin
      IF A[i,indx]=0 then
        T:=A[5-n,indx]
        A[5-n,ind]:=A[i,indx];
        A[i,indx]:=T;
        n:n+1;
   end;
end;
volvo
       IF A[i,indx]=0 then
T:=A[5-n,indx]
A[5-n,ind]:=A[i,indx];
A[i,indx]:=T;
n:n+1;

это не будет работать...
Begin ... End забыл. Кроме этого, зачем работать со значением A[i, indx], если ты только что выяснил, что оно равно 0? blink.gif
Serega18
Код
 IF A[i,indx]=0 then
       T:=A[5-n,indx]
       A[5-n,ind]:=A[i,indx];
       A[i,indx]:=T;
       n:=n+1;

Условие-то что i-тый элемент в столбце indx =0
Затем я T -присваиваю последний элемент в столбце
и меняю i-тый элемент который равен нулю с последним

Цитата
Кроме этого, зачем работать со значением A[i, indx], если ты только что выяснил, что оно равно 0?

Я пытаюсь нулевой элемент переставить в конец,для этого A[i, indx] должен быть равен нулю
volvo
Вот только не говори мне, что этот код НЕ эквивалентен твоему:
IF A[i,indx]=0 then begin
A[i,indx]:=A[5-n,indx];
A[5-n,indx] := 0;
n:=n+1;
end;

T - "лишняя" переменная... Будь внимательнее
Serega18
А почему T лишняя? (я думал что для перестановки двух элементов всегда нужна переменная)
Дож
Естественно, нет...

Это
Код

k:=a;
a:=b;
b:=k;


можно заменить на то:
Код

a:=a+b;
b:=a-b;
a:=a-b;
volvo
Дож
Во-первых, речь не об этом, а о том, что если значение одной переменной известно (= 0), то можно обойтись без буферной переменной...
А во-вторых, я уже выкладывал результаты теста, где сравнивал 3 способа обмена... И результат - далеко не в пользу твоего метода :no:
Serega18
Решил собрать все подзадачи в одну и используя текстовый файлы составить задачу.Но так как с текстовыми файлами я некогда не работал ни чего не вышло.
Поставить на первое место столбец с наименьшим количеством нулевых элементов,поставив все нули в конец этого столбца.
Исходный код
Program St;
Uses crt;
Type Matrix=array[1..4,1..5] of real;
var a:Matrix;
i,j,indx:integer;
f1,f2:text;
Procedure chislo(var A:matrix);
var i,j,ch:integer;
Begin
ch:=0;
For i:=1 to 4 do
Begin
For j:=1 to 5 do
Begin
IF A[i,j]=0 Then
ch:=ch+1;
end;
end;
end;
Function min_nulls(var a:matrix):integer;
var i,j:integer;
min,indx,count:integer;
Begin
min:=5;
for j:=1 to 5 do
Begin
count:=0;
for i:=1 to 4 do
if A[i,j]=0 then
inc(count);
If min>count then
Begin
min:=count;
indx:=j;
end;
end;
min_nulls:=indx;
end;
Procedure resort(var A:matrix;indx:integer);
Var i:integer;
T:real;
Begin
If indx<>1 then
for i:=1 to 4 do
Begin
T:=A[i,1];
A[i,1]:=A[i,indx];
A[i,indx]:=T;
end;
end;
Procedure ST(var A:matrix;indx:integer);
Var i,j,n:integer;
Begin
n:=0;
for i:=1 to 4 do
Begin
IF A[i,indx]=0 then
Begin
A[i,indx]:=A[5-n,indx];
A[5-n,indx]:=0;
n:=n+1;
end;
end;
end;
Begin
assign(f1,'isdan.pas');
assign(f2,'vdan.pas');
reset(f1);
rewrite(f2);
Begin
for i:=1 to 4 do
Begin
For j:=1 to 5 do
read(f1,A[i,j]);
end;
writeln(f2);
end;
Begin
clrscr;
chislo(A);
min_nulls(A);
resort(A,indx);
St(A,indx);
readln;
end;
end.
volvo
Опять велосипед изобретаем? Ну-ну... Что за смысл вкладывался в ПРОЦЕДУРУ:
Procedure chislo(var A:matrix);
var i,j,ch:integer;
Begin
ch:=0;
For i:=1 to 4 do Begin
For j:=1 to 5 do Begin
IF A[i,j]=0 Then ch:=ch+1;
end;
end;
end;

Я не вижу в ней смысла. Если можно, с комментариями !!!
Serega18
Найти нул элементы в каждом столбце
Может так
Код
Procedure chislo(var A:matrix);
var i,ch:integer;
Begin
ch:=0;
For i:=1 to 4 do
  Begin
    for j:=1 to 5 do
     Begin
       IF A[i,j]=0 Then
         ch[j]:=ch[j]+1;
     end;
  end;
end;
volvo
Прочти теорию сначала, а потом уже начинай программировать, хорошо? Ты вообще представляешь, что ты от компилятора просишь? Обращаться к Integer как к массиву целых - это невозможно ... Кроме того, ты должен получать результат подсчета, что в случае с процедурой возможно только через Var-параметры, а Var-параметр у тебя только один - сама матрица.

Я кстати не зря попросил "с комментариями"... Когда комментируешь чего ты ХОЧЕШЬ добиться и пишешь код - ошибки видны как на ладони. Но ты, я вижу это просто проигнорировал... So Am I... :yes:
Дож
Цитата(volvo @ 16.05.05 20:14)
Во-первых, речь не об этом, а о том, что если значение одной переменной известно (= 0), то можно обойтись без буферной переменной...


Когда значение одной переменной известно, то все естественно проще...

Цитата(volvo @ 16.05.05 20:14)
А во-вторых, я уже выкладывал результаты теста, где сравнивал 3 способа обмена... И результат - далеко не в пользу твоего метода


Я и не говорю, что это лучший метод... :no: Я всегда пользуюсь буфферной переменной.
Serega18
Присваиваю ch тип odn(одномерный массив),А-matrix
проц-задаю матрицу А и одномерный массив ch затем беру начальное число нул элементов,тоесть ноль(ch:=0),дальше условие(если элемент матрицы равен нулю,то число нул элементов увеличивается на один).
Код
Program St;
Uses crt;
Type Matrix=array[1..4,1..5] of real;
Odn=array[1..5] of real;
var a:Matrix;
    ch:odn;
i,j,indx:integer;
f1,f2:text;
Procedure chislo(var A:matrix;ch:odn);
var i,j,:integer;
Begin
ch:=0;
For i:=1 to 4 do
 Begin
  For j:=1 to 5 do
   Begin
    IF A[i,j]=0 Then
     ch[j]:=ch[j]+1;
   end;
 end;
VDmV
Извиняюсь что вклиниваюсь, но я не могу на енто смотреть меня переполняют эмоции. Ещё раз извиняюсь.
Цитата
Найти нул элементы в каждом столбце
Может так

Нет не так.
1) ch:integer; //Ладно, а вот это что ch[j]:=ch[j]+1. Ты бы попробовал этот код в деле. У тебя ошибка совместимомсти типов. И как сказал volvo - в этой процедуре нет смысла всё равно.
2) Я так понял тебе нужно определить координаты всех нулей и затолкать их массив. Проще простого:
Код

procedure Chislo(var a:matrix; var b:array [1..5] of integer {этот массив будет хранить номера строк, которые на пресечении с i столбцом значение =0.});
var
 i,j:integer;
begin
 for i:=1 to 5 do
   for j:=1 to 4 do
   if a[j,i]=0 then
     b[i]:=j;
end;

Вот и всё. Зачем тебе это надо - это другой вопрос.

Добавлено позже: Похоже последние 4 поста были посланы почти одновременно smile.gif
volvo
VDmV, а ты правила читал?
Цитата
6. Проверяйте программы перед тем, как запостить их!!!

В Турбо-Паскале твой фрагмент кода не откомпилируется. Внимательнее с этим... Это первое.

А второе - нужно не координаты нулей, а количество их в каждом столбце... Чтобы потом найти максимум... чтобы потом перебросить столбец с максимальным количеством нулей на последнюю позицию... И т.д. и т.п. Вместо того, чтобы ВНИМАТЕЛЬНО прочесть пост №4, и ссылку которая там находится. С учетом той информации программа уложится в несколько строк...

Изобретаем дальше...
VDmV
Цитата
В Турбо-Паскале твой фрагмент кода не откомпилируется. Внимательнее с этим... Это первое.

Я понял. Возможно и не откомпилируется, но я хотел высказать хотябы идею.
А количество нулей найти ещё проще:
Код

type
 mass= b:array[1..5] of integer;
procedure Chislo(var a:matrix; var b:mass);
var
i,j:integer;
begin
 for i:=1 to 5 do
 begin
   b[i]:=0;
   for j:=1 to 4 do
   if a[j,i]=0 then b[i]:=b[i]+1;
 end;
end;

Это должно откомпилироваться unsure.gif Давно на чистом паскале не программировал, всё приходиться на делфи.
Serega18
Код
Begin
assign(f1,'isdan.pas');
assign(f2,'vdan.pas');
reset(f1);
rewrite(f2);
 Begin
  for i:=1 to 4 do
   Begin
    For j:=1 to 5 do
     read(f1,A[i,j]);
    end;
   writeln(f2);
  end;

Такой вот вопрос я ввел матрицу А в f1 read(f1,A[i,j]); ,а выводить в f2 мне тоже матрицу А(но ведь она изменена) как мне поступить
volvo
Цитата(Serega18 @ 28.05.05 22:22)
я ввел матрицу А в f1 read(f1,A[i,j]); ,а выводить в f2 мне тоже матрицу А(но ведь она изменена) как мне поступить

Ну так куда же деваться? Если нужно сохранять измененную матрицу - значит пиши измененные значения в F2, если тебе еще раз понадобится исходная матрица A, ты же ее всегда сможешь считать из F1, не так ли?
Serega18
Сделал так:Сделал еще одну процедуру в которой из элементов измененной матрицы А формирую матрицу В и потом в F2 вывожу уже матрицу В.Так я могу сделать?
Исходный код
Program S4_3_3;
Uses crt;
Type Matrix=array[1..4,1..5] of real;
Odn=array[1..5] of real;var A,B:matrix;
ch:odn;
i,j,indx:integer;
f1,f2:text;
Procedure chislo(var A:matrix;ch:odn);
var i,j:integer;
Begin
ch[j]:=0;
For i:=1 to 4 do
Begin
For j:=1 to 5 do
Begin
IF A[i,j]=0 Then
ch[j]:=ch[j]+1;
end;
end;
end;
Function min_nulls(var a:matrix):integer;
var i,j:integer;
min,indx,count:integer;
Begin
min:=5;
for j:=1 to 5 do
Begin
count:=0;
for i:=1 to 4 do
if A[i,j]=0 then
inc(count);
If min>count then
Begin
min:=count;
indx:=j;
end;
end;
min_nulls:=indx;
end;
Procedure resort(var A:matrix;indx:integer);
Var i:integer;
T:real;
Begin
If indx<>1 then
for i:=1 to 4 do
Begin
T:=A[i,1];
A[i,1]:=A[i,indx];
A[i,indx]:=T;
end;
end;
Procedure ST(var A:matrix;indx:integer);
Var i,j,n:integer;
Begin
n:=0;
for i:=1 to 4 do
Begin
IF A[i,indx]=0 then
Begin
A[i,indx]:=A[5-n,indx];
A[5-n,indx]:=0;
n:=n+1;
end;
end;
end;
Procedure output(A,B:matrix);
Var i,j:integer;
Begin
for i:=1 to 4 do
Begin
For j:=1 to 5 do
A[i,j]:=B[i,j];
end;
end;
Begin
assign(f1,'isdan.pas');
assign(f2,'vdan.pas');
reset(f1);
rewrite(f2);
Begin
for i:=1 to 4 do
Begin
For j:=1 to 5 do
read(f1,A[i,j]);
end;
writeln(f2,B[i,j]);
end;
Begin
clrscr;
chislo(A,ch);
min_nulls(A);
resort(A,indx);
St(A,indx);
Output(A,B);
readln;
end;
end.
volvo
Цитата(Serega18 @ 30.05.05 16:52)
Так я могу сделать?

Сделать-то можешь только... Вот программа-то твоя работать если и будет, то с ошибками. Смотри:
Procedure chislo(var A:matrix;ch:odn);
В ней ты меняешь содержимое массива Ch, но пойми, что этих изменений ты не увидишь: чтобы их увидеть, нужно передавать массив так:
Procedure chislo(var A:matrix;var ch:odn);

А так как сейчас у тебя - массив не изменится...

Аналогично здесь:
Procedure output(A,B:matrix);
Какой матрица B была до вызова Output, такой и останется (по причине, указанной выше)...
Serega18
Исправил предыдущие ошибки но f2 всеравно остается пустой
volvo
А файлы за тебя кто закрывать будет? Может быть ты и записал матрицу B в файл, но файл не закрыл, и данные потерялись...
Serega18
Теперь в f2 выводит просто ноль
Исходный код
Program S4_3_3;
Uses crt;
Type Matrix=array[1..4,1..5] of real;
Odn=array[1..5] of real;var A,B:matrix;
ch:odn;
i,j,indx:integer;
f1,f2:text;
Procedure chislo(var A:matrix;VAR ch:odn);
var i,j:integer;
Begin
ch[j]:=0;
For i:=1 to 4 do
Begin
For j:=1 to 5 do
Begin
IF A[i,j]=0 Then
ch[j]:=ch[j]+1;
end;
end;
end;
Function min_nulls(var a:matrix):integer;
var i,j:integer;
min,indx,count:integer;
Begin
min:=5;
for j:=1 to 5 do
Begin
count:=0;
for i:=1 to 4 do
if A[i,j]=0 then
inc(count);
If min>count then
Begin
min:=count;
indx:=j;
end;
end;
min_nulls:=indx;
end;
Procedure resort(var A:matrix;indx:integer);
Var i:integer;
T:real;
Begin
If indx<>1 then
for i:=1 to 4 do
Begin
T:=A[i,1];
A[i,1]:=A[i,indx];
A[i,indx]:=T;
end;
end;
Procedure ST(var A:matrix;indx:integer);
Var i,j,n:integer;
Begin
n:=0;
for i:=1 to 4 do
Begin
IF A[i,indx]=0 then
Begin
A[i,indx]:=A[5-n,indx];
A[5-n,indx]:=0;
n:=n+1;
end;
end;
end;
Procedure output(Var A:matrix; var B:matrix);
Var i,j:integer;
Begin
for i:=1 to 4 do
Begin
For j:=1 to 5 do
A[i,j]:=B[i,j];
end;
end;
Begin
assign(f1,'isdan.pas');
assign(f2,'vdan.pas');
reset(f1);
rewrite(f2);
Begin
for i:=1 to 4 do
Begin
For j:=1 to 5 do
read(f1,A[i,j]);
end;
writeln(f2,B[i,j]);
close(f1);
close(f2);
end;
Begin
clrscr;
chislo(A,ch);
min_nulls(A);
resort(A,indx);
St(A,indx);
Output(A,B);
readln;
end;
end.
volvo
А вот что у меня получилось: Нажмите для просмотра прикрепленного файла

(только учти, что в программе столбец с минимальным числом нулей НЕ просто меняется местами с первым, а столбцы СДВИГАЮТСЯ и тот, в котором меньше нулей ставится первым... При запуске программы поймешь о чем я smile.gif )
Я же говорил, прочти 4-ый пост, и сходи по ссылке... smile.gif
Serega18
Это очень круто blink.gif ,я так понял там нетипизированные,константы и еще много чего.только это не мой уровень . хотелось бы хотя бы в простом виде сделать (хоть "немного" своими руками) и немного разобраться.
насчет столбцов понял,4 пост прочитал(по ссылке прошел).
И хотелось бы узнать почему у меня не работал последний вариант sad.gif
VDmV
Мдя, решение конечно найдено, но 2Serega18. Не разбирался я почему у тебя не работает (это может быть либо по не внимательности либо по не совсем хорошему знанию паскаля).
Я вот посмотрел бегло и вот что:
Цитата

Procedure chislo(var A:matrix;VAR ch:odn);
var i,j:integer;
Begin
  ch[j]:=0;

Посмотри переменная j - не определена, а ты её уже используешь, откуда ты знаешь что в ней хранилось до этого времени? Никогда не полагайся на то что там будет 0 или ещё что нибудь, если ты явно этого не указал.
Смотри сам по коду, я уверен ты найдёшь на все свои вопросы сам ответы.
Serega18
тоесть мне надо j во входящие параметры записать?
Код
Procedure chislo(var A:matrix;j:integer; VAR ch:odn);
var i:integer;
Begin
 ch[j]:=0;
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.