Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ 4 задачи и куча вопросов....

Автор: Анка 8.07.2005 16:13

Цитата
1. Даны две последовательности a1 ≤ a2 ≤ ... ≤ аn и b1 ≤ b2 ≤ ... ≤ bn. Образовать из них новую последовательность чисел так, чтобы она тоже была неубывающей (дополнительный массив не использовать).

2. Расположить столбцы матрицы D[M, N] в порядке возрастания элементов k-ой строки (1 ≤ k ≤ М).

3. Реализовать набор подпрограмм для выполнения следующих операций над векторами: а) сложение; б) вычитание; в) скалярное умножение векторов; г) умножение вектора на число; д) нахождение длины вектора.
1) Дан массив A – массив векторов. Отсортировать его в порядке убывания длин векторов.
2) С помощью датчика случайных чисел сгенерировать 2N целых чисел. N пар этих чисел задают N точек координатной плоскости. Вывести номера тройки точек, которые являются координатами вершин треугольника с наибольшим углом.

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

Мало того, что мне нужно решить все эти задачи, но мне еще нужно объединить их одним меню (хотя это я сделала). Причек все это надо реализовать с выбором способа ввода - с клавы, из файла или случайная генерация.
Из-за практики появилось много вопросов. Может кто-нибудь поможет?
1. Не могу решить 1 задачу... что-то не получается... ввести ввожу, а вот дальше... тоже самое обстоит со второй...
2. не понимаю, как можно реализовать 2 пункт в 3 задаче...... просто даже толком не понятно, что нужно...
ну пока вроде всё... huh.gif

Автор: volvo 8.07.2005 16:22

Анка, (она же Незнакомка? или я ошибаюсь? rolleyes.gif )
Поиском пользуемся...
1 задание - http://forum.pascal.net.ru/index.php?showtopic=5840&view=findpost&p=44358 (это как раз случай для 2-х последовательностей)
2 задание - http://forum.pascal.net.ru/index.php?showtopic=2694&view=findpost&p=38100 + поиск (задача уже решалась)

и т.д.

Автор: volvo 8.07.2005 16:46

Цитата
4. Дана строка, содержащая произвольный текст. Выяснить чего в нем больше: русских букв или цифр.
Это, по-моему, тоже решалось, но ...
const
russ = ['А'..'П', 'Р'..'Я', 'а'..'п', 'р'..'я'];
digits = ['0'..'9'];
var
count_rus, count_digit: integer;
...
begin
{ Здесь - читаешь строку s }
count_rus := 0; count_digit := 0;
for i := 1 to length(s) do
if s[i] in russ then inc(count_rus)
else if s[i] in digits then inc(count_digit);

{ если count_rus > count_digit значит букв больше, иначе - больше цифр }
end.

Автор: Анка 8.07.2005 16:50

volvo, klem4, спасибо, но 4 задачу я как раз решила....... rolleyes.gif причем видимо 3 способом..... :D

Автор: volvo 8.07.2005 17:01

Насчет операций с векторами -

Код
Type
 TVector = Record
   X, Y: Real;
 End;
Procedure VAdd(Var a: TVector; b, c: TVector);
Begin
 a.X := b.X + c.X; a.Y := b.Y + c.Y;
End;
Procedure VSub(Var a: TVector; b, c: TVector);
Begin
 a.X := b.X - c.X; a.Y := b.Y - c.Y;
End;
Procedure VScale(Var a: TVector; b: TVector; k: Real);
Begin
 a.X := b.X * k; a.Y := b.Y * k;
End;
{ Это - скалярное произведение векторов }
Function VDot(a, b: TVector): Real;
Begin
 VDot := a.X * b.X + a.Y * b.Y;
End;
{ Длина вектора }
Function VLength(a: TVector): Real;
Begin
 VLength := Sqrt(sqr(a.X) + sqr(a.Y));
End;

Можно немного оптимизировать (для большего количества элементов вектора, чтобы не считать все вручную)... Если нужно - говори, я покажу как...

Добавлено:
Вот пример сортировки массива векторов...
Код
Type
 TVector = Record
   X, Y: Real;
 End;

Function VLength(a: TVector): Real;
Begin
 VLength := Sqrt(sqr(a.X) + sqr(a.Y));
End;

const
 size = 10;
type
 arrType = Array[1 .. size] Of TVector;

Procedure Bubble(Var ar: arrType; n: integer);
Var
 i, j: Integer;
 T: TVector;
