Страница 1 из 2

Глава 24, задачи В и Г

СообщениеДобавлено: 21.11.2012 20:21:32
deka47
Опять застрял на похожем задании, не знаю как его решить.

Код: Выделить всё
procedure check (const s: string);
var i, k: integer;
    ch: char;
    t: string;
begin
t:='';
k:=length(s);
for i:=1 to k do if ord(s[i])>32 then begin t:=inttostr(i); writeln (t, ' - ', s[i]);
end;
end;

var s: string;
begin
write ('Write a word - '); readln (s);
check (s);
end.


Программа работает, она выводит местоположение буквы в строке, кроме управляючих символов. Но вот как сделать, чтобы она выводила повторяюищиеся буквы в одной строке? Т.е. к примеру слово PASCAL, вывод у меня:
Код: Выделить всё
Write a word - pascal
1 - p
2 - a
3 - s
4 - c
5 - a
6 - l


А хочу:
Код: Выделить всё
Write a word - pascal
1 - p
2, 5 - a
3 - s
4 - c
6 - l

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 22.11.2012 09:08:03
Oleg_D
Для начала давайте объясним всем, что речь идёт о задачах 24-В и 24-Г:

24-В) Для введенной пользователем строки напечатать позиции всех встречающихся в ней символов, кроме пробелов, в алфавитном порядке. Для символов, которые встречаются несколько раз, напечатать позиции в одной строке.

Код: Выделить всё
var  S: string;
     c: char;
     i: integer;
     flag: boolean; { признак для печати очередной строки }
begin
  Write('S = ');  Readln(S);
  { Char(33) - первый символ после пробела }
  for c:=Char(33) to Char(255) do begin
    flag:= false;
    for i:=1 to Length(S) do if c=S[i] then begin
      if not flag then Write(c, ' - ');
      Write(i,' ');
      flag:= true;
    end;
    if flag then Writeln;
  end;
  Readln;
end.



24-Г) Для введенной пользователем строки напечатать позиции всех встречающихся в ней символов, кроме пробелов, в порядке их следования в строке.

Код: Выделить всё
var  S: string;
     c: char;
     i, j: integer;
begin
  Write('S = ');  Readln(S);
  for i:=1 to Length(S)  do begin
    c:= S[i];
    if c<>Char(32) then begin  { Char(32) - пробел }
      Write(c, ' - ');
      for j:=i to Length(S) do if c=S[j] then begin
        Write(j,' ');
        S[j]:= Char(32);  { затираем символ пробелом }
      end;
      Writeln;
    end;
  end;
  Readln;
end.


А теперь переделайте их, создав процедуры, принимающую строку.

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 23.11.2012 01:46:53
deka47
В ответы я тоже смотрел, меня интересовало как сделать на базе моего варианта.

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 23.11.2012 13:21:28
bormant
deka47 писал(а):В ответы я тоже смотрел, меня интересовало как сделать на базе моего варианта.

Например,
Код: Выделить всё
procedure check(s: string);
var
  i, j: integer;
begin
  for i := 1 to length(s) do
    if s[i] > ' ' then begin
      write(i);
      for j := i+1 to length(s) do
        if s[j] = s[i] then begin
          write(', ', j); s[j] := ' ';
        end;
      writeln(' - ', s[i]);
    end;
end;

var
  s: string;
begin
  write('Enter a word: '); readln(s);
  check(s);
end.
Прогон:
Код: Выделить всё
Enter a word: pascal
1 - p
2, 5 - a
3 - s
4 - c
6 - l

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 23.11.2012 13:29:32
Oleg_D
Хорошее решение от bormant.
Обратите внимание на передачу строки в процедуру:
procedure check(s: string);
Это тот случай, когда не ставится ни VAR, ни CONST.

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 23.11.2012 14:10:12
bormant
Ещё один вариант процедуры check, в котором для учёта уже обработанных символов используется не модификация копии оригинальной строки, а множество символов:
Код: Выделить всё
procedure check(const s: string);
var
  i, j: integer;
  p: set of char(33)..char(255);
begin
  p := [];
  for i := 1 to length(s) do
    if (s[i] > ' ') and not (s[i] in p) then begin
      write(i);
      for j := i+1 to length(s) do
        if s[j] = s[i] then begin
          write(', ', j); include(p, s[j]);
        end;
      writeln(' - ', s[i]);
    end;
