我试图解决一个问题,我无法弄清楚如何做到这一点。 问题说,给定的,其具有在所述第一线上的数k和在下一行的某些单词的输入文件,K是一个字需要具有在控制台要打印元音的最小数目。
Example:
Input: test.in
cars
are...great and awesome
Output:
If k is 2 the result should be:
are
great
awesome
And also it should not take into account spaces or other characters like .,!,? and so on.
我到目前为止有:
int main(){
ifstream fin("dataTest.in");
char s[250];
int k;
fin>>k;
int nrVowels=0;
while(fin>>s) {
int n = strlen(s);
for(int i=0; i < n; i++)
{
if (s[i] == 'a' || s[i] == 'e' || s[i] == 'o' || s[i] == 'i' || s[i] == 'u'){
nrVowels++;
if(nrVowels == k){
cout<<"Here i guess i should print the word?";
}
}
}
}
}
正如你可以从代码中看到我的问题是,我真的不知道,应该怎样打印文字和如何将我知道这个词是因为结束我不想只打印字的一部分。 难道你们对我应该怎么做什么想法?
std::ifstream file("Read.txt");
int number;
file>>number;
std::string str;
auto vowels = [](char c){return c == 'a' || c == 'e' || c == 'o' || c == 'i' || c == 'u';};
while (std::getline(file, str))
{
if(std::count_if(str.cbegin(), str.cend(), vowels) >= number){
std::cout<<str<<'\n';
}
}
谢谢回答! 我修改我的代码与此基础上对你有所帮助:
int main(){
ifstream fin("dateTest.in");
char s[250];
int k;
fin>>k;
int nrVowels=0;
while(fin>>s) {
int n = strlen(s);
nrVowels=0;
for(int i=0; i < n; i++)
{
if (s[i] == 'a' || s[i] == 'e' || s[i] == 'o' || s[i] == 'i' || s[i] == 'u'){
nrVowels++;
if(nrVowels >= k){
cout<<s<<" ";
break;
}
}
}
}
}
这样的工作,但现在我也需要单独具有的话。,? 等等。 应该如何是做什么?
您的要求规定,“K是元音的最小数目,一个字需要具有在控制台要打印”,这将转换为大于或等于条件
if (nrVowels >= k) { /* print word */ }
然而,你的代码只要打印字k
元音被发现,所以你可以保持你的条件不变。 但是,你应该打破内部循环一次所需的数量达到。
此外,由于它已经被评论,您需要重置nrVowels
对于每个要检查字计数器。 更重要的是:让nrVowels
您while循环体内局部范围的变量。
关于你的代码中暗示,是不是绝对必要解决的问题:
- 使用
std::string
,而不是字符数组。 - 使用包含所有元音单个变量
- 不计元音,正好确保字至少两个有
码:
ifstream fin("dataTest.in");
std::string s;
const char* vowels = "aeiou";
int k;
fin>>k;
while(fin>>s)
{
// If the string contains at least two vowels, the find results will differ
if (s.find_first_of(vowels) != s.find_last_of(vowels))
{
std::cout << s << std::endl;
}
}
首先修复明显问题
int main(){
ifstream fin("dataTest.in");
char s[250];
int k;
fin>>k;
while(fin>>s) {
int nrVowels=0; // moved
int n = strlen(s);
for(int i=0; i < n; i++) {
if (s[i] == 'a' || s[i] == 'e' || s[i] == 'o' || s[i] == 'i' || s[i] == 'u') {
nrVowels++;
if(nrVowels == k) {
cout<< s;;
break; // inner for
}
}
}
}
}
你有
char s[250];
与组合
fin>>s
是一个潜在的缓冲区溢出。 改变s到
std::string s;
现在你
int n = strlen(s);
免费。
if (s[i] == 'a' || s[i] == 'e' || s[i] == 'o' || s[i] == 'i' || s[i] == 'u')
相当长倒不如说
if (IsVowel(s[i]) {
通过使(如Kaldrr提议)
auto IsVowel = [](const char c){return c == 'a' || c == 'e' || c == 'o' || c == 'i' || c == 'u';};
这使
int main(){
ifstream fin("dataTest.in");
std::string s;
int k;
fin>>k;
auto IsVowel = [](const char c){return c == 'a' || c == 'e' || c == 'o' || c == 'i' || c == 'u';};
while(fin>>s) {
int nrVowels=0; // moved
for(int i=0; i < n; i++) {
if (IsVowel(s[i]) {
nrVowels++;
if(nrVowels == k) {
cout<< s;;
break; // inner for
}
}
}
}
}
但是,仍然有每个单词的问题进行测试,而不是每个字符串。
int main(){
ifstream fin("dataTest.in");
std::string s;
int k;
fin>>k;
auto IsVowel = [](const char c) { return c == 'a' || c == 'e' || c == 'o' || c == 'i' || c == 'u'; };
auto IsSplit = [](const char c) { return isspace(s[i]) || ispunct(s[i]); };
while(fin>>s) {
int nrVowels=0; // moved
for(int i=0; i < s.length; i++) {
if (IsVowel(s[i]) {
nrVowels++;
if(nrVowels == k) {
cout << s; // wrong writes all the string and not the word
break; // inner for
}
} else {
if (IsSplit(s[i]) {
nrVowels = 0; // restart at each word.
}
}
}
}
}
我们要的是
while(fin>>s) {
auto split = Split(s);
for (const auto& str : split) {
if (HasEnougVowels(str, k)) {
cout << s;
}
}
}