Begin
 For i := 1 To n Do
   For j := n DownTo i+1 Do
     If VLength(ar[Pred(j)]) > VLength(ar[j]) Then Begin { < }
       T := ar[Pred(j)]; ar[Pred(j)] := ar[j]; ar[j] := T
     End
End;

Procedure GetVector(Var v: TVector);
Begin
 With v Do Begin
   Write('X='); ReadLn(X);
   Write('Y='); ReadLn(Y);
 End;
End;
Procedure PrintVector(v: TVector);
Begin
 With v Do
   WriteLn('X:',X:10:5,' Y:',Y:10:5)
End;

Var
 A: arrType;
 i: Integer;

begin
 For i := 1 To size Do
   GetVector(A[i]); { Вводим все вектора }

 { Сортируем }
 Bubble(A, size);

 For i := 1 To size Do
   PrintVector(A[i]); { Печатаем массив векторов }
end.

Автор: Анка 8.07.2005 19:11

volvo, а можете мне объяснить вот эту строчку? Я просто не могу что-то понять, что это именно за элементы? (ar[Pred(j)] например)

If VLength(ar[Pred(j)]) > VLength(ar[j]) Then Begin { < }
T := ar[Pred(j)]; ar[Pred(j)] := ar[j]; ar[j] := T

Автор: volvo 8.07.2005 19:37

Ну, это же стандартный метод "пузырька"...
ar[Pred(i)] - это то же самое что и ar[i - 1]. То есть, все что там делается - проверяется, если длина (VLength) предыдущего вектора больше длины последующего, то поменять эти 2 элемента местами (этим занимается вторая строка)... А закомментированный значок "<" - если понадобится сортировать по убыванию, меняем в этой строке "больше" на "меньше"...

Автор: Анка 9.07.2005 1:11

volvo, спасибо, просто я не поняла только как раз записи ar[Pred(i)], так как я раньше так ни разу не писала.....то что это стандартно я знаю, сама часто писала через такой метод, а почему метод именно "пузырька" (первый раз такое слышу smile.gif )?

Автор: volvo 9.07.2005 1:51

Цитата(Анка @ 8.07.05 21:11)
а почему метод именно "пузырька" (первый раз такое слышу  smile.gif )?

А потому, что в процессе сортировки более "легкие" (меньшие по значению) элементы как бы "всплывают" до тех пор, пока не будет встречен элемент еще более "легкий"...

Автор: Анка 9.07.2005 2:38

что-то у меня Паксаль не хочет признавать процедуры и функции для программы с векторами... с действиями над ними...... sad.gif кстати, а можно объявить переменные к конкретной задаче как бы в середине программы или в самом начале только? Просто у меня все 4 задачи объединены общим меню......

Автор: volvo 9.07.2005 2:50

Прикрепи свою программу в аттаче или вышли мне в личку, я посмотрю, что ты делаешь.. Эти процедуры (с небольшими изменениями) взяты из нормально работающей программы...

Автор: Анка 10.07.2005 19:20

я сейчас попробую пока сама разобраться.... надеюсь все будет нормально......
у меня сейчас возникла др. проблема...... с выводом массива в 1 задаче....
печатаю
for i:=1 to (size+size) do (или to 20) {максимальное количество в обоих массивах}
write (result[i]);
{end for}, а он выдает вообще весело... если массивы формируются случайно, то все нормально, а вот если самому...... то получается что-то вида
1 2 3 4 0 0 0 0 0 0 56 67 0 0 0 0 0 0 0 0 0 0

Автор: volvo 10.07.2005 19:23

Ну, так приведи код, КАК заполняются массивы. Телепатов тут нет ...

Автор: Анка 10.07.2005 21:22

volvo, не знаю, правильно ли, но решила разбить вывод массива на 2 пункта - для случайной генерации этих массивов и для чтения из файла, также с клавы. Немного устранились глюки, только теперь последний элемент во втором варианте (для файла и с клавы) конечного массива заменяется почему-то нулем. Массив формируется точно также почти, как вы предложили через поиск.... у меня только переменные другие. Вот.

Автор: volvo 10.07.2005 21:37

Цитата(Анка @ 10.07.05 17:22)
Массив формируется точно также почти, как вы предложили через поиск.... у меня  только переменные другие.
Ну, значит, и результат будет почти правильный... Я без кода ничего сказать не могу...

Автор: Анка 10.07.2005 23:26

Там только заменены переменные, типа arr[i] на a[i], вот и все... как сюда скинуть текст не знаю..... как вообще скопировать из Паскаля текст? или это нельзя сделать.... rolleyes.gif

