C ++将规则应用于分解字符串

时间:2017-03-08 01:08:39

标签: c++ string split

我有点失落。我试图从书中解决一个示例问题,该书让我将一些规则应用于我之前已经分成单词的字符串。

从规则1开始,我需要在具有模式vowel-consonant-consonant-vowel的单词之间添加连字符,因此例如单词rules将变为ru-les

然而规则2规定,如果模式为vowel-consonant-vowel,我应该在辅音之前连字符,除非第二个元音是e并且出现在单词的末尾。我想我需要使用嵌套的if语句来应用这些?

我使用名为istreamstring的{​​{1}}分隔了所有单词,但如何在newWords之间添加连字符以成为VCCV?本书没有提到在这种情况下使用什么样的过程或功能。我为基本问题道歉,我通过研究尽我所能,但在这一点上已经陷入困境。非常感谢您的帮助,谢谢您的时间。

1 个答案:

答案 0 :(得分:0)

这是我的完整解决方案。我使用命令行参数作为要处理的单词的来源。代码检查单词中的每个位置以查看Rule1或Rule2是否适用。如果规则应用于单词中的给定索引,则该规则应用于该索引,然后循环继续搜索单词的其余部分以查找要匹配的更多规则。

在处理完所有单词之后,它输出可能或可能不是连字符的已处理单词。每个命令行参数都在一行输出。

以下是一些示例输出:(我的bash Promot是">" char)

> hyphenate
usage: hyphenate <string to hyphenate>

> hyphenate "HELLO World! You Rule!" Test Evil One
HEL-LO World! You Ru-le! 
Test 
E-vil 
One 

以下是代码:

#include <iostream>     // std::cout
#include <sstream>      // std::istringstream
#include <string>       // std::string
#include <cctype>       // std::tolower

using namespace std;

void DisplayUsage(int argc, char** argv) {
    cout << "usage: hyphenate <string to hyphenate>"  << endl;
}

bool IsaVowel(char c) {
    bool Vowel = false;
    // Simplify switch by using tolower to convert uppercase to lowercase
    // Only 5 cases to consider
    switch(tolower(c)) {
        case 'a':
        case 'e':
        case 'i':
        case 'o':
        case 'u': 
            Vowel = true;
    }
    return Vowel;
}

bool IsaConsonant(char c) {
    // A character is a consonant if it is alphabetic and not a vowel
    return isalpha(c) && !IsaVowel(c);
}

bool VCCV(string s, int idx) {
    bool matchFound = false;

    // Only check for the pattern if there are enough characters past idx
    if (idx+3 < s.length())
        // return true only if see a VCCV pattern
        if (IsaVowel(s.at(idx)) 
                && IsaConsonant(s.at(idx+1))
                && IsaConsonant(s.at(idx+2))
                && IsaVowel    (s.at(idx+3)))
            matchFound = true;

    return matchFound;
}

bool VCV(string s, int idx) {
    bool matchFound = false;

    // Only check for the pattern if there are enough characters past idx
    if (idx+2 < s.length())
            // return true only if see a VCV pattern
            if (IsaVowel(s.at(idx)) 
                && IsaConsonant(s.at(idx+1))
                && IsaVowel    (s.at(idx+2)))
            matchFound = true;

    return matchFound; 
}

bool VCe(string s, int idx) {
    bool matchFound = false;

    // VCe matches if VCV matches, and idx+2 is the last letter, and its an e
    if (VCV(s,idx) && (idx+2==(s.length()-1)) && (s.compare(idx+2,1,"e") == 0))
        matchFound = true;

    return matchFound;
}

bool Rule1(string s, int idx) {
    return VCCV(s,idx);
}

bool Rule2(string s, int idx) {
    return VCV(s,idx) && !VCe(s,idx);
}


// This program assumes compiled using the -std=c++11 standard
int main(int argc, char** argv) { 
    if (argc < 2) {
        // Did not provide a string to hyphenate, display usage and exit
        DisplayUsage(argc, argv);
        return -1; // Error
    }

    // Process each of the supplied parameters which may each contains multiple words
    for(int i=1; i<argc; i++) {
        // Get the next command line parameter
        istringstream newWords(argv[i]);

        while (!newWords.eof()) {
            string nextWord;
            newWords >> nextWord;

            // Scan the next word to see if any rules apply
            for(int j=0; j<nextWord.length(); j++) {
                if (Rule1(nextWord, j))
                    nextWord.insert(j+2,"-");
                if (Rule2(nextWord, j))
                    nextWord.insert(j+1,"-");
            }

            cout << nextWord << " ";
        }
        cout << endl;
    }

  return 0;
}

要编译它,将其保存在文件hyphenate.cpp中,然后使用-std = c ++ 11选项进行编译。

g++ -o hyphenate -std=c++11 hyphenate.cpp