end;

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 23.11.2012 14:41:18
Oleg_D
include(p, s[j]) равнозначно p:= p + [ s[j] ] ?
Тоже хорошее решение, но на будущее, поскольку в главе 24 множества ещё не изучались.

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 23.11.2012 14:52:34
bormant
Oleg_D писал(а):include(p, s[j]) равнозначно p:= p + [ s[j] ] ?
По смыслу -- да, по эффективности реализации Include/Exlude должны быть эффективнее (по крайней мере не хуже) варианта с созданием промежуточного множества [ s[j] ] (как для i:=i+1 и inc(i)). К тому же поддерживаются "магией компилятора", позволяя указывать в качестве второго параметра диапазоны через ":".
Oleg_D писал(а):Тоже хорошее решение, но на будущее, поскольку в главе 24 множества ещё не изучались.
Возможно, это повод для дополнительной задачи в главу про множества ;) их обычно не так-то просто придумывать. Да и реализация одного и того же различными средствами может возыметь положительный педагогический эффект.

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 23.11.2012 15:10:03
Oleg_D
bormant писал(а):Возможно, это повод для дополнительной задачи в главу про множества их обычно не так-то просто придумывать. Да и реализация одного и того же различными средствами может возыметь положительный педагогический эффект.

Согласен. Альтернативная реализация множеств затронута здесь:
Задача 49-В (стр. 389)
Задача 61-Б (стр. 519)
Но есть ещё много мыслей на эту тему, только руки не доходят всё изложить.

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 24.11.2012 02:06:52
deka47
bormant , разобрался с вашим кодом, спасибо. Но есть один вопрос, что это значит:

Код: Выделить всё
if s[i] > ' '

Если символ больше пробела? Я не пойму вот только этот кусочек.

Это тоже что и:
Код: Выделить всё
if ord(s[i]) > 32

Но я что то сомневаюсь.

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 24.11.2012 04:46:06
bormant
Не сомневайтесь, возможно многое ;)
например, словари "Англо-русский" или "Русско-английский" -- в качестве критерия сортировки обычно используется "положение буквы в алфавите". Вот только одна есть беда, иногда порядок сортировки с кодом символа не совпадает... Но это не наш случай, в латинице все до пробела и дальше до символа с кодом 127 стандартнее некуда -- ASCII, только очень-и-очень древние могут перемочь эти нынешние условности.

Возвращаясь к вопросу: да, char1 vs. char2 в нынешних паскалях сравнивается как byte(char1) vs byte(char2), то есть по их числовому коду.

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

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 19.01.2015 13:47:32
Ackur
Не дает покоя решение задачи Глава 24, Г

а именно строки :
S[j]:= Char(32); { затираем символ пробелом }

Мужики, разъясните пожалуйста для чего она нужна?

Спасибо!

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 06.07.2016 06:03:26
saavvva
Глава посвящена шифрованию, но в решении ничего с ним не связано. Есть другой способ решения этой задачи?

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 31.10.2016 15:37:07
Герман
HELP!
Задание " Г ".

Так и не понял, как у bormanta получается обнулять строки с помощью " s[j] := ' '; ". Можно ли задать в " if " ( красным цветом в коде if (S <> ' ') { and (S[i] <> S[1..(i - 1)]) } условие, чтобы сравнивал предыдущие символы с рассматриваемым?

Код: Выделить всё
var S             : string;
    N             : integer;        { dlina stroki }
    i, k          : integer;        { schetchiki }

begin
  Write(' Vvedite stroku: '); Readln(S);
  N := Length(S);                           { dlina stroki }
  for i := 1 to N do
                    if (S[i] <> ' ') { and (S[i] <> S[1..(i - 1)]) }
                      then
                        begin
                          Write(S[i], '- ');
                          for k := i to N do
                                            if S[k] = S[i]
                                              then
                                                Write(k, ', ');
                          Writeln('');
                        end;
  Readln;
end.




Добавлено спустя 1 час 24 минуты 49 секунд:


[i]В задании " Г "
,

Объясните, пожалуйста, на пальцах, какое условие является решающим для переменной FLAG?

Re: Глава 24, задачи В и Г

СообщениеДобавлено: 01.11.2016 16:23:20
bormant
Уж Герман близится, а полночи всё нет... (почти цитата)

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