Автор: volvo 11.07.2005 0:18

Так присоедини весь PAS-файл...

Жмешь кнопку "Ответить" (не Быстрый ответ, а именно "Ответить"), и выбираешь имя файла для присоединения (.PAS, или заархивируй, если исходник большой)...

Автор: Archon 11.07.2005 3:07

Цитата
как сюда скинуть текст не знаю..... как вообще скопировать из Паскаля текст? или это нельзя сделать.... 
Это можно сделать. Сперва перейти в оконный режим (Alt+Enter). Затем правой кнопкой по заголовку окна. Далее: Изменить->Пометить (выделяем мышкой текст), Изменить->Копировать. Всё!

PS В Win9x для этого есть аналогичные кнопки на тулбаре.

PPS Иногда проще открыть файл с программой в "блокноте" и скопировать оттуда.

Автор: Анка 11.07.2005 19:24

а можно случайно сгенерировать текст (или строку)? rolleyes.gif

Автор: klem4 11.07.2005 20:02

Цитата(Анка @ 11.07.05 16:24)
а можно случайно сгенерировать текст (или строку)? rolleyes.gif


конечно можно, если возможны все символы, то например так :


var
ch:char;
s:string;

...
Begin
...
readln(n);
s:='';
randomize;
count:=0;
repeat
ch:=chr(random(256));
s:=s+ch;
inc(count);
until count=n;
...
End.


Добавлено

Для латинских букв

ch:=chr(random(26)+97)

Автор: volvo 11.07.2005 20:07

Цитата(klem4 @ 11.07.05 16:02)
конечно можно, если возможны все символы, то например так :
  ch:=chr(random(256));

Никогда больше так не делай... Ты должен генерировать символы, которые можно распечатать, не включая управляющие:
s := s + chr(32+random(255-32));

Автор: Анка 11.07.2005 20:26

klem4, а что такое n? количество символов в строке что ли?
еще вопросик.... rolleyes.gif
как лучше реализовать возможность сохранить результаты в файл? после каждой конкретной задачи или в конце программы после всего? и как это сделать? blink.gif

Автор: volvo 11.07.2005 20:39

Цитата(Анка @ 11.07.05 16:26)
а что такое n? количество символов в строке что ли?
Я конечно не klem4 smile.gif Именно количество символов в строке... Причем я бы и это количество тоже генерировал random-ом
Цитата(Анка @ 11.07.05 16:26)
как лучше реализовать возможность сохранить результаты в файл? после каждой конкретной задачи или в конце программы после всего? и как это сделать?
Зависит от конкретных требований к программе, смотря что сохранять... Например, в этот раз ты посчитала сумму векторов, в другой раз - отсортировала массив... Сумму векторов тоже будешь сохранять?

Тогда делай что-то типа Log-файла, куда будут заноситься все удачно завершенные операции (естественно, только при последнем запуске...). Для этого программа должна просто дублировать вывод на экран выводом в текстовый файл... (файл должен открываться при старте программы - первой строкой, а закрываться - последней...)

Автор: Анка 12.07.2005 1:45

а что такое count? какого типа? хм.....
volvo, а как это сделать? просто открыть вначале файл для записи, а в конце закрыть его? что я не совсем понимаю... blink.gif

Автор: volvo 12.07.2005 2:20

Count - типа Byte (больше нет смысла, все равно в строке только до 255 символов):

var
count, n: byte;
s: string;
begin
s := '';
n := 5 + random(255 - 5); { случайная длина от 5 до 255 символов }
for count := 1 to n do
s := s + chr(32+random(255-32)); { это я уже писал, почему }
end;


А насчет лог-файла... Вот тебе пример:

var f_log: text;
begin { начало основной программы }
assign(f_log, 'log.txt');
{$i-} rewrite(f_log); {$i+}
{ обработка ошибки открытия лог-файла }
...
Begin { здесь обрабатываем сложение векторов }
GetVector('first vector', v1);
GetVector('second vector', v2);

VAdd(v3, v1, v2); { v3 <- v1 + v2 }
PrintVector('result', v3); { печатаем на экран }

{ и записываем в лог }
WriteLn(f_log, 'add vector: v1=', v1.X:7:3, v1.Y:7:3,
' v2=', v2.X:7:3, v2.Y:7:3, ' result = ', v3.X:7:3, v3.Y:7:3);
End;
...
close(f_log); { перед самым концом программы закрываем лог-файл }
end.

Автор: Анка 12.07.2005 13:01

