在C ++中查找非元音对

时间:2019-03-13 13:00:01

标签: c++ arrays string char word

我遇到了一个编程问题,我应该编写一个程序来计算不是“ a”,“ e”,“ i”,“ o”, 'u'(元音)。

示例:

  • jas 0
  • olovo 0
  • skok 1(sk)
  • stvarnost 4(st,tv,rn,st)

输入由不超过200个字符的小字母组成,输出应输出不是元音的字母对数(a,e,i,o,u)。

时间限制

  • 1秒

内存限制

  • 64 MB

问题中提供的示例已给出:

  • 输入 skok
  • 输出 1

但是,当我输入“ skok”一词时,该程序不起作用(它似乎一直在后台运行,但屏幕上未显示任何内容)。但是,单词“ stvarnost”(现实)有效,显示为“ 4”-如问题中所给。

在10个测试用例中,有两个测试用例给我正确的输出,一个给我提供了错误的输出,另外七个测试用例告诉我我已经超过了时间限制。

现在,我还希望获得有关如何避免超过给定时间限制以及如何在下面的程序中解决该问题的建议。

这是我开始的代码:

#include <iostream>
#include <string.h>

using namespace std;

int main() {

    char zbor[200];
    cin.get(zbor, 200);
    int length = strlen(zbor);
    int j_value = 0;
    int check_pairs = 0;
    int pairs = 0;
    int non_vowels = 0;

    for (int i = 0; i < length; i++) {
        if (zbor[i] == 'a' || zbor[i] == 'e' || zbor[i] == 'i' || zbor[i] == 'o' || zbor[i] == 'u') {
            continue;
        } else {
            non_vowels++;
            for (int j = i + 1; j < length; j++) {
                if (zbor[j] == 'a' || zbor[j] == 'e' || zbor[j] == 'i' || zbor[j] == 'o' || zbor[j] == 'u') {
                    break;
                } else {
                    non_vowels++;
                    if (non_vowels % 2 != 0) {
                        check_pairs = non_vowels / 2 + 1;
                    } else {
                        check_pairs = non_vowels / 2;
                    }
                    if (pairs < check_pairs) {
                        pairs++;
                    }
                    j_value = j;
                }
            }
            i = j_value +  1;
        }
    }

    cout << pairs;

    return 0;
}

编辑:

#include <iostream>
#include <string.h>

using namespace std;

int main() {

    char zbor[200];
    cin.get(zbor, 200);
    int length = strlen(zbor);
    int pairs = 0;
    int non_vowels = 0;

    for (int i = 0; i < length; i++) {
        if (zbor[i] == 'a' || zbor[i] == 'e' || zbor[i] == 'i' || zbor[i] == 'o' || zbor[i] == 'u') {
            non_vowels = 0;
            continue;
        } else {
            non_vowels++;
            if (non_vowels >= 2) {
                if (non_vowels % 2 != 0) {
                    pairs = non_vowels / 2 + 1;
                } else if (non_vowels % 2 == 0) {
                    pairs = non_vowels / 2;
                }
            }
        }
    }

    cout << pairs;

    return 0;
}

使用以下答案的代码段( bruno Ozzy )来编辑代码,这是有效的最终版本:

#include <iostream>
#include <string.h>

using namespace std;

bool vowel(char c) {
    switch(c) {
    case 'a':
    case 'e':
    case 'i':
    case 'o':
    case 'u':
        return true;
    default:
        return false;
    }
}

int main()
{

    char zbor[200];
    cin.get(zbor, 200);
    int N = strlen(zbor);
    int non_vowels = 0;
    int pairs = 0;

    for (int i = 0; i < N; i++) {
        if (!vowel(zbor[i])) {
            non_vowels = 0;
        } else {
            non_vowels++;
            if (!vowel(zbor[i])) {
                non_vowels = 0;
            } else {
                non_vowels++;
                if (non_vowels > 1) {
                    pairs++;
                }
            }
        }
    }

    cout << pairs;

    return 0;
}

7 个答案:

答案 0 :(得分:2)

您可以使用C ++功能(建议)轻松地简化代码:

#include <algorithm>
#include <iostream>
#include <array>
#include <vector>

const std::array<char, 5> vowels = {'a', 'e', 'i', 'o', 'u'};

bool isVowel(char c)
{
    return std::find(vowels.begin(), vowels.end(), c) != vowels.end();
}

bool checker(char c)
{
    static bool lastFound = false;

    if (lastFound && !isVowel(c))
        return true;
    else
        lastFound = !isVowel(c);

    return false;   
}

int main()
{
    std::vector<char> v{'s', 'k', 'o', 'k', 'a', 'k'};

    int num_items = std::count_if(v.begin(), v.end(), &checker);

    std::cout << num_items << std::endl;
}

答案 1 :(得分:2)

这是使用std::adjacent_find的解决方案:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>

bool isConsonant(char c)
{
    static const char *vowels = "aeiou";
    return strchr(vowels, c)?false:true;
}

int main()
{
    std::string s = "stvarnost";
    auto it = s.begin();
    int count = 0;
    while (true)
    {
        // find the adjacent consonants
        auto it2 = std::adjacent_find(it, s.end(), 
                                     [&](char a, char b) 
                                     { return isConsonant(a) && isConsonant(b); });
        if ( it2 != s.end())
        {
            // found adjacent consonents, so increment count and restart at the next character.
            ++count;
            it = std::next(it2);
        }
        else
            break;
    }
    std::cout << count << "\n";
}

输出:

4

Live Example

答案 2 :(得分:2)

这是一个使用string_view和neighbor_find的C ++ 17解决方案。它是惯用的C ++,使其非常简短且易于理解。

#include <algorithm>
#include <iostream>
#include <string_view>
using namespace std;

bool checkPair(char a, char b)
{
    string_view vowels { "aeiou" };
    bool aNotVowel = vowels.find(a) == string_view::npos;
    bool bNotVowel = vowels.find(b) == string_view::npos;
    return aNotVowel && bNotVowel;
}

int main(int argc, char **argv)
{
    int pairs { 0 };
    string_view input(argv[1]);

    for(auto next = input.begin(); next != input.end();)
    {
        next = adjacent_find(next, input.end(), checkPair);
        if(next != input.end())
        {
            ++pairs;
            ++next;
        }
    }
    cout << pairs << endl;

    return 0;
}

答案 3 :(得分:1)

提案:

#include <iostream>

using namespace std;

bool vowel(char c)
{
    switch (c) {
    case 'a':
    case 'e':
    case 'i':
    case 'o':
    case 'u':
    case 'y':
        return true;
    default:
        return false;
    }
}

int main()
{
    string zbor;

    if (! (cin >> zbor))
        return -1;

    int pairs = 0;

    for (size_t i = 0; i < zbor.length(); ++i) {
        if (!vowel(zbor[i])) {
          int n = 0;

          do
            n += 1;
          while ((++i != zbor.length()) && !vowel(zbor[i]));

          pairs += n - 1;
        }
    }

    cout << pairs << endl;

    return 0;
}

编译和执行:

/tmp % g++ -pedantic -Wextra p.cc
/tmp % ./a.out
jas
0
/tmp % ./a.out
olovo
0
/tmp % ./a.out
skok
1
/tmp % ./a.out
stvarnost
4

答案 4 :(得分:1)

确实,有几件事。

  1. 访问zbor [i]可能会非常耗时,因为它每次执行比较时都会再次查找i的位置(除非编译器进行了一些优化)

  2. 不需要第二个for循环,您只需计算最后一个条目是否是元音,这就是在进一步遍历字符串时所需的全部信息。

  3. 利用lambdas等c ++功能使代码更易于阅读

auto isVowel = [](char& c) {return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';};

for (int i = 0; i < length; i++)
{
  if (isVowel(zbor[i]))
  {
    non_vowels = 0;
  }
  else
  {
    non_vowels++;

    if (non_vowels > 1)
      pairs++;
  }
}

cout << pairs;

答案 5 :(得分:1)

  1. 优化时间:解析字符串(char *)时,请使用“ while”而不是获取长度和使用“ for”。您只获得1个通行证而不是2个通行证(strlen已经采取了1个通行证)。
  2. 优化代码:如果您有重复的代码,请将其放在函数或宏中。
  3. 使用之前的两点,这是示例代码(您可以处理输入管理):

样本

#include <iostream>
#include <cstddef>

using namespace std;

#define IS_VOWEL(a) ((a == 'a') || (a == 'i') || (a == 'u') || (a == 'e') || (a == 'o') || (a == 'y'))

int find_pairs(char * input, char ** stop_pos)
{
    char * input_cursor = input;

    while ((*input_cursor != 0) && IS_VOWEL(*input_cursor))
    {
        input_cursor++;
    }
    size_t used_count = 0;
    while ((*input_cursor != 0) && !IS_VOWEL(*input_cursor))
    {
        used_count++;
        input_cursor++;
    }
    *stop_pos = input_cursor;
    if (used_count < 2)
    {
        return 0;
    }
    else
    {
        return used_count - 1;
    }
}

int main()
{
    char input[] = "stvarnost";
    char * input_cursor = input;
    int found = 0;
    while (*input_cursor != 0)
    {
        found += find_pairs(input_cursor, &input_cursor);
    }
    cout << found << endl;
    return 0;
}

玩得开心:)

答案 6 :(得分:1)

我认为,根据要求,您可以使程序看起来更简单,如下所示,我已对其进行测试并针对您提供的示例进行工作。我没有进行输入,而是通过对输入进行硬编码来测试,您可以更改输入:

#include <iostream>
#include <string.h>

using namespace std;

bool IsVowel(char ch)
{
    switch (ch)
    {
    case 'a':
    case 'e':
    case 'i':
    case 'o':
    case 'u':
    case 'A':
    case 'E':
    case 'I':
    case 'O':
    case 'U':
        return true;
        //break;
    default:
        return false;
    }

    return false;
}

int CountNonVowelPair(char* chIn)
{
        char zbor[200];
        //cin.get(zbor, 200);
        strcpy(zbor, chIn);
        int length = strlen(zbor);
        int j_value = 0;
        int check_pairs = 0;
        int pairs = 0;
        int non_vowels = 0;

        if (length <= 1)
            return 0;

        for (int i = 1; i < length; i++)
        {
            if (IsVowel(zbor[i - 1]) || IsVowel(zbor[i]))
                continue;
            else
                pairs++;
        }

        return pairs;
}

int main() 
{
    int nRet;
    nRet = CountNonVowelPair("jas");
    cout << nRet <<endl;
    nRet = CountNonVowelPair("olovo");
    cout << nRet <<endl;
    nRet = CountNonVowelPair("skok");
    cout << nRet <<endl;
    nRet = CountNonVowelPair("stvarnost");
    cout << nRet <<endl;

    return 0;
}