Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab_3.doc
Скачиваний:
3
Добавлен:
14.11.2019
Размер:
298 Кб
Скачать
☆

Форматирование строки

Форматирование строки - размещение ее в выходном массиве заданной размерности таким образом, чтобы интервалы между соседними словами отличались не более, чем на 1.

1. Исходные данные и результат. Входная строка произвольной длины в массиве IN[], отформатированная строка длины n в массиве OUT[]. Выходная строка отвечает следующим требованиям:

  • слово - любая последовательность символов, кроме пробела;

  • после форматирования число пробелов между словами различается не более чем на 1;

  • первое и последнее слово расположены по краям строки.

2. Форматирование включает в себя последовательность из трех действий:

void format(char IN[], char OUT[], int n)

{

Собрать исходные данные по строке, необходимые для форматирования;

Проверить возможность форматирования;

Разместить слова в выходной строке.

}

3. Данные по строке, необходимые для форматирования:

  • количество слов в строке - nw;

  • общее количество символов во всех словах - ns;

  • стандартное количество пробелов междлу словами

  • при форматировании - np;

  • оставшееся количество пробелов, добавляемых

  • по одному между словами - nr.

На этом шаге детализируется проверка возможности форматирования и определяются взаимосвязанные параметры.

void format(char IN[], char OUT[], int n)

{

int nw, ns, np, nr;

...Определение nw, ns ...

OUT[0] = '\0';

if (nw < 2) return; // Мало слов в строке

np = (n - ns) / (nw - 1);

if (np <= 0) return; // Много символов в словах

nr = (n - ns) % (nw - 1); // Остаточное число пробелов

...Размещение слов в выходной строке...

}

4. Просмотр строки при определении параметров и форматировании можно выполнить, используя:

  • цикл просмотра всех слов, в который включен цикл посимвольного просмотра интервала между словами и самого слова;

  • цикл посимвольного просмотра строки, с использованием признака нахождения внутри слова - inword.

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

5. Определение ns, nw:

for (i=0,ns=0,nw=0,inword =0; ; i++)

{

// анализ символа IN[i] и подсчет параметров;

if (IN[i] =='\0') break;

}

6. Размещение слов в выходной строке:

for (i=0,j=0,inword =0; ; i++)

{

// анализ символа IN[i] и форматирование (перенос в OUT[j]);

if (IN[i] =='\0') break;

}

7. Анализ символа состоит в выделении 4 вариантов по двум сравнениям - признака inword и типа символа IN[i] разделителя или символа слова:

if (IN[i]==' ' || IN[i]=='\0')

if (inword)

{ nw++; inword =0; } // конец слова

else

{} // продолжение

else // разделителя

{ ns++;

if (inword)

{} // продолжение

else // слова

{ inword =1; } // начало слова

}

8. Анализ символа IN[i] и форматирование:

if (IN[i]==' ' || IN[i]=='\0')

if (inword)

{ // конец слова

for (k=0; k<np; k++) // включение "np"

OUT[j++]=' '; // пробелов

if (nr-- >0) // включение

OUT[j++]=' '; // дополнительного пробела

}

else

{} // продолжение

else // разделителя

if (inword)

OUT[j++]=IN[i]; // продолжение

else // слова

{ // Начало слова

OUT[j++]=IN[i];

inword =1;

}

Окончательный вариант с оптимизацией (исключение лишних ветвей):

// форматирование строки

void format(char IN[], char OUT[], int n)

{

int nw, ns, np, nr, i, j, k, inword;

for (i=0, ns=0, nw=0, inword =0; ; i++)

{

if (IN[i]==' ' || IN[i]=='\0')

{ if (inword) { nw++; inword =0; } }

else

{ ns++; inword=1; }

if (IN[i] =='\0') break;

}

OUT[0] = '\0';

if (nw < 2) return;

np = (n - ns) / (nw - 1);

if (np <= 0) return;

nr = (n - ns) % (nw - 1);

for (i=0,j=0,inword=0; ; i++)

{

if (IN[i]==' ' || IN[i]=='\0')

{ if (inword)

{

for (k=0; k<np; k++) OUT[j++]=' ';

if (nr-- >0) OUT[j++]=' ';

}

}

else

{ OUT[j++]=IN[i]; inword =1; }

if (IN[i] =='\0') break;

}

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]