volvo, а у меня n типа integer, зачем byte?
с файлом кошмар.... значит придется это писать, точнее одну часть в каждой части моей программы, но спасибо, вроде поняла. Я немного не так думала....
кстати, я сейчас конечно попробую на деле, но какие символы формируются при случайной генерации? Мне нужна латиница и цифры (П.С. это для 4 задачи)

Автор: volvo 12.07.2005 13:36

Цитата(Анка @ 12.07.05 9:01)
volvo, а у меня n типа integer, зачем byte?

А зачем Integer? Все равно больше 255 нельзя, но если не хочешь менять - можно оставить Integer...
Цитата(Анка @ 12.07.05 9:01)
кстати, я сейчас конечно попробую на деле, но какие символы формируются при случайной генерации? Мне нужна лиитница и цифры
Если тебе только латиница и цифры, то вот так:
var ch: char;
{ здесь генерируешь n }
for i := 1 to n do begin
repeat
{ случайный символ в интервале ['0'(ноль) .. 'z'] }
ch := chr(48+random(122-48));

{ но в этом интервале есть и другие символы,
(точки, двоеточия, запятые...), и их не надо включать в строку }
until upcase(ch) in ['A'..'Z', '0'..'9'];
s := s + ch;
end;

Автор: Анка 12.07.2005 13:51

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

а на счет integer.... просто я уже сгенерировала n, и если не integer, то придется вводить новую переменную, а так n у меня уже есть, используется в др. месте, а переменых уже...... очень много rolleyes.gif :D

Автор: Анка 13.07.2005 16:18

что-то у меня немного не получается с 4, так как я уже сделала ее для ввода с клавы и из файла, у меня программа для str {char}, вот теперь не знаю, что делать для случайно генерации, так как не хочется опять писать новую программу для генерации, а в старой при замене некоторых переменых типы не подходят....... а сдавать завтра.... sad.gif
вот моя программа, может кто подскажет:


begin
cifri:=0;
bukvi:=0;
repeat
repeat
read (str);
if str in ['a'..'z'] then
bukvi:=bukvi + 1;
if str in ['0'..'9'] then
cifri:=cifri + 1;
until eoln;
until str='*';
readln;
if bukvi>cifri then
writeln ('V dannoi stroke bol`she bukv');
if cifri>bukvi then
writeln ('V dannoi stroke bol`she cifr');
if cifri=bukvi then
writeln ('V dannoi stroke bukv i cifr porovnu');
writeln ('Dlja prodolgenija nagmite enter');
end;


Автор: volvo 13.07.2005 16:44

Попробуй вот так:

begin
str_ok := True; { введи новую переменную }
case t of { t - твой выбор, откуда читать строку }
1: begin
{ читаешь строку с клавиатуры (только читаешь, не обрабатываешь !!!) }
end;

2: begin
{ Чтение строки из файла }
end;
3: begin
{ генерация случайной строки }
end;
4: begin
{ сообщение о выходе }
str_ok := False;
end;
end {case}

{ а здесь - собственно обработка строки (если нужно) }
if(str_ok) then begin

cifri:=0; bukvi:=0;

for i := 1 to length(str) do
if upcase(str[i]) in ['A'..'Z'] then bukvi:=bukvi + 1
else if str[i] in ['0'..'9'] then cifri:=cifri + 1;

if bukvi>cifri then writeln ('V dannoi stroke bol`she bukv')
else if cifri>bukvi then writeln ('V dannoi stroke bol`she cifr');
else writeln ('V dannoi stroke bukv i cifr porovnu');
end;
end;

Если я не ошибаюсь, этот блок Begin ... End надо поставить вместо того Case, что сейчас стоит под условием:
if (t=1) or (t=2) or (t=3) or (t=4) then

Автор: Анка 13.07.2005 16:58

volvo, спасибо, куда писать, я знаю, но эта переменная чем мне поможет? если при генерацци случайной у меня все записывается в переменную s, как вы показали, а если изменить, чтобы все читалось в str, то типы не подходят! А так суть программы-то не меняется..... все равно надо что-то делать с вводом случайно или я что-то не понимаю? Готова признать, что неправа, если это так..... rolleyes.gif

Автор: Romtek 13.07.2005 17:32

Я что-то не вижу где здесь переменная S...

Автор: Анка 13.07.2005 18:12

Цитата
Я что-то не вижу где здесь переменная S...

при случайной генерации....... смотрите выше.....volvo выкладывал, так вот там если заменить на str, то тип не подходит....
еще вопросик.... rolleyes.gif
я как всегда видимо что-то напутала...
вот часть моей программы:

