2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу 1, 2, 3  След.
 
 простой вопрос по Pascal
Сообщение10.05.2014, 20:53 
Аватара пользователя
Помогите чайнику!

Пишу небольшую программку на Паскаль (лет 20 не писал) и вот трудность:
тут на входе строка W, состоящая из последовательности символов a1 и b1.
Я хочу заменить все a1 на х и все b1 на у, получив строку R вдвое меньшей длины:
Код:
Program o;
var W,R: string;
var i,n: integer;

begin
readln(W);
n:=length(W);

for i:=1 to n do
begin
if i mod 2=0 then
  if W[i-1]+W[i]='a1' then R[i div 2]:='x';
if W[i-1]+W[i]='b1' then R[i div 2]:='y';
   end;
writeln(R);
end.

И нифига он не выдает R и еще пишет, что Length(R)=0. Хотя любой элемент R[i] по отдельности выдает.

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 21:28 
Аватара пользователя
alcoholist
Всё правильно пишет. Вы не установили длину строки.
К примеру можно
R:=W; или R:=Copy(w); А после удалить лишнее с конца строки.

За 20 лет формат строк в паскале сильно изменился. С символьных массивов до специального типа. Совет прочитайте про форматы строк в вашем компиляторе. В разных компиляторах строки имеют разный формат.
В вашем коде ещё одна ошибка - выходит за пределы строки. Символы в паскаливских строках, как правило, начинаются с 1.

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 21:38 
Аватара пользователя
Pavia в сообщении #861460 писал(а):
W[i-1] выходит за пределы строки


ну, я мог бы написать
Код:
for i:=1 to n div 2 do
begin
   if W[2*i-1]+W[2*i]='a1' then R[i]:='x';
if W[2*i-1]+W[2*i]='b1' then R[i]:='y';

это непринципиально.

Сейчас
Pavia в сообщении #861460 писал(а):
К примеру можно
R:=W; или R:=Copy(w)


Не понял. Мне же заменить символы надо.
Pavia в сообщении #861460 писал(а):
Вы не установили длину строки.

Мне конечно надо чтобы длина была произвольной (зависит от вводимых данных). Но даже если руками поставить длину R: string[4] и ввести W длины 8, то результат тот же неутешительный

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 21:54 
Аватара пользователя
У Вас строка R со старта пустая, там нет R[i]

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 22:02 
Ну это просто какая-то нелепость. Если заранее известно, что входная строка корректна, то надо попросту

Используется синтаксис Pascal
R='';
for i:=1 to length(W) div 2 do
    if W[i*2-1]='a'
        then R:=R+'x'
        else R:=R+'y';

Если же неизвестно, то надо просто анализ корректности произвести предварительно.

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 22:08 
Аватара пользователя
ewert в сообщении #861471 писал(а):
надо попросту

я для простоты написал про a1, b1 -- там по всякому может быть. Строку W надо воспринимать как состоящую из последовательных пар, а строка R -- последовательность этих пар.

-- Сб май 10, 2014 22:19:26 --

ewert, Xugin
я потом делаю некоторые манипуляции со строкой и она выводится, только вдвое меньшей длины

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 22:19 
Ну так поставьте задачу толком.

А так да, первопричина именно в том, что длина выходной строки не инициализирована. И это независимо от реализации строкового типа в том или ином варианте Паскаля ни к чему хорошему точно привести не может.

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

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 22:20 
Аватара пользователя
ewert, R='' не катит

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 22:23 
alcoholist в сообщении #861475 писал(а):
ewert, R='' не катит

Куда "не катит"?... Мой код -- версиенезависим, он использует только базовые конструкции Паскаля как такового.

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 22:27 
Аватара пользователя
ewert в сообщении #861474 писал(а):
Ну так поставьте задачу толком.


Ну, давайте так. На входе -- строка из xyz, yzx, xzy (или из n-ок каких-нибудь). Например xyzzxyyzxyzx.
На выходе нужна строка втрое меньшей длины (в n раз меньшей длины), в которой каждый xyz заменен на a, yzx -- на b, xzy -- на c.

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 22:27 
Если уж вникать в детали.

alcoholist в сообщении #861441 писал(а):
И нифига он не выдает R и еще пишет, что Length(R)=0.

Второе -- вполне естественно, первое же неверно: всё он выдаёт, просто Вы этого не видите (в полном соответствии со вторым).

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 22:28 
Аватара пользователя
ewert в сообщении #861477 писал(а):
Куда "не катит"?

результат тот же, что и без R''

-- Сб май 10, 2014 22:29:21 --

ewert в сообщении #861480 писал(а):
всё он выдаёт

если спросить writeln(R[k]) он выдает правильный результат для всех k

-- Сб май 10, 2014 22:31:39 --

ewert в сообщении #861480 писал(а):
Если уж вникать в детали.

Если не лень, то можете вставить
Код:
Program omega2;
var R,E,F,WW,W: string;
var ff,s,C,i,n,m,k,ly,ny: integer;
var p,q: char;


begin
readln(W);
n:=length(W);
C:=0;
m:=n div 2;

{R:='';}

 
for i:=1 to m do
begin
   if W[2*i-1]+W[2*i]='a1' then R[i]:='x';
if W[2*i-1]+W[2*i]='b1' then R[i]:='y';
   if W[2*i-1]+W[2*i]='a2' then R[i]:='z';
    if W[2*i-1]+W[2*i]='b2' then R[i]:='t';
     if W[2*i-1]+W[2*i]='A1' then R[i]:='a';
      if W[2*i-1]+W[2*i]='B1' then R[i]:='b';
       if W[2*i-1]+W[2*i]='A2' then R[i]:='c';
        if W[2*i-1]+W[2*i]='B2' then R[i]:='d';
end;

writeln(R[1]);
writeln(R);



  k:=0;
  for i:=1 to m do
  begin
  if R[i] in ['y','t','b','d'] then k:=k+1;
  end;
      ny:=k;
 
  k:=m;
  while R[k] in ['x','z','a','c'] do k:=k-1;
  ly:=k;
 

 
  repeat
            begin
            for k:=ly downto 2 do
                        begin
                        if R[k]='y' then
                                begin
                                if R[k-1]='z' then C:=C+1{F[k]};
                                if R[k-1]='c' then C:=C-1{F[k]};
                                end;
                        if R[k]='b' then
                                begin
                                if R[k-1]='z' then C:=C-1{F[k]};
                                if R[k-1]='c' then C:=C+1{F[k]};
                                end;           
    {остальные варианты}
                        p:=R[k];
                        Delete(R, k,1);
                        Insert(p, R, k-1);
                        end; 
            end;
           
        k:=ly;
        while R[k] in ['x','z','a','c'] do k:=k-1;
       
        ly:=k;
       
until ny<ly;

writeln(Length(R));


end.


на сайт http://www.compileonline.com/compile_pascal_online.php

На вход вставьте a1a1b1a1

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 22:32 
alcoholist в сообщении #861479 писал(а):
Ну, давайте так. На входе -- строка из xyz, yzx, xzy (или из n-ок каких-нибудь). Например xyzzxyyzxyzx.
На выходе нужна строка втрое меньшей длины (в n раз меньшей длины), в которой каждый xyz заменен на a, yzx -- на b, xzy -- на c.

Наиболее разумно -- завести массив входных кодов и массив соответствующих им выходных, а потом просто накапливать выходную строку в соответствующем двойном цикле. При этом как минимум выходные коды без каких-либо спецусилий могут быть более-менее произвольной длины (с переменностью длин входных несколько сложнее, не ненамного).

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 22:36 
Аватара пользователя
На вход вставьте a1a1b1a1

-- Сб май 10, 2014 22:41:12 --

ewert в сообщении #861482 писал(а):
Наиболее разумно -- завести массив входных кодов и массив соответствующих им выходных, а потом просто накапливать выходную строку в соответствующем двойном цикле.

это для меня слишком сложно

 
 
 
 Re: простой вопрос по Pascal
Сообщение10.05.2014, 22:42 
alcoholist в сообщении #861481 писал(а):
Если не лень, то можете вставить

Лень, чересчур длинно. Заводите исходные массивы кодов (разумнее всего -- в виде типизированных констант) и организуйте двойной цикл.

alcoholist в сообщении #861481 писал(а):
если спросить writeln(R[k]) он выдает правильный результат для всех k

Естественно. Дело в том, что Паскаль проверяет выход за пределы объявленного массива. Однако стандартные строки в Паскале (во всяком случае, в типичных паскалях) -- это фиксированные 255-байтные массивы. Вот только выход за этот 255-байтный предел компилятор и проверяет, на выход же за пределы текущей длины строки (хранящейся в начальном байте соотв. участка памяти) ему наплевать. Он же компилятор; он же не может предугадать, чему будет равно это значение по ходу работы.

Соответственно, Вы честно заполняете всю строку, и она в памяти хранится не менее честно. Однако при попытке её вывода Паскаль, не мудрствуя лукаво, в первую очередь смотрит на поле длины этой строки -- и в соответствии с ним и выводит. Что там фактически накоплено за этим полем -- его уже волнует очень мало.

 
 
 [ Сообщений: 35 ]  На страницу 1, 2, 3  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group