#P2982. 相对开音节(100分)
-
1000ms
Tried: 1083
Accepted: 147
Difficulty: 3
所属公司 :
华为od
-
算法标签>字符串
相对开音节(100分)
题面描述
给定一个字符串,以空格为分隔符,反转每个单词中的字母。若单词中包含非字母字符(如数字、标点符号等),则不进行反转。反转后,计算其中含有相对开音节结构的子串个数。相对开音节的结构为:辅音 + 元音(aeiou)+ 辅音(r除外) + e。
思路
本题的核心思路是通过字符串处理和条件判断,统计符合相对开音节结构的子串个数。首先,将输入字符串按空格分割成多个单词,对每个单词进行反转(若单词中只包含字母);然后,遍历反转后的单词,检查其中是否存在符合相对开音节结构的子串(辅音 + 元音 + 辅音(r除外) + e),并统计符合条件的子串个数。
- 反转单词:首先将字符串按空格分割成多个单词,然后对每个单词进行反转。如果单词中包含非字母字符,则不进行反转。
- 判断相对开音节:对于反转后的每个单词,检查其中是否存在符合相对开音节结构的子串。相对开音节的结构为:辅音 + 元音 + 辅音(r除外) + e。
- 统计符合条件的子串:遍历每个单词,统计其中符合相对开音节结构的子串个数。
cpp
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>
using namespace std;
// 判断一个字符是否是元音
bool isVowel(char c) {
return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
}
// 判断一个字符是否是辅音(且不是r)
bool isConsonant(char c) {
return isalpha(c) && !isVowel(c) && c != 'r';
}
// 判断一个子串是否是相对开音节
bool isRelativeOpenSyllable(const string& s, int start, int end) {
if (end - start + 1 != 4) return false;
return (s[start] == 'r' || isConsonant(s[start])) && isVowel(s[start + 1]) && isConsonant(s[start + 2]) && s[start + 3] == 'e';
}
// 反转单词并统计相对开音节子串个数
int countRelativeOpenSyllables(const string& input) {
vector<string> words;
string word;
for (char ch : input) {
if (ch == ' ') {
words.push_back(word);
word.clear();
} else {
word += ch;
}
}
words.push_back(word);
int count = 0;
for (string& w : words) {
bool hasNonAlpha = false;
for (char ch : w) {
if (!isalpha(ch)) {
hasNonAlpha = true;
break;
}
}
if (!hasNonAlpha) {
reverse(w.begin(), w.end());
}
for (size_t i = 0; i + 3 < w.size(); ++i) {
if (isRelativeOpenSyllable(w, i, i + 3)) {
count++;
}
}
}
return count;
}
int main() {
string input;
getline(cin, input);
cout << countRelativeOpenSyllables(input) << endl;
return 0;
}
python
def is_vowel(c):
return c in {'a', 'e', 'i', 'o', 'u'}
def is_consonant(c):
return c.isalpha() and not is_vowel(c) and c != 'r'
def is_relative_open_syllable(s, start, end):
if end - start + 1 != 4:
return False
return (s[start] == 'r' or is_consonant(s[start])) and is_vowel(s[start + 1]) and is_consonant(s[start + 2]) and s[start + 3] == 'e'
def count_relative_open_syllables(input_str):
words = input_str.split(' ')
count = 0
for i in range(len(words)):
word = words[i]
if all(c.isalpha() for c in word):
word = word[::-1]
for j in range(len(word) - 3):
if is_relative_open_syllable(word, j, j + 3):
count += 1
return count
input_str = input().strip()
print(count_relative_open_syllables(input_str))
java
import java.util.*;
public class Main {
// 判断一个字符是否是元音
private static boolean isVowel(char c) {
return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}
// 判断一个字符是否是辅音(且不是r)
private static boolean isConsonant(char c) {
return Character.isLetter(c) && !isVowel(c) && c != 'r';
}
// 判断一个子串是否是相对开音节
private static boolean isRelativeOpenSyllable(String s, int start, int end) {
if (end - start + 1 != 4) return false;
return (s.charAt(start) == 'r' || isConsonant(s.charAt(start))) && isVowel(s.charAt(start + 1)) && isConsonant(s.charAt(start + 2)) && s.charAt(start + 3) == 'e';
}
// 反转单词并统计相对开音节子串个数
private static int countRelativeOpenSyllables(String input) {
String[] words = input.split(" ");
int count = 0;
for (int i = 0; i < words.length; i++) {
String word = words[i];
boolean hasNonAlpha = false;
for (char ch : word.toCharArray()) {
if (!Character.isLetter(ch)) {
hasNonAlpha = true;
break;
}
}
if (!hasNonAlpha) {
word = new StringBuilder(word).reverse().toString();
}
for (int j = 0; j + 3 < word.length(); j++) {
if (isRelativeOpenSyllable(word, j, j + 3)) {
count++;
}
}
}
return count;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
System.out.println(countRelativeOpenSyllables(input));
}
}
题目内容
相对开音节构成的结构为:辅音 + 元音(aeiou)+ 辅音(r除外) + e。
常见的单词有bike、cake等。
给定一个字符串,以空格为分隔符,反转每个单词中的字母,若单词中包含如数字等其他非字母时不进行反转。
反转后计算其中含有相对开音节结构的子串个数(连续的子串中部分字符可以重复)。
输入描述
字符串,以空格分割的多个单词,字符串长度<10000,字母只考虑小写
输出描述
含有相对开音节结构的子串个数,注:个数<10000
样例1
输入
ekam a ekac
输出
2
说明
反转后为 make a cake 其中make、cake为相对开音节子串,返回2。
样例2
输入
!ekam a ekekac
输出
2
说明
反转后为!ekam a cakeke 因!ekam含非英文字符所以未反转,其中 cake、keke为相对开音节子串,返回2。