Текст, сформированный построчно, выровнять по правому краю так, чтобы каждая строка заканчивалась знаком препинания или одним пробелом. Выравнивание осуществить, вставляя дополнительные пробелы между словами(равномерно по всей строке).
Текст | ||
There are many big and small libraries everywhere in our country. They have millions of books in different languages. Every school has a library. Pupils come to the library to take books on different subjects. |
||
Результат | ||
|
Код программы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
#include <cstdlib> #include <iostream> #include <vector> #include <cstring> using namespace std; int main() { vector<string> v; string sm; while( getline(cin, sm) ) { v.push_back(sm); } int p[v.size()]; // Количество пробелов в строке int max=0; for( int i=0 ; i<(int)v.size() ; i++ ) { p[i]=0; string s; for( int j=0 ; j<(int)v[i].length() ; j++ ) { if( v[i][j] != ' ' ) { s+= v[i][j]; } else if( v[i][j+1] != ' ' ) { s+=' '; p[i]++; } } if( s[0] == ' ' ) { s.erase(0, 1); p[i]--; } if( s[s.length()-1] == ' ' )// Если в конце пробел, то число пробелов все равно нужно уменьшить, так как он не будет участвовать в выравнивании по ширине { if( strchr( ",.!-?:\"\'", s[s.length()-2] )!=NULL ) s.erase(s.length()-1, 1); // И если в конце стоит знак препинания, то пробел в конце не нужен p[i]--; } v[i] = s; // Заменяем неотформатированный вариант отформатированным if( max < (int)v[i].length() ) { max = (int)v[i].length(); } } for( int i=0 ; i<(int)v.size() ; i++ ) // Затем второй проход строк { int k = (int)v[i].length(); // Резервируем длину строки, так как она сейчас будет изменяться, а нам нужно при вычислениях учитывать исходные данные for( int j=0 ; j<(int)v[i].length() ; j++ ) { if( v[i][j] == ' ' && j+1!=(int)v[i].length() ) { v[i].insert(j, (max-k)/p[i], ' '); // Вставляем нужное количество пробелов между строк (так чтобы их было равное количество) j+=(max-k)/p[i]; // Смещаем указатель проходящий все символы в строке } } v[i].insert(0, (max-k)%p[i], ' '); // Оставшиеся пробелы вставляем в начало чтобы выровнять строку по правому краю } for( int i=0 ; i<(int)v.size() ; i++ ) { cout << v[i] << endl; } } |
По условию задачи необходимо сформированный построчно текст выровнять по правому краю, равномерно вставляя дополнительные пробелы между словами.
Алгоритм:
Описываем и считываем строки. Затем описываем количество пробелов в строке и длину самой длинной строки (относительно которой и будет производится выравнивание по правому краю).
При проходе строк создаем счётчик для подсчета пробелов. Создаем строку и вводим в нее форматированный вариант представления строки на которую указывает указатель i, потом убираем ведущий пробел. Увеличиваем счетчик каждый раз когда встречаем пробел. Убираем ведущий пробел.
Если в конце пробел, то число пробелов все равно нужно уменьшить, так как он не будет участвовать в выравнивании по ширине. И если в конце стоит знак препинания, то пробел в конце не нужен. Затем заменяем неотформатированный вариант отформатированным и ищем максимум. Мы последовательно форматируем строку, а потом находим максимум уже среди отформатированных строк.
Затем второй проход строк.
Резервируем длину строки, так как она сейчас будет изменяться, а нам нужно при вычислениях учитывать исходные данные. Проходим все символы строки и если это пробел (конечно же, не учитывая заключающий пробел), то вставляем нужное количество пробелов между строк (так чтобы их было равное количество).
Смещаем указатель проходящий все символы в строке. Теперь оставшиеся пробелы вставляем в начало чтобы выровнять строку по правому краю.
Для проверки работы программы можно воспользоваться объектом.