writeln ('Vvedite nomer stroki');
write ('Vibrana stroka: ');
readln (k);
min:=mx[k][1];
jmin:=1;
for i:=k to k do {не знаю, как записать иначе, мне нужна лишь одна строка}
for j:=1 to size_col do
if mx[k][j]<min then begin
swap_cols(mx,jmin,j);
min:=mx[k][j];
jmin:=jmin+1;
end
else
j:=j+1;
{end;}


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

Автор: Romtek 13.07.2005 18:29

Цитата(Анка)
у меня все записывается в переменную s, как вы показали, а если изменить, чтобы все читалось в str, то типы не подходят!
Ну так поменяй str на s ... В чём проблема вообще?

Для замены столбцов нужен только 1 цикл for j
j - столбец
k - строка

k := 3; { заменяем по 3-й строке, допустим. }

for j:=1 to size_col do
if mx[j, k]<min then begin
swap_cols(mx,jmin,j);
min:=mx[j, k];
jmin:=jmin+1;
end
else
j:=j+1;

Автор: Romtek 13.07.2005 18:33

mx[k][j] - такой формы записи в Паскале не существует. Так только в языке C пишут.
Надо так: mx[j, k]
j - столбец.

Автор: Анка 13.07.2005 18:38

Цитата
Ну так поменяй str на s ... В чём проблема вообще?

так в том-то и проблема, что они разных типов, а там надо в s записать всю строку:
s := s + ch
. Если изменить даже тип переменной str на string (было char), то почему-то не идет сама программа.....
я уже пробовала..... там не нравится Паскалю вот это строчка при таком типе данных
[if str in ['a'..'z'] then


за программу спасибо, я не знала, что нужен один цикл.... rolleyes.gif

Автор: Анка 13.07.2005 18:49

Цитата
mx[k][j] - такой формы записи в Паскале не существует. Так только в языке C пишут.
Надо так: mx[j, k]
j - столбец.

тогда почему на этом же форуме есть запись вот такая:
 procedure print (var mx: tmatrix);
var i, j: integer;
begin
for i:=1 to size_col do
begin
for J:=1 to size_col do
write(mx[j][i]:4);
writeln;
end;
end;

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

Автор: Romtek 13.07.2005 19:02

Понятно. У тебя матрица определена по-другому. Значит всё нормально.

Вольво писал:

    for i := 1 to length(str) do
if upcase(str[i]) in ['A'..'Z'] then bukvi:=bukvi + 1
else if str[i] in ['0'..'9'] then cifri:=cifri + 1;


str: string;

str[i] - соответственно, типа char.
Если у тебя дана строка s, то замени все str на s.
Твой вариант был неверен.

Автор: Анка 13.07.2005 21:07

или я что-то не понимаю, но нужные столбцы он менять не хочет все равно.... sad.gif

Автор: volvo 13.07.2005 21:28

Какие столбцы ???? О чем речь вообще? Об обработке матриц или строк? Я вообще уже ничего не понимаю...

В-общем, так: подобных тем ("4 задачи и куча вопросов") больше НЕ создавать. Одна тема - один вопрос. Эту тему я скорее всего закрою, ибо здесь уже полный балаган.

Автор: Анка 13.07.2005 21:46

volvo, я не знаю, что делать..... а столбцы это я с Romtek`ом обсуждала........ у меня ничего не идет.............. sad.gif :bye2: в строках у меня при любой случайной генерации выдается сообщение, что букв и цифр поровну................................ huh.gif sad.gif

Автор: volvo 13.07.2005 21:57

My fault ... Извиняюсь, я просто поставил лишнюю запятую... Вот так измени (то, что я тебе раньше давал):

  { а здесь - собственно обработка строки (если нужно) }
if(str_ok) then begin

cifri:=0; bukvi:=0;

for i := 1 to length(str) do
if upcase(str[i]) in ['A'..'Z'] then bukvi:=bukvi + 1
else if str[i] in ['0'..'9'] then cifri:=cifri + 1;

if bukvi>cifri then writeln ('V dannoi stroke bol`she bukv')
else if cifri>bukvi then writeln ('V dannoi stroke bol`she cifr') {; <--- запятой быть НЕ ДОЛЖНО !!! }
else writeln ('V dannoi stroke bukv i cifr porovnu');
end;

Автор: Анка 13.07.2005 22:05

volvo, я ее и не ставила..... правила я знаю...... но мне от этого не легче....

Автор: volvo 13.07.2005 22:11

Проверь PM ...