Модераторы: Oleg_D, Модераторы
var
  s: string;
  i: integer;
  p: boolean;
begin
  write('Введите слово: '); readln(s);
  p := true;
  for i := length(s) div 2 downto 1 do
    if s[i] <> s[length(s) - i + 1] then begin
      p := false; break;
    end;
  if p then writeln('Слово - палиндром')
  else writeln('Слово - НЕ палиндром');
end.
function IsPalindrom(s: string): boolean;
var
  i: integer;
begin
  IsPalindrom := true;
  for i := length(s) div 2 downto 1 do
    if s[i] <> s[length(s) - i + 1] then begin
      IsPalindrom := false; break;
    end;
end;
begin
  write('Введите слово: '); readln(s);
  if IsPalindrom(s) then writeln('Слово - палиндром')
  else writeln('Слово - НЕ палиндром');
end.

 if s[i] <> s[length(s) - i - 1] then beginif s[i] <> s[length(s) - i + 1] then beginOleg_D писал(а):Если количество букв в слове НЕЧЁТНОЕ, то среднюю букву сравнивать саму с собой нет смысла.
if arg[i] <> arg[Length(arg)-i+1]

Oleg_D писал(а):Потому, что в выражении:сравниваются первая и последняя буква, вторая и предпоследняя и т.д. в цикле вплоть до средней буквы (но исключая её), если длина нечётная.
- Код: Выделить всё
if arg[i] <> arg[Length(arg)-i+1]
Завтра утром вам это станет ясно, как белый день.
for i:=1 to Length(arg) div 2if arg[i] <> arg[Length(arg)-i+1]Подскажите мне, вот сколько вы учились, чтобы понимать паскаль, как вы понимаете сейчас?

function checkword(var arg:string):boolean;
var i,j:integer;
begin
  checkword:=true;
  j:=0;
  for i:=length(arg) downto 1 do begin
    while j<length(arg) do begin
      inc(j);
      break;
    end;
    if arg[i]<>arg[j] then begin
      checkword:=false;
      break;
    end;
  end;
end;
var s:string;
begin
  writeln('введите слово');
  readln(s);
  if checkword(s) then
    writeln('это слово палиндром')
  else
    writeln('слово не является палиндромом');
  readln;
end.
deka47 писал(а):Минутку, а разве команда: for i:=1 to Length(arg) div 2 не делит, к примеру, слово с 13 символом на 2 и оставляет только первых 6 символов?
deka47 писал(а):У меня к вам еще один личный вопрос, вот я застреваю на таких задачках, с меня что-то будет? Потому-что я решил поступить на программирование, но не знаю получится ли что-то. Кажется что я туплю в каждой задаче и достаю вас здесь... Подскажите мне, вот сколько вы учились, чтобы понимать паскаль, как вы понимаете сейчас?
Vadim писал(а):Он учился всю жизнь и до сих пор учится.
 У каждого свой путь, кто-то тупит, тупит, а потом прорывает его, горизонт проясняется. Что тут посоветовать? Настойчивость и упорство -- хорошо. Но порой лучше не упираться рогом в одну задачу или вопрос, пройти немного вперёд, через 3-4 дня вернуться и вновь почитать. Обычно это помогает. И ещё экспериментировать надо, пробовать разные варианты решений. По моим ощущениям "песни" можно освоить за 6-12 месяцев. Когда я учился, никаких книг по Паскалю не было, пользовались скупыми техническими руководствами.
  У каждого свой путь, кто-то тупит, тупит, а потом прорывает его, горизонт проясняется. Что тут посоветовать? Настойчивость и упорство -- хорошо. Но порой лучше не упираться рогом в одну задачу или вопрос, пройти немного вперёд, через 3-4 дня вернуться и вновь почитать. Обычно это помогает. И ещё экспериментировать надо, пробовать разные варианты решений. По моим ощущениям "песни" можно освоить за 6-12 месяцев. Когда я учился, никаких книг по Паскалю не было, пользовались скупыми техническими руководствами.Paster Fob писал(а):
- Код: Выделить всё
while j<length(arg) do begin
inc(j);
break;
end;
 
    if j<length(arg) then Inc(j);
   Inc(j);

абсолютно верно.deka47 писал(а):
- Код: Выделить всё
if s[i] <> s[length(s) - i - 1] then begin
Вы, наверное, имели ввиду
- Код: Выделить всё
if s[i] <> s[length(s) - i + 1] then begin
Мы с самой строкой ничего не делаем. length(s) возвратит нам число -- длину строки, пусть n. Затем, мы будем проверять условие палиндромности исходя из его определения, сравнивая 1-ю букву с n-ной, 2-ю с (n-1) и т. д. То есть, сравниваем [i]-ю с [n-i+1]-ой. Как только найдем неравенство, условие палиндромности нарушено и можно завершать проверку. Перебрав индексы от 1 до (n div 2) заметим, что дальше продолжать нет смысла: при четном количестве одна половина уже полностью была сравнена с другой, а при нечетном -- остался один один символ, который сравнивать с самим собой смысла не имеет. Но если продолжить до конца -- на результат это не повлияет, просто работа будет проделана дважды: [1] с [n] и [n] с [1] и т.д.deka47 писал(а):А теперь вопрос, зачем мы делим строку на 2, мы обрезаем конец строки и средний символ?
Т.е. с слова "потоп" остается "по"? Но я не пойму логики, если так, то, к примеру слово "порок", тоже остается лишь "по", то почему он не выдает как палиндром? Это вопрос к Олегу, к решению задачи, которое предложено в книге.

Oleg_D писал(а):Paster Fob писал(а):
- Код: Выделить всё
while j<length(arg) do begin
inc(j);
break;
end;
Мудро накручено, не сразу понял.
Проще так:А ещё проще:
- Код: Выделить всё
if j<length(arg) then Inc(j);поскольку IF тоже лишний. К тому же в вашем решении цикл вдвое длиннее. Ну, опыт -- дело наживное.
- Код: Выделить всё
Inc(j);
function checkword(var arg:string):boolean;
var i,j:integer;
begin
  checkword:=true;
  j:=0;
  for i:=length(arg) downto length(arg) div 2 do begin
    inc(j);
  if arg[i]<>arg[j] then begin
      checkword:=false;
      break;
    end;
  end;
end;
var s:string;
begin
  writeln('введите слово');
  readln(s);
  if checkword(s) then
    writeln('это слово палиндром')
  else
    writeln('слово не является палиндромом');
  readln;
end.
function checkword(const arg: string): boolean;
var i, j: integer;
begin
  checkword:=true;
  j := (length(arg) + 1) div 2 + 1;
  for i := length(arg) div 2 downto 1 do begin
    if arg[i]<>arg[j] then begin
      checkword:=false; break;
    end;
    inc(j);
  end;
end;
function IsPalindrom(s: string): boolean;
var
  i, j: integer;
begin
  i := 1; j := length(s);
  while (i < j) and (s[i] = s[j]) do begin
    inc(i); dec(j);
  end;
  IsPalindrom := i >= j;
end;
Например, если речь идёт о показе отличающихся символов:deka47 писал(а):как бы сделать так, чтобы "запоминались" все местоположения?
procedure ShowPalDiff(const s: string; MarkSame, MarkDiff: char);
var
  i, j: integer;
  p: boolean;
begin
  writeln(s);
  j := length(s); p := true;
  for i := 1 to length(s) do begin
    if s[i] = s[j] then write(MarkSame)
    else begin 
      write(MarkDiff); p := false;
    end;
    dec(j);
  end;
  if p then writeln(^M'Это палиндром.', '':length(s)-14) 
  else begin
    writeln; writeln('Это НЕ палиндром.');
  end;
end;
var
  s: string;
begin
  write('Введите слово: '); readln(s);
  ShowPalDiff(s, '_', '^');
end.
Введите слово: pascal
pascal
^_^^_^
Это НЕ палиндром.
Введите слово: potop
potop
Это палиндром.

bormant писал(а):Перебрав индексы от 1 до (n div 2) заметим, что дальше продолжать нет смысла: при четном количестве одна половина уже полностью была сравнена с другой, а при нечетном -- остался один один символ, который сравнивать с самим собой смысла не имеет.
Да. Только "отсекаем" -- это в переносном смысле, строку мы никак не модифицируем, только берём из неё символы по индексу. Дело в чём, если мы в качестве инструмента выбрали по каким-то причинам цикл for, мы должны указать начальное и конечное значения счётчика цикла. Счётчиком нам достаточно пробежать только половину, посколько вторую половину мы будем получать "зеркально" от противоположного конца строки.deka47 писал(а):Т.е. мы отсекаем первую часть "строки". Мы сравнивамем 1 с последним, 2 с последним минус 1, 3 с последним минус 2. А потом уже нету смысла сравнивать последний минус 1 с вторым? Выходит слово "потоп", мы оставляем "оп" и сравниваем: "п"="п", "о"="о", верно? Буква "т" уже не затрагивается, потому что нету разницы какая она. Я верно понял?

Вернуться в Книга "Песни о Паскале"
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0