Переписать код с C++ на Python ( разбиение на слоги)
Есть код на C++, который разбивает слово на слоги, нужно переписать его на Python
Снизу код на C++ и моя попытка переписать его на Python
//Для подключения и использования стандартной библиотеки ввода-вывода
#include <iostream>
//Подключение библиотеки строковых функций:
//memset(), strcpy(), strlen(), strncat()
//их описание легко найти в сети
#include <string.h>
#include "stdlib.h"
//Для вывода русских символов на консоль (см. setlocale(LC_ALL,"Rus"))
#include <clocale>
//Делаем глобальным пространство имен стандартных шаблонов
using namespace std;
//Глобальные константы для длин вспомогательных текстовых буферов
#define SUBL 512
#define BIGL 4096
//------------------------------------------------------------------
//Сам алгоритм разбиения, а также его элементы реализованы
//с помощью функций. Благодаря такому подходу код будет компактным,
//ясным и хорошо структурирован. Кроме того, функция main не будет
//загромождена текстом программы.
//------------------------------------------------------------------
//Сначала реализуем несколько вспомогательных функций, которые
//помогут сделать наглядным наш алгоритм
//------------------------------------------------------------------
//Функция IsVowel возвращает 1 (истина), если проверяемый символ letter
//является гласной буквой русского алфавита и 0 (ложь) в противном
//случае
////////////////////////////////////////////////////////////////////
bool IsVowel(char letter){
char l = tolower(letter);//приводим символ к нижнему регистру А->а
char a[] = "аоэиуыеёюя";//10
for(int i=0;i<strlen(a);i++)//по очереди проверяем
if(a[i] == l) return true;//является ли символ l одним из a[i]
return false;
}
//------------------------------------------------------------------
//Функция IsConsonant возвращает 1 (истина), если проверяемый символ letter
//является согласной буквой русского алфавита и 0 (ложь) в противном
//случае
////////////////////////////////////////////////////////////////////
bool IsConsonant(char letter){
char l = tolower(letter);//приводим символ к нижнему регистру А->а
char a[] = "бвгдйжзклмнпрстфхцчшщ";//21
for(int i=0;i<strlen(a);i++)
if(a[i] == l) return true;
return false;
}
//------------------------------------------------------------------
//Функция IsLetter возвращает 1 (истина), если проверяемый символ letter
//является буквой русского алфавита и 0 (ложь) в противном
//случае
////////////////////////////////////////////////////////////////////
bool IsLetter(char letter){
char l = tolower(letter);//приводим символ к нижнему регистру А->а
char a[] = "абвгдеёжзийклмнопрстуфхцчшщыъьэюя";//33
for(int i=0;i<strlen(a);i++)
if(a[i] == l) return true;
return false;
}
//------------------------------------------------------------------
//Функция ContainVowel возвращает 1 (истина), если в строке str
//есть гласная буква русского алфавита и 0 (ложь) в противном
//случае
////////////////////////////////////////////////////////////////////
bool ContainVowel(char *str){
for(int k=0;k<strlen(str);k++)
if(IsVowel(str[k])) return true;
return false;
}
//------------------------------------------------------------------
//Функция InsertDash вставляет тире в позицию pos строки str
////////////////////////////////////////////////////////////////////
void InsertDash(char *str,int pos){
int n = strlen(str);
for(int i=n+1;i>pos;i--)
str[i] = str[i-1];
str[pos] = '-';
}
//------------------------------------------------------------------
//Функция GetWord выделяет из текста str первое
//встреченное в ней слово
////////////////////////////////////////////////////////////////////
char* GetWord(char* str,char* buf){
memset(buf,'\0',SUBL);//заполняем буфер нулями
int i=0, j=0, n = strlen(str);
//пропускаем не буквы
while (!IsLetter(str[i]) && i < n)
i++;
//а буквы не пропускаем
while (IsLetter(str[i]) && i < n){
buf[j] = str[i];
i++; j++;
}
return buf;
}
//------------------------------------------------------------------
//Функция SubString возвращает фрагмент строки начиная с символа
//в позиции pos и длиной len
////////////////////////////////////////////////////////////////////
char* SubString(char* str, char* buf, int pos, int len){
int n = strlen(str), i, j = 0, a = len + pos;
memset(buf,'\0',SUBL);//заполняем буфер нулями
if(len == 0 || a > n) a = n;//контроль выхода за границы
for(i=pos;i<a;i++,j++)//копируем элементы в подстроку
buf[j] = str[i];
return buf;
}
//------------------------------------------------------------------
//Функция SplitWord - главная функция, которая разбивает слово str
//на слоги и возвращает группу слогов разделенных тире
////////////////////////////////////////////////////////////////////
char* SplitWord(char* str,char* buf){
char sub[SUBL];
memset(sub,'\0',SUBL);//заполняем буфер нулями
strcpy (buf,str);
int pos = 0, len = strlen(str), i = 1;
while(i < len){
if(i+2 < len){
//проверка первого условия из задания
// сг-гx (x - хотя бы одна буква)
if(IsConsonant(str[i-1]) && IsVowel(str[i]) &&
IsVowel(str[i+1]) ){
InsertDash(buf,i+1+pos);
pos++;
} else
//проверка второго условия из задания
// гс-сy (y - имеется хотя бы одна гласная)
if(IsVowel(str[i-1]) && IsConsonant(str[i]) && IsConsonant(str[i+1]) &&
ContainVowel(SubString(str,sub,i+2,0))){
InsertDash(buf,i+1+pos);
pos++;
} else
//проверка третьего условия из задания
// xг-y (y - имеется хотя бы одна гласная)
if(IsLetter(str[i-1]) && IsVowel(str[i]) &&
ContainVowel(SubString(str,sub,i+1,2))){
InsertDash(buf,i+1+pos);
pos++;
}
//обработка случая, когда два первых символа гласные
if(i == 1 && IsVowel(str[i-1]) &&
ContainVowel(SubString(str,sub,i,2))){
InsertDash(buf,i);
pos++;
}
}
i++;
}
return buf;
}
//------------------------------------------------------------------
//Функция Processing принимает строку str, которая может состоять
//из нескольких слов и возвращает строку с разбитыми на слоги словами
//Эту простую функцию мы будем вызывать в main
////////////////////////////////////////////////////////////////////
char* Processing(char* str,char* buf){
int start, end = strlen(str), j=0, i=0;
char buf1[SUBL], buf2[SUBL], buf3[SUBL], *word = NULL;
memset(buf,'\0',BIGL);//заполняем буфер нулями
while(i < end){
//Вставка знаков препинания
//если не буква, значит знак препинания
while(!IsLetter(str[i]) && i < end){
buf[j] = str[i];
i++; j++;
}
start = i;
//Получение очередного слова
word = GetWord(SubString(str,buf1,start,end),buf3);
i += strlen(word);
//Разбивка на слоги
//копируем разбитое слово в буфер
strcpy (buf1,SplitWord(word,buf2));
//вставляем слово из буфера в результирующую строку
strncat(buf,buf1,strlen(buf1));
j += strlen(buf1);
//Конец разбивки на слоги
}
return buf;
}
//------------------------------------------------------------------
int main(int argc, char *argv[]) {
//Эта команда позволяет выводить русские символы на консоль
//забей в гугл "вывод русских символов на консоль C++"
setlocale(LC_ALL,"Rus");
char buf[BIGL];//Объявляем вспомогательный текстовый буфер
char text[] =
"Пример текста слова которого надо разбить на слоги.";
cout << text << endl;
cout << Processing(text,buf) << endl;
char text1[] =
"хоккей";
cout << text1 << endl;
cout << Processing(text1,buf) << endl;
//system("cls") - использовать незачем
system("pause");
return 0;
}
Код на Python:
def is_vowel(letter):
if letter.lower() in "аоэиуыеёюя":
return True
return False
def is_consonant(letter):
if letter.lower() in "бвгдйжзклмнпрстфхцчшщ":
return True
return False
def is_russian_letter(letter):
letter = letter.lower()
if letter.lower() in "абвгдеёжзийклмнопрстуфхцчшщыъьэюя":
return True
return False
def check_vowel(string):
for letter in string:
if is_vowel(letter):
return True
return False
def insert_dash(string, position):
length = len(string)
for letter in range(position, length+1, -1):
string[letter] = string[letter - 1]
string[position] = '-'
def get_word(string):
buf = [0]*512
i = 0; j = 0
length = len(string)
while not is_russian_letter(string[i]) and i < length:
i += 1
while is_russian_letter(string[i]) and i < length:
buf[j] = string[i]
i += 1; j += 1
return buf
def substring(string, position, length):
n = len(string)
i = 0; j = 0
a = length + position
buf = [0]*512
if length == 0 or a > n: a = n
for _ in range(position, a):
buf[j] = string[i]
i += 1; j += 1
return buf
def split_word(string):
sub = [0]*512
buf = string
pos = 0
length = len(string)
i = 1
while i < length:
if i+2 < length:
if is_consonant(string[i-1]) and is_vowel(string[i]) and is_vowel(string[i+1]):
insert_dash(buf, i + 1 + pos)
pos += 1
else:
if is_vowel(string[i-1]) and is_consonant(string[i]) and is_consonant(string[i+1]) and check_vowel(substring(string, sub, i+1, 0)):
insert_dash(buf, i+1+pos)
pos += 1
else:
if is_russian_letter(string[i-1]) and is_vowel(string[i]) and check_vowel(substring(string,sub,i+1,2)):
insert_dash(buf, i+1+pos)
pos += 1
if i == 1 and is_vowel(string[i-1]) and check_vowel(substring(string, sub, i, 2)):
insert_dash(buf, i)
pos += 1
i += 1
return buf
def processing(string):
end = len(string)
j = 0; i = 0
buf = [0]*512
buf1, buf2, buf3 = [], [], []
while i < end:
while not is_russian_letter(string[i]) and i < end:
buf[j] = string[i]
i+=1; j+=1
start = i
word = get_word(substring(string, start, end))
i += len(word)
buf1 = split_word(word)
j += len(buf1)
return buf
def main():
buf = [0]*512
text = 'Суета'
print(processing(text))
if __name__ == '__main__':
main()
Вылезают различные ошибки: исправляю одну - появляется другая. Вот последняя: AttributeError: 'int' object has no attribute 'lower' line 12, in is_russian_letter Вроде заполняю нулями массив, и он берет не букву, а число, что делать - не знаю.
Ответы (2 шт):
-
Вот последняя: AttributeError: 'int' object has no attribute 'lower' line 12, in is_russian_letter Вроде заполняю нулями массив, и он берет не букву, а число, что делать - не знаю.
потому что функция у вас букву переводит в нижний регистр
letter.lower()но в массив вы кроме букв пишите еще и нули - а это ЧИСЛА, числа нельзя переводить в нижний регистр, так что вам надо делать или:
if letter == 0: return Falseили
if str(letter).lower() кроме этого у вас в коде еще много ошибок, например
i = 0; j = 0в питоне так не пишут
кроме того вы используете функцию
substring(string, sub, i+1, 0)хотя ей надо на вход 3 параметра
внутри функции substring вы делаете
a = length + positionно
positionу вас принимает список, а вы число складываете со списком
P.S.
на самом деле выгоднее в таких случаях писать код чуть ли не с нуля, а C++ код использовать лишь как инструкцию
кое что сделал, но логические ошибки уже ищите сами:
def IsVowel(letter):
return letter.lower() in "аоэиуыеёюя"
def IsConsonant(letter):
return letter.lower() in "бвгдйжзклмнпрстфхцчшщ"
def IsLetter(letter):
return letter.lower() in "абвгдеёжзийклмнопрстуфхцчшщыъьэюя"
def ContainVowel(text):
for letter in text:
if IsVowel(letter):
return True
return False
def SplitWord(text):
size = len(text)
buf = []
for i in range(size):
buf.append(text[i])
if 0 < i < size - 2:
# проверка первого условия из задания
# сг-гx (x - хотя бы одна буква)
if IsConsonant(text[i - 1]) and IsVowel(text[i]) and IsVowel(text[i + 1]):
buf.append('-')
else:
# проверка второго условия из задания
# гс-сy (y - имеется хотя бы одна гласная)
if IsVowel(text[i - 1]) and IsConsonant(text[i]) and IsConsonant(text[i + 1]) and ContainVowel(text[i + 2:]):
buf.append('-')
else:
# проверка третьего условия из задания
# xг-y (y - имеется хотя бы одна гласная)
if IsVowel(text[i]) and ContainVowel(text[i + 1:]):
buf.append('-')
# обработка случая, когда два первых символа гласные
if i == 1 and IsVowel(text[i - 1]) and ContainVowel(text[i]):
buf.append('-')
return ''.join(buf)
text = "Кооператив Пример текста слова которого надо разбить на слоги."
# разбить предложения на слова
words = text.split()
# разбить каждое слово на слога
new_words = []
for word in words:
# разбить текущее слово на слога
new_words.append(SplitWord(word))
# соединить слова в предложение
print(' '.join(new_words))