Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.03.2012, 13:16   #1
weech
Пользователь
 
Аватар для weech
 
Регистрация: 16.11.2011
Сообщений: 91
По умолчанию Переполнение строки

Не могу понять, почему, подскажите, пожалуйста. Участок кода с ошибкой выделен.

Программа должна определять, можно ли из введеннйо последовательности прописных латинских букв составить палиндром и если да, то вывести его.
Код:
var
   i,k,l:integer;
   s:string;
   a:array [65..90] of integer;
begin
s:=''; k:=0;
for i:=65 to 90 do a[i]:=0;
    readln(s);
    l:=length(s);
for i:=1 to l do inc(a[ord(s[i])]);
    s:='';
for i:=90 downto 65 do
  if odd(a[i])
    then
       begin
       inc(k);
       
       if k=2
          then
              begin
              writeln('No');
              break;
              end;
       if s=''
          then
              begin
              s:=chr(i);
              Dec(a[i]);
              end
          else
              begin
              Insert(chr(i),s,length(s) div 2);
              Dec(a[i]);
              end;
       end
    else
        repeat
        s:=chr(i)+s+chr(i);
        Dec(a[i],2);
        until a[i]=0;
writeln('Yes ', s);
end.
weech вне форума Ответить с цитированием
Старый 27.03.2012, 13:24   #2
dann.ftk
http://resumup.com
 
Регистрация: 18.12.2011
Сообщений: 9
По умолчанию

Возможно, a[i] равно нулю до того, как ты вычитаешь из него 2
Тогда a[i] становится отрицательным -> переполнение

Еще можно задать слишком длинную строку, например 255 символов (это вроде стандарт для Паскаля при определении типа string без явного указания размера)
Тогда переполнение будет из-за того, что к этой строке ты прибавляешь еще что-то и переприсваиваешь -> переполнение
dann.ftk вне форума Ответить с цитированием
Старый 27.03.2012, 14:03   #3
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от dann.ftk
Возможно, a[i] равно нулю до того, как ты вычитаешь из него 2
подтверждаю. так и есть. проверки на то, что в A[i] ноль - нет!


такое решение устроит?

Код:

var
   ch, Center : char;
   i, k  : integer;
   s  : string;
   a  : array ['A'..'Z'] of integer;
begin
  s:='';
  for ch:='A' to 'Z' do a[ch]:=0;

  repeat
    WriteLn('Введите строку из прописных латинских букв: ');
    readln(s);
    k:=0;
    for i:=1 to length(s) do
      if not( s[i] in ['A'..'Z']) then inc(k);
  until (length(s)>0) and (k=0);

  for i:=1 to length(s) do inc(a[s[i]]);

  {сначала определим, можно ли составить палиндром.
   для этого проверим, сколько непарных букв в строке (нечётных).
   таких допускается не более ОДНОЙ!}
  k:=0;
  Center := #0;
  for ch:='A' to 'Z' do 
    if odd(a[ch]) then begin
       inc(k);
       Center := ch; {запомним, какой символ встречался нечётное число раз!}

       {и УМЕНЬШИМ на единицу счётчик этого символа, теперь там будет чётное чило (или ноль)}
       dec( a[ch] )
    end;

  if k>1 then WriteLn('Палиндром составить нельзя!')
  else begin
    {можно составить. чем мы и займёмся!}

    if k=0  {в строке нет непарных элементов}
      then s := ''
      else s := Center; {иначе непарный сразу поставим в центр строки}

    for ch:='Z' downto 'A' do
      if (a[ch]>0) and not odd(a[ch]) 
      then
        for i:=1 to (a[ch] div 2) do s:= ch+s+ch;

    WriteLn('YES! Палиндром: ',s);

  end;   
  Readln
end.

Последний раз редактировалось Serge_Bliznykov; 28.03.2012 в 09:24. Причина: исправил недочёт в коде!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 27.03.2012, 16:49   #4
weech
Пользователь
 
Аватар для weech
 
Регистрация: 16.11.2011
Сообщений: 91
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
такое решение устроит?
Ну вообще-то не совсем:


Не соображу, почему отбрасывает часть...
weech вне форума Ответить с цитированием
Старый 28.03.2012, 09:23   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Не соображу, почему отбрасывает часть...
почему, почему... потому что я в алгоритме ОШИБКУ допустил.
нечётный элемент я то в центр помещаю. Но я совершенно упустил из виду, что нечётный - это совсем не обязательно 1 (ОДИН) элемент, может быть и три и пять и семь т.д...

вот, можно так:
Код:
  {сначала определим, можно ли составить палиндром.
   для этого проверим, сколько непарных букв в строке (нечётных).
   таких допускается не более ОДНОЙ!}
  for ch:='A' to 'Z' do 
    if odd(a[ch]) then begin
       inc(k);
       Center := ch; {запомним, какой символ встречался нечётное число раз!}

       {и УМЕНЬШИМ на единицу счётчик, теперь там будет чётное чило (или ноль)}
       dec( a[ch] )    
  end;
p.s. в коде выше я тоже подправлю (так, чтобы всё было чистенько и аккуратенько!)

p.p.s. приношу извинения за такую досадную промашку с моей стороны!

Последний раз редактировалось Serge_Bliznykov; 28.03.2012 в 09:25.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 28.03.2012, 16:00   #6
weech
Пользователь
 
Аватар для weech
 
Регистрация: 16.11.2011
Сообщений: 91
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
p.p.s. приношу извинения за такую досадную промашку с моей стороны!
Да бросьте вы, все мы люди Спасибо за помощь, исправил у себя по подобию.
weech вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Переполнение стека DeKot Общие вопросы Delphi 4 02.02.2012 01:28
Переполнение stas45rus Паскаль, Turbo Pascal, PascalABC.NET 1 11.01.2012 20:54
Переполнение деления!!! zero-cool Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 5 28.09.2010 21:10
Переполнение стека Ake Паскаль, Turbo Pascal, PascalABC.NET 3 30.05.2009 22:39
Переполнение Стека Викдон Паскаль, Turbo Pascal, PascalABC.NET 0 19.12.2008 19:16