如何获取字符串中每个单词的第一个字母,该单词由多个点或空格分隔

时间:2016-08-19 20:51:15

标签: c++ arrays string char

这是问题的例子:

输入:

Spy..enigma .....长... address.muscle ...动漫....时间

输出:

斯拉末

我可以制作'。'消失但我无法得到每个单词的第一个字母。 感谢。

这是我的代码:

char dot[] = {'.'}; 

bool isDot(char c) {
    for (int i = 0; i < 1; i++) {
        if (c == dot[i]) {
            return true;
        }
    }
    return false;
}

int main() {
    string str;
    cin >> str;
    cout << str[0];
    for (int i = 0; i < str.length(); i++) {
            if (!isDot(str[i])) {
                cout << str[i+1];
            }
    }
    return 0;
}

4 个答案:

答案 0 :(得分:0)

  1. 删除其他点,以便 Spy.enigma.long.address.muscle.anime.time
  2. 运行for循环以查找点
  3. 后的每个字符

    以下是代码:

    #include <iostream>
    using namespace std;
    
    int main() {
        string str;
        cin >> str;
        cout << str[0];
        // Remove additional dots
        for (int i = 0; i < str.size() - 1; i++) {
            if (str[i] == '.' && str[i + 1] == '.') str.erase(i, 1), i--;
        }
        // print every character after dots
        for (int i = 0; i < str.size(); i++) {
            if (str[i] == '.') cout << str[i + 1];
        }
        return 0;
    }
    

    注意:如果第一个字符为'。',则此代码无效,但根据您的代码我假设不是。

    或者只是运行一个简单的if (s[i] == '.' && s[i + 1] != '.')

    #include <iostream>
    using namespace std;
    
    int main() {
        string str;
        cin >> str;
        cout << str[0];
        for (int i = 0; i < str.size(); i++) {
            if (str[i] == '.' && str[i + 1] != '.') cout << str[i + 1];
        }
        return 0;
    }
    

答案 1 :(得分:0)

我使用的是C ++ 11正则表达式库:

#include <regex>
#include <string>

std::string first_letters(const std::string& input_string) {
    std::string result;
    std::regex word_regex { "[^\\.\\s]*" };
    std::sregex_iterator i { input_string.begin(), input_string.end(), word_regex };
    std::sregex_iterator end;
    while (i != end) {
        result.push_back(i->str().front());
        ++i;
    }
    return result;
}

答案 2 :(得分:0)

如果您有兴趣,可以学习使用正则表达式。它确实需要学习如何制作正则表达式模式,但有些网站可以帮助您测试表达式。

以下是一个例子:

#include <boost/regex.hpp>
#include <string>
#include <vector>
#include <iostream>

using namespace std;

char* acronymMaker(vector<string> wordList) { // reusable function for any string vectors

    if (wordList.size() > 0 ) {  // if there is at least one word in the vector
        char* result = new char[wordList.size() + 1]; // create array big enough for all first characters of each string, and terminating char
        int i = 0; // i is declared outside to be used again
        for (; i < wordList.size(); i++) // for each word
            result[i] = wordList[i][0]; // take first character of each word

        result[i] = '\0'; // add terminating character at end

        return result; // return completed acronym
    }
    return (char*)""; // return empty acronym for 0 words
}

int main(void) { // example using boost::regex and function from above

    string str = "Spy..enigma.....long...address.muscle...anime....time"; //input string
    vector<string> words; // dynamic storage for words
    char* acronym; // acronym to be filled later;

    boost::regex exp{"(\\w+)"}; // regular expression to capture separated words only

    boost::sregex_iterator iter(str.begin(), str.end(), exp); // define iterator parameters
    boost::sregex_iterator end; // empty iterator, same state if no more matches exist or no matches at all

    for (; iter != end; ++iter) { // for each word captured (++ before iter skips first capture, which is the full string being evaluated)
        words.push_back(iter->str()); // push it to the back of the word container
    }

    acronym = acronymMaker(words); // call function

    cout << acronym << endl; // display result on screen

    return 0;
}

如果您编译此代码,它将按要求返回Selamat。但是我正在使用我的正则表达式的boost库,所以你也需要编译我的代码。从技术上讲,它也应该与c ++ 11正则表达式库一起使用,因为输入/输出是相同的,但是我没有运气让它工作,我会在这篇文章之后查看原因。

答案 3 :(得分:0)

这并没有完全回答你的问题,但我只想说...... 看看这段代码:

char dot[] = {'.'}; 

bool isDot(char c) {
    for (int i = 0; i < 1; i++) {
        if (c == dot[i]) {
            return true;
        }
    }
    return false;
}

这是一种非常复杂的方法来确定角色是否是一个点(:

编写for循环来执行单次迭代? 创建一个数组来保存单个值?

如何,而不是:

bool isDot(char c) {
    return c == '.';
}

至于你的实际问题,其他人提出了正则表达式,但you know what they say about that

您可以循环输入,跟踪当前状态。

你能关注多少个州?

  • 单词的第一个字母(您想输出这些)
  • 单词的非首字母
  • 一个点(这些单独的单词)

如果我们分别将这些状态称为ABC,则您的示例如下所示:

Spy..enigma.....long...address.muscle...anime....time
ABBCCABBBBBCCCCCABBBCCCABBBBBBCABBBBBCCCABBBBCCCCABBB

从左到右扫描输入时,可以轻松跟踪此信息。 然后你只想打印A个州。

如果你想略显聪明,你只能使用两种状态:

  • 点后面的第一个字符
    • 如果输入中的第一个字符有特殊例外,可能是非点的。
  • 其他

根据这些州,你有:

Spy..enigma.....long...address.muscle...anime....time
ABBBBABBBBBBBBBBABBBBBBABBBBBBBABBBBBBBBABBBBBBBBABBB
相关问题