XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Общение> Трактир
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
Aspid

offline
Опыт: 8,361
Активность:
Вопрос по программированию № 2
помогите понять в чем ошибка. никак не могу.

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


Код:
program griclaba6;
uses crt;
var
a:string[100];
i,x,l:integer;
begin
clrscr;
writeln('Введите исходную строку');
read(a);
writeln('Введите желаемую длину');
read(x);
l:=length(a);
while l <> x do begin
for i:= 1 to l do begin
if a[i]= ' ' then a[i]:=a[i]+' '; {на этой строке выкидывает ошибку type mismatch}
end;
end;
readkey;
end.

Отредактировано Avatar, 29.11.2006 в 01:17.
Старый 28.11.2006, 22:41
NETRAT

offline
Опыт: 83,712
Активность:
хм, лол, а кто точки с запятой ставить будет? и еще это хреновое выравнивание - сначала нужно посчитать количество слов в строке(N), разделить количество добавляемых пробелов на N-1 и постепенно добавлять эти пробелы в строку, не забывая при этом что число пробелов может быть не целое - поэтому нужно хранить остаточное количество пробелов и добавлять их перед последним словом.
м.б. напишу код, правда за синтаксис не отвечаю - паскалем давно не пользуюсь

NETRAT добавил:
и не только точка с запятой, здесь ты к символу добавляешь число, а не складываешь строки

NETRAT добавил:
и вообще ты не добавляешь, а сравниваешь, ибо
Код:
a[i]=a[i]+' '
это же не присвоение
Старый 29.11.2006, 00:29
Aspid

offline
Опыт: 8,361
Активность:
елы. это я просто в спешке набирал и не проверял. исправил.
Цитата:
м.б. напишу код, правда за синтаксис не отвечаю - паскалем давно не пользуюсь

буду благодарен. у мну что-то ничерта не получаицо.
Старый 29.11.2006, 01:18
tysch_tysch
Работаем
offline
Опыт: отключен
Код:
a[i]:=a[i]+' '

или я туплю или ты тут присваиваешь переменной типа char переменную типа string[2]
так как фактически a[i] - это символ в строке
a[i]+' ' есть строка из 2-х символов
Старый 29.11.2006, 01:36
Aspid

offline
Опыт: 8,361
Активность:
я перебираю в цикле строку.
проверяю
Код:
if a[i]= ' '

если символ = пробел
тогда
Код:
a[i]:=a[i]+' '

приплюсовываю исчо 1 пробел.
Старый 29.11.2006, 02:10
NETRAT

offline
Опыт: 83,712
Активность:
нет, это бред, работать не будет
Старый 29.11.2006, 02:20
Aspid

offline
Опыт: 8,361
Активность:
почему?
Старый 29.11.2006, 02:22
NETRAT

offline
Опыт: 83,712
Активность:
Естественно, синтаксические ошибки будут, думаю, сам справишься
Код:
program griclaba6;
uses crt;
var
in,out:string[255];
len,wantedlen,wordscount,wordswritten,spacestoadd,wordslen,i,t:integer;
wflag:boolean;
begin
clrscr;
writeln('Введите исходную строку');
read(in);
writeln('Введите желаемую длину');
read(wantedlen);

len:=length(in); // Длинна входной строки

// Подсчитываем количество слов в предложении
wordscount:=0; // Количество слов в предложении
wordslen:=0; // Реальная длинна слов предложения (длинна предложения за вычетом количества пробелов)
wflag:=false; // Флаг, необходимый для подсчета количества слов
for i:=1 to len do
begin
if (in[i]=' ') then
begin
if (wflag) then
begin
// Найдено слово
wordscount:=wordscount+1;
wflag:=false;
end
end
else
begin
// Найдены признаки слова (не пробелы)
wordslen++;
wflag:=true;
end
end
// Не забыть посчитать последнее слово
if (wflag) then wordscount:=wordscount+1;

wantedlen:=wantedlen-wordslen; // реальное количество пробелов, в предложении, которое мы должны сгенерировать

if (wantedlen<0) then
begin
// Длинна выходного предложения меньше длинны слов - то есть потеря значащих символов
writeln('Impossible to stretch down sentence, need to add %d < 0 spaces\n',wantedlen);
getch();
return -1;
end
if (wantedlen<wordscount-1) then
begin
// Если так расставлять пробелы, то некоторые слова просто сольются - им не хватит места для пробела
writeln('This will merge all words because number of spaces is lower than needed (%d < %d)\n',wantedlen,wordscount-1);
getch();
return -1;
end
if (wordscount=0) then
begin
// В предложении нет слов
writeln('Empty sentence\n');
getch();
return -1;
end
if (wordscount=1) then
begin
// В предложении только одно слово - нет нужды расставлять пробелы, правда, удалить можно, но это я делать не стал, так как это обычная функция Trim
writeln('There is no need to stretch sentence with one word\n');
getch();
return 0;
end
// Расставляем пробелы
spacestoadd:=wantedlen/(wordscount-1); // количество пробелов после каждого слова, кроме предпоследнего
wordswritten:=0; // обработано слов
wflag:=false;
for i:=1 to len do
begin
if (in[i]=' ') then
begin
if (wflag) then
begin
// Слово закончилось, записать пробелы
wordswritten:=wordswritten+1;
if (wordswritten=wordscount-1)
begin
// Пишем последнее слово - перед ним нужно добавить не меньше пробелов чем перед всеми остальными
for t:=1 to wantedlen-spacestoadd*(wordswritten-1) do out:=out+' ';
end;
else
begin
// Пишем не последнее слово
for t:=1 to spacestoadd do out:=out+' ';
end;
wflag:=false;
end
end
else
begin
// Слово идет
out:=out+in[i];
wflag:=true;
end
end
// Вывод предложения
writeln(out); // это лучше выводить в кавычках что бы хорошо видно было что в конце никаких пробелов нет
readkey;
end.

На всякий случай, изоморфный
» код на C
Код:
#include "conio.h"
#include "string"
using namespace std;

int _tmain()
{
string in="shit happensX",out;
int len,wantedlen=100,wordscount,wordswritten,spacestoadd,wordslen,i;
bool wflag;

len=in.length(); // Длинна входной строки

// Подсчитываем количество слов в предложении
wordscount=0; // Количество слов в предложении
wordslen=0; // Реальная длинна слов предложения (длинна предложения за вычетом количества пробелов)
wflag=false; // Флаг, необходимый для подсчета количества слов
for (i=0;i<len;i++)
{
if (in[i]==' ')
{
if (wflag)
{
// Найдено слово
wordscount=wordscount+1;
wflag=false;
}
}
else
{
// Найдены признаки слова (не пробелы)
wordslen++;
wflag=true;
}
}
// Не забыть посчитать последнее слово
if (wflag) wordscount=wordscount+1;

wantedlen=wantedlen-wordslen; // реальное количество пробелов, в предложении, которое мы должны сгенерировать

if (wantedlen<0)
{
// Длинна выходного предложения меньше длинны слов - то есть потеря значащих символов
_cprintf("Impossible to stretch down sentence, need to add %d < 0 spaces\n",wantedlen);
getch();
return -1;
}
if (wantedlen<wordscount-1)
{
// Если так расставлять пробелы, то некоторые слова просто сольются - им не хватит места для пробела
_cprintf("This will merge all words because number of spaces is lower than needed (%d < %d)\n",wantedlen,wordscount-1);
getch();
return -1;
}
if (wordscount==0)
{
// В предложении нет слов
_cprintf("Empty sentence\n");
getch();
return -1;
}
if (wordscount==1)
{
// В предложении только одно слово - нет нужды расставлять пробелы, правда, удалить можно, но это я делать не стал, так как это обычная функция Trim
_cprintf("There is no need to stretch sentence with one word\n");
getch();
return 0;
}
// Расставляем пробелы
spacestoadd=wantedlen/(wordscount-1); // количество пробелов после каждого слова, кроме предпоследнего
wordswritten=0; // обработано слов
wflag=false;
for (i=0;i<len;i++)
{
if (in[i]==' ')
{
if (wflag)
{
// Слово закончилось, записать пробелы
wordswritten=wordswritten+1;
if (wordswritten==wordscount-1)
{
// Пишем последнее слово - перед ним нужно добавить не меньше пробелов чем перед всеми остальными
for (int t=0;t<wantedlen-spacestoadd*(wordswritten-1);t++)
out=out+" ";
}
else
{
// Пишем не последнее слово
for (int t=0;t<spacestoadd;t++)
out=out+" ";
}
wflag=false;
}
}
else
{
// Метод извратный (следующие две строки), но мне вломы делать хорошо =)
char bu[]="?";
bu[0]=in[i];
// Слово идет
out=out+string(bu);
wflag=true;
}
}
// Вывод предложения и его длинны
_cprintf("'%s' [%d]\n",out.c_str(),out.length());
getch();

return 0;
}
, полностью рабочий

Программа удаляет все пробелы в исходном предложении и расставляет их заново. По крайней мере так я себе представляю нормальный стретч
Старый 29.11.2006, 03:24
Aspid

offline
Опыт: 8,361
Активность:
спасибо! кстати синтаксис практически полностью верный.
Старый 29.11.2006, 03:33
NETRAT

offline
Опыт: 83,712
Активность:
Странно... Проверь везде ли после end стоит точка с запятой и проверь индексы строк (в С начинаются с 0, а в паскале - с 1), так вроде все нормально. Печатает строку?

NETRAT добавил:
Как видишь, задача не такая простая как кажется на первый взгляд, простым добавлением пробелов после слов она не решается...

NETRAT добавил:
ага, забыл заменить getch() = readkey
Старый 29.11.2006, 03:37
Aspid

offline
Опыт: 8,361
Активность:
ну точки с запятыми это фигня.

Avatar добавил:
да это я сам сделал. я понял что это readkey

Avatar добавил:
wordslen++ хмм только вот это непонятно....это по моему не из той оперы...
Старый 29.11.2006, 03:39
NETRAT

offline
Опыт: 83,712
Активность:
wordslen++
равносильно
inc(wordslen)
равносильно
increase(wordslen)
равносильно
wordslen:=wordslen+1

NETRAT добавил:
А ты как думаешь почему язык называется С++ ? =)
Старый 29.11.2006, 03:44
Aspid

offline
Опыт: 8,361
Активность:
точки с запятыми расставил
Код:
return -1;

=)крута а я 5 минут думал почему он писал неизвестный индетификатор.
спасибо щас все переделаю.
Старый 29.11.2006, 03:53
Wolfeg
oldfag
offline
Опыт: 23,207
Активность:
Цитата:
ага, забыл заменить getch() = readkey

можно просто getch()
Старый 29.11.2006, 05:00
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 01:40.