Помощь - Поиск - Пользователи - Календарь
Полная версия: Выравнивание текста по ширине
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Feagor
задача такова дана символьная матрица матрица n*m, вводятся строки длиной m<=255
затем текст выравнивается по ширине, т.е. добавить пробелы в местах где они есть, но так чтобы их разница между их количеством различалась не больше чем на 1.
Собственно листинг:

uses crt;
var a:array[1..255,1..255] of char;
b,probeli:array[1..255] of integer;
s:string;
i,n,m,j,k:integer;
begin
clrscr;
writeln('Vvedite chisla n,m(kolichestvo strok,dlina stroki)');
readln(n,m);
for i:=1 to n do
begin
writeln('Vvedite ',i,' stroku');
readln(s);
b[i]:=length(s);
for j:=1 to m do a[i,j]:=s[j];
end;
{ for i:=1 to n do writeln(b[i]);}
for i:=1 to n do
begin
for j:=1 to b[i] do if a[i,j]=' ' then probeli[i]:=probeli[i]+1;
{writeln(probeli[i]);}
if b[i]<m then
begin
for j:=1 to b[i] do s[j]:=a[i,j];
j:=1;
while j<=b[i] do
begin
if s[j]=' ' then
begin
for k:=1 to ((m-b[i]) div probeli[i]) do insert(' ',s,j);
end;
j:=j+((m-b[i]) div probeli[i])+1;
end;
for j:=1 to m do a[i,j]:=s[j];
end;
end;
for i:=1 to n do begin
writeln;
for j:=1 to m do write(a[i,j]);
end;
readkey;
end.


работает правда не правильно=(
andriano
1. Предполагаю, что в условии ошибка: матрица не n*m, а m*n.
2. Не понял, что делает фрагмент:
                 j:=1;
while j<=b[i] do
begin
if s[j]=' ' then
begin
for k:=1 to ((m-b[i]) div probeli[i]) do insert(' ',s,j);
end;
j:=j+((m-b[i]) div probeli[i])+1;
end;

Скорее всего, именно он и должен вставлять пробелы внутрь строки. Но почему-то делается это с фиксированным шагом.
Ведь, насколько я понял из условия, количество вставляемых пробелов должно быть неодинаковым в разных местах - чтобы обеспечить на выходе фиксированную длину строки.
Это разумно делать с помощью двух вложенных циклов:
- во врутреннем вставляется по одному пробелу в каждую последовательность пробелов,
- во внешнем эта операция повторяется до тех ор, пока строка не примет нужную длину.

k := 1; // счетчик внешнего цикла, а заодно - длина последовательности пробелов (сколько пропускать)
repeat
j := 1;
while (j < length(s)) and (length(s) < m) do begin
if s[j] = ' ' then begin // найдя пробел, вставляем еще один и "перепрыгиваем" через всю последовательность пробелов
insert(' ',s,j);
inc(j,k);
end;
inc(j);
end;
inc(k);
until length(s)=m;

Еще пара замечаний:
- искать длину строки можно и сразу во втором цикле,
- целесообразно перед началом обработки строки исключить из нее все двойные пробелы, а также пробелы в начале и конце.
Feagor
Цитата(andriano @ 18.12.2007 11:49) *

1. Предполагаю, что в условии ошибка: матрица не n*m, а m*n.

Нет в условии все верно n строк и m столбцов
За поправку спасибо, щас проверю...
andriano
Размер принято указывать в виде (размер по X)[*|x](размер по Y). Мы же не говоим 480x640 или 1024x1280.
Feagor
Цитата(andriano @ 18.12.2007 14:29) *

Размер принято указывать в виде (размер по X)[*|x](размер по Y). Мы же не говоим 480x640 или 1024x1280.

размер матрицы указывается не как x*y а как количество строк на количество столбцов...не веришь можешь почитать началы мат.анализа...хотя не советую - гадкая вещь lol.gif
Feagor
че-то все перепроверил все равно не работает, почему то тупо в конец дорисовывает пробелы=(
Client
Цитата
работает правда не правильно=(
А у меня она даже не компилируется blink.gif
andriano
Цитата(Feagor @ 18.12.2007 19:33) *

че-то все перепроверил все равно не работает, почему то тупо в конец дорисовывает пробелы=(

Ты свой прежний вариант, или тот, что предложил я?
Если последний, притом, с учетом предложенных остальных исправлений, должно работать (за одним исключением - если в строке изначально нет ни одного пробела).
Посмотри законченый вариант:
uses crt;
const
m = 20;
n = 10;
var
a:array[1..n,1..m] of char;

procedure FillArray; // заполнение массива
var
i,j,k : integer;
ch : char;
begin
for i := 1 to n do
for j := 1 to m do
a[i,j] := ' ';
for i := 1 to n do begin
k := m div 2 + random(m div 2);
for j := 1 to k do
if random(6) > 0 then
a[i,j] := 'O';
end;
end;

procedure WriteArray; // вывод массива на печать
var
i,j,k : integer;
ch : char;
begin
for j := 1 to n do begin
write(' [');
for i := 1 to m do
write(a[j,i]);
writeln(']');
end;
writeln('==============================');
end;

var
s:string;
i,j,k,b:integer;
begin
FillArray;
WriteArray;
for i:=1 to n do begin // перебор по строкам массива
s := '';
for j := 1 to m do
s := s + a[i,j]; // переносим из строки массива в переменную типа строки
while s[length(s)] = ' ' do delete(s,length(s),1); // удаляем пробелы в начале и конце строки
while s[1] = ' ' do delete(s,1,1);
b := length(s);
write(b:3,' <',s); // по мере подсчета постепенно выводим, что мы делаем
if (b < m) and (pos(' ',s) > 0) then begin // если в строке нет пробелов - ничего не поделаешь sad.gif
k := 1; // счетчик внешнего цикла, а заодно - длина последовательности пробелов (сколько пропускать)
repeat
j := 1; // бежим вдоль строки
while (j < length(s)) and (length(s) < m) do begin
if s[j] = ' ' then begin // найдя пробел, вставляем еще один и "перепрыгиваем" через всю последовательность пробелов
insert(' ',s,j);
inc(j,k);
end;
inc(j);
end;
inc(k);
write(' k=',k);
until length(s) = m;
for j:=1 to m do a[i,j]:=s[j];
end;
writeln('>');
end;
WriteArray;
readkey;
end.

Feagor
спасибо andriano работает!!!!
2client я работаю в FPC и у мну все норм компилится, для TP7 он орет слишком много переменных, попробуй уменьшить количество строк в матрице...при уменьшении от 255 до 25 работает
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.