在C 中查找成对的非vowlel

Finding pairs of non_vowels in C++

本文关键字:vowlel 查找      更新时间:2023-10-16

我有一个编程问题,我应该制作一个程序,该程序将计算不'a','e',e','e'的字母对数(彼此相邻的字母)'i','o','u'(元音)。

示例:

  • JAS 0
  • Olovo 0
  • Skok 1(SK)
  • stvarnost 4(ST,TV,RN,ST)

输入由小字母组成,这些字母的单词不超过200个字符,输出应输出不是元音的字母对数(a,e,i,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 'S)这是有效的最终版本:

#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;
}

您可以使用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;
}

这是使用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

实时示例

这是使用String_view和Adjacent_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;
}

确实有几件事。

  1. 访问Zbor [i]可能非常耗时,因为它总是在每次比较中再次查找我的位置(除非编译器优化某些东西)

  2. 不需要第二循环,您只需计算最后一个条目是元音,这是您在沿着字符串进一步浏览时所需的所有信息。

  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;
  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;
}

有娱乐:)

我认为,对于要求,您可以使程序看起来更简单,如下所示,我对此进行了测试和工作。我没有获得输入,而是通过硬编码输入进行了测试,您可以更改:

#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;
}

建议:

#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