Важное примечание: Вы можете использовать только для циклов for-range в C ++ 11 или выше , если ваш компилятор не поддерживает C ++ 11 или выше, используйте обычный цикл for ...
Учитывая ваш вопрос, у вас есть для использованияэта структура (эквивалентна той, что в вопросе):
typedef struct
{
std::string english;
std::string pig_latin;
} Word;
Это макрос, который будет использоваться для проверки, является ли первая буква гласной или согласный (следовательно, !IS_VOWEL(some_char)
) ...
#define IS_VOWEL(x) ((x) == 'A' || (x) == 'E' || (x) == 'I' || (x) == 'O' || (x) == 'U' || \
(x) == 'a' || (x) == 'e' || (x) == 'i' || (x) == 'o' || (x) == 'u')
Еще одна функция, которая нам нужна для получения только той части слова, которая имеет буквы (не символы и цифры):
std::pair<unsigned, unsigned> GetWord(std::string word)
{
auto start = word.end();
for (auto it = word.begin(); it != word.end(); ++it)
if (tolower(*it) >= 'a' && tolower(*it) <= 'z' && start == word.end())
start = it;
else if (start != word.end() && !(tolower(*it) >= 'a' && tolower(*it) <= 'z'))
return std::make_pair(std::distance(word.begin(), start), std::distance(word.begin(), it));
return std::make_pair(start == word.end() ? 0 : std::distance(word.begin(), start), std::distance(word.begin(), word.end()));
}
И, наконец, не в последнюю очередь, функция для преобразования английского языка в Pig-Latin (я знаю, это огромная):
std::vector<Word> CreatePigLatinWordsFromEnglish(std::string english, bool sentence_case = true)
{
// You can break it from here to use inside another function (viz., splitSentence)
std::transform(english.begin(), english.end(), english.begin(), ::tolower);
std::stringstream english_stream(english);
std::vector<Word> words;
std::string temporary;
while (std::getline(english_stream, temporary, ' '))
words.emplace_back(Word({ temporary, "" }));
// Till here...
// From here the conversion starts...
for (auto &word : words)
{
auto const word_it = GetWord(word.english);
if (!IS_VOWEL(word.english[word_it.first]) && !std::string(std::next(word.english.begin(), word_it.first),
std::next(word.english.begin(), word_it.second)).empty())
{
word.pig_latin.append(std::string(word.english.begin(), std::next(word.english.begin(), word_it.first)));
word.pig_latin.append(std::string(std::next(word.english.begin(), word_it.first + 1), std::next(word.english.begin(), word_it.second)));
word.pig_latin.append(1, word.english[word_it.first]);
word.pig_latin.append(std::string("ay"));
word.pig_latin.append(std::next(word.english.begin(), word_it.second), word.english.end());
}
else
word.pig_latin = std::string(word.english.begin(), std::next(word.english.begin(), word_it.second)) + "way"
+ std::string(std::next(word.english.begin(), word_it.second), word.english.end());
}
// Conversion ends here...
// Changing the case from lower case to sentence case if needed...
if (sentence_case)
{
words[0].english[0] = toupper(words[0].english[0]);
words[0].pig_latin[0] = toupper(words[0].pig_latin[0]);
}
return words; // Returning the list of words we got...
}
Ну, пример, чтобы продемонстрировать этоМетод:
int main()
{
auto const test = "An apple a day keeps the doctor away!";
for (auto word : CreatePigLatinWordsFromEnglish(test))
std::cout << word.pig_latin << " ";
return 0;
}
Вывод:
В любом случае, Appleway Away Day Eepskay Hetay Octorday Вдали!
Попробуйте и посмотрите,дает вам необходимый результат ...
С уважением,
Ruks.