Страницы

Поиск по вопросам

среда, 18 декабря 2019 г.

Хороший стиль речи [закрыт]

#алгоритм


        
             
                
                    
                        
                            Закрыт. На этот вопрос невозможно дать объективный ответ.
Ответы на него в данный момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Update the question so it
can be answered with facts and citations by editing this post.
                        
                        Закрыт 4 года назад.
                                                                                
           
                
        
Участник форума Вова очень любит писать сообщения, опуская пробелы после знаков препинания
и забывая ставить заглавные буквы в начале предложения (ему почему-то кажется, что
это придает его сообщениям особый шарм). Модераторы уже устали делать замечания Вове
и решили попросить программистов форума написать простейший корректор, который будет
расставлять пробелы и делать буквы заглавными за Вову. 
Правила исправлений таковы:

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

Предложите свой вариант корректора. На вход подается текст, на выходе получается
текст.    


Ответы

Ответ 1



import re def correction(text): def callback(m): punct, word = m.groups() word = word.capitalize() if punct in ('.', '!', '?', '') else word.lower() return '%s %s' % (punct if punct else '', word) return re.sub(u'\s*(^|[.!?,:\s]|\.\.\.)?\s*([a-zA-Zа-яА-Я]+|$)', callback, text, re.U) Проверяем как работает: >>> print(correction(u'раз ,два, три , четыре, ПЯТЬ - вышел ZaIcHiK погулять.ТУТ охотник выбегает ...прямо в зайчика СТРЕЛЯЕТ ! КОНЕЦ .')) Раз, два, три, четыре, пять - вышел zaichik погулять. Тут охотник выбегает... прямо в зайчика стреляет! Конец.

Ответ 2



use utf8; sub correct{ my $string = shift; $string =~ s/(\w+)/\L$1/g; $string =~ s/(\w+)\s*([.,!?:]+)\s*/$1$2 /g; $string =~ s/(\A|[.!?]+)(\s*)(\w+)/$1$2\u$3/g; return $string; } print correct "раз ,два, три , четыри, ПЯТЬ - вышел ZaIcHiK погулять!ТУТ охотник выбегает ...прямо в зайчика СТРЕЛЯЕТ ? КОНЕЦ ."; Результат : Раз, два, три, четыри, пять - вышел zaichik погулять! Тут охотник выбегает... Прямо в зайчика стреляет? Конец. P.S позаимствовал пример для теста у Ilya Pirogov, надеюсь он не обидеться :) P.S Это решение на Perl

Ответ 3



string Corrector(string innerText, UserInfo userInfo) { var reg1 = new Regex(@"[\.\,\:\!\?][^\s]"); //после знака препинания нет пробела или переноса var reg2 = new Regex(@"[\.]\ [^А-ЯA-Z]"); //после точки и пробела не заглавная буква var reg3 = new Regex(@"\b[^А-ЯA-Z]"); //после переноса строки не заглавная буква var reg4 = new Regex(@"\ [\.\,\:\!\?]"); //пробел перед знаком препинания if(reg1.IsMatch(innerText) || reg2.IsMatch(innerText) || reg3.IsMatch(innerText) || reg4.IsMatch(innerText)) { return("Прошу прощения, товарищи. К сожалению, я безнадежно безграмотная соволочь! В связи с этим, не имею возможности в письменном виде высказать вам свою мысль."); } return innerText; }

Ответ 4



На PHP: function corrector($string){ $string=strtolower($string); $patterns = array(); $patterns[0] = '/ *\. */'; $patterns[1] = '/ *\, */'; $patterns[2] = '/ *\! */'; $patterns[3] = '/ *\? */'; $patterns[4] = '/ *\: */'; $replacements = array(); $replacements[0] = '. '; $replacements[1] = ', '; $replacements[2] = '! '; $replacements[3] = '? '; $replacements[4] = ': '; $string=preg_replace($patterns, $replacements, $string); $string=preg_replace('/\. \. \. /', '... ', $string); $string=preg_replace_callback( '/([\.\!\?]|(\.\.\.)) [a-zA-Zа-яА-Я]/', create_function( '$matches', 'return strtoupper($matches[0]);' ), $string ); $string=preg_replace_callback( '/^ *[a-zA-Zа-яА-Я]/', create_function( '$matches', 'return strtoupper($matches[0]);' ), $string ); return $string; } $string=" test . ..test ?teSt ."; echo corrector($string);

Ответ 5



Вот что у меня получилось на java + oop без regexp. Закодить различное форматирование для дефисов и тире банально не хватило терпения =/ input string (для наглядности строки в кавычках): ' hello DUMMY-user ! a lot of thanks ,- this is a "Hello World" Text ... just to check ' result string: 'Hello dummy - user! A lot of thanks, - this is a "hello world" text... just to check.' USE_CUSTOM_FORMATTERS - рубильник дополнительных форматтеров, которые нужны, но не были явно оговорены в условии задачи public class FormatStr { // debug mode switcher - dump results after each formatter private static boolean DEBUG = false; // additional formatters switcher - use additional formatters private static boolean USE_CUSTOM_FORMATTERS = true; public static void main(String[] args) { // create list List formatters = new LinkedList(); // add extra formatters if (USE_CUSTOM_FORMATTERS) { formatters.add(new DashFormatter()); formatters.add(new TrimStringFormatter()); formatters.add(new RemoveExtraWhitespacesFormatter()); } // add required formatters formatters.add(new LastDotFormatter()); formatters.add(new StringToLowerCaseFormatter()); formatters.add(new FirstCharToCapitalFormatter()); formatters.add(new SentenceFromUpperCaseCharFormatter()); formatters.add(new BeforePunctMarkFormatter()); formatters.add(new AfterPunctMarkFormatter()); // input str String str = " hello DUMMY-user ! a lot of thanks ,- this is a \"Hello World\" Text ... just \nto check "; dump("input string:", str); String result = str; for (ABaseFormatter sf : formatters) { result = sf.format(result); if (DEBUG) { dump("applied formatter " + sf.getClass().getName(), result); } } dump("result string:", result); } private static void dump(final String purpose, final String str) { System.out.println(purpose + "\n'" + str + "'\n"); } } abstract class ABaseFormatter { // private Set set = new HashSet(); public static Set SENTENCE_SEPARATOR_CHARS = new HashSet(); public static Set PUNCTUATION_CHARS = new HashSet(); static { Collections.addAll(SENTENCE_SEPARATOR_CHARS, '.', '!', '?'); Collections.addAll(PUNCTUATION_CHARS, ',', '.', '!', '?', ':'); } /** * Format string * * @param string */ public final String format(String string) { if (null == string) { return null; } return formatStr(string); } /** * Override to apply formatting to whole string * * @param str */ protected String formatStr(String str) { StringBuilder buff = new StringBuilder(str); // default behavior - apply per character formatting for (int i = 0; i < buff.length();) { i = formatChar(buff, i, buff.charAt(i)); } return buff.toString(); } /** * Override to apply formatting per char * * @param buff * @param pos * @param ch */ protected int formatChar(StringBuilder buff, int pos, char ch) { return pos + 1; } } class SentenceFromUpperCaseCharFormatter extends ABaseFormatter { @Override protected int formatChar(StringBuilder buff, int pos, char ch) { if (pos == 0) { // find first letter if possible while (pos < buff.length()) { if (Character.isLetter(buff.charAt(pos))) { buff.setCharAt(pos, Character.toUpperCase(buff.charAt(pos))); break; } pos++; } } return pos + 1; } } class AfterPunctMarkFormatter extends ABaseFormatter { @Override protected int formatChar(StringBuilder buff, int pos, char ch) { // add whitespace after punctuation mark if (PUNCTUATION_CHARS.contains(ch)) { // if dots are coming just move to next one if ('.' != ch) { // add whitespace between punct mark and word ch = buff.charAt(pos + 1); if (' ' != ch && '\n' != ch) { buff.insert(pos + 1, ' '); } } } return pos + 1; } } class BeforePunctMarkFormatter extends ABaseFormatter { @Override protected int formatChar(StringBuilder str, int pos, char ch) { // delete leading whitespaces before punctuation marks if (PUNCTUATION_CHARS.contains(ch)) { // count leading whitespaces to the punctuation mark; for (int start = pos; start > 1; start--) { char prevCh = str.charAt(start - 1); if (' ' != prevCh && '\n' != prevCh) { str.replace(start, pos, ""); pos = start + 1; break; } } // new sentence should start from upper case letter if (SENTENCE_SEPARATOR_CHARS.contains(ch) && (pos > 0 && str.charAt(pos - 1) != '.')) { // find first letter if possible while (pos < str.length()) { if (Character.isLetter(str.charAt(pos))) { str.setCharAt(pos, Character.toUpperCase(str.charAt(pos))); break; } pos++; } } } return pos + 1; } } class LastDotFormatter extends ABaseFormatter { @Override protected String formatStr(String str) { // default behavior - apply per character formatting for (int i = str.length() - 1; i >= 0; i--) { char ch = str.charAt(i); if (SENTENCE_SEPARATOR_CHARS.contains(ch)) { break; } // add end of sentence char to the last character // of the last sentence if (Character.isLetter(ch)) { return str + '.'; } } return str; } } class FirstCharToCapitalFormatter extends ABaseFormatter { @Override public String formatStr(String string) { return Character.toUpperCase(string.charAt(0)) + string.substring(1); } } class RemoveExtraWhitespacesFormatter extends ABaseFormatter { @Override public String formatStr(String string) { while (-1 != string.indexOf(" ")) { string = string.replaceAll(" ", " "); } return string; } } class StringToLowerCaseFormatter extends ABaseFormatter { @Override public String formatStr(String string) { return string.toLowerCase(); } } class TrimStringFormatter extends ABaseFormatter { @Override public String formatStr(String string) { return string.trim(); } } class DashFormatter extends ABaseFormatter { @Override protected int formatChar(StringBuilder buff, int pos, char ch) { // delete leading whitespaces before dashes if ('-' == ch) { // add white space before dash ch = buff.charAt(pos - 1); if (pos > 1 && ' ' != ch && '\n' != ch) { buff.insert(pos, ' '); } // add whitespace after pos = pos + 1; ch = buff.charAt(pos + 1); if (pos + 1 < buff.length() && (' ' != ch && '\n' != ch)) { buff.insert(pos + 1, ' '); } } return pos + 1; } }

Ответ 6



А я решил реализовать это на C++. Может, Хэшкоду полезно будет, кто знает...несмотря на то, что задача почти элементарная( и, думаю, стандартная ). Я сделал все через классы( ну а как же еще!? ), поэтому можно встраивать в любые системы, не вдаваясь в подробности функционирования этого класса, зная лишь одни его методы. Инкапсуляция, соответственно. Да и вообще, такие вещи не разумно реализовывать не через классы, так как тут имеется свое поведение. Прошу любить и жаловать: #include #include #include #include #include #include using namespace std; class Corrector // наш класс, реализующий функционал корректора { private: char* filename; // имя файла, где лежит BAD-TEXT. std::string text; // текст из этого файла std::vectorlines; // все лексемы( Tok = ' ') void CreateText() { for(vector::iterator itr=lines.begin();itr!=lines.end();++itr) text+=*itr+" "; transform(text.begin(),text.end(),text.begin(),tolower); text[0] = toupper(text[0]); Correct(); } public: Corrector(char* fn):filename(fn){setlocale(LC_ALL,"Russian");} void LoadText() // метод загрузки текста { std::string str; ifstream f(filename); while(!f.eof()) { f>>str; lines.push_back(str); } f.close(); CreateText(); } void Correct() // корректор исходного текста { int i = 0; for(string::iterator itr=text.begin();itr!=text.end();++itr) { i++; if(*itr==',' || *itr=='!' || *itr=='?' || *itr=='.' || *itr==';') if(i>0) if(*(itr+1)!=' ') text.insert(itr+1,' '); if(*itr=='!' || *itr=='?' || *itr=='.') if(i>0) if(*(itr-1)==' ') text.erase(itr-1,itr); if(i>2) if(*(itr-2)=='!' || *(itr-2)=='?' || *(itr-2)=='.') *itr = toupper(*itr); } } void SaveText(char* fn) // Сохранение отформатированного текста в Файл "fn" { ofstream f(fn); f<

Комментариев нет:

Отправить комментарий