在C中优化for()循环
我的老师说我可以优化这个for()循环,但我不知道如何优化,任何帮助都是很好的在C中优化for()循环,c,for-loop,optimization,C,For Loop,Optimization,我的老师说我可以优化这个for()循环,但我不知道如何优化,任何帮助都是很好的 void vowels(char strng[]) { int i, j, word_len, vowels_len, vowel_count; char vowels[] = "aeiouAEIOU"; word_len = strlen(strng); vowels_len = strlen(vowels); vowel_count = 0; for (i = 0; i < word_len;
void vowels(char strng[])
{
int i, j, word_len, vowels_len, vowel_count;
char vowels[] = "aeiouAEIOU";
word_len = strlen(strng);
vowels_len = strlen(vowels);
vowel_count = 0;
for (i = 0; i < word_len; ++i) {
for (j = 0; j < vowels_len; ++j) {
if (strng[i] == vowels[j]) {
++vowel_count;
break;
}
}
}
printf("%s: %d vowels\n", strng, vowel_count);
}
无效元音(char strng[]
{
int i,j,单词,元音,元音计数;
字符元音[]=“aeiouAEIOU”;
单词_len=strlen(strng);
元音=strlen(元音);
元音计数=0;
对于(i=0;i
一种方法是完全删除嵌套循环,将其替换为一个数组,该数组将字符代码映射到一个标志,指示char
是否为元音:
int isVowel[256] = {0};
for (int i = 0 ; vowels[i] != '\0' ; i++) {
isVowel[(unsigned char)vowels[i]] = 1;
}
现在主回路可以优化如下:
for (int i = 0; i != word_len ; i++) {
vowel_count += isVowel[(unsigned char)string[i]];
}
使用开关
语句,您可以获得相当的性能:
for (int i = 0; i != word_len ; i++) {
switch(string[i]) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':
vowel_count ++;
break;
}
}
一种方法是完全删除嵌套循环,将其替换为将字符代码映射到指示
char
是否为元音的标志的数组:
int isVowel[256] = {0};
for (int i = 0 ; vowels[i] != '\0' ; i++) {
isVowel[(unsigned char)vowels[i]] = 1;
}
现在主回路可以优化如下:
for (int i = 0; i != word_len ; i++) {
vowel_count += isVowel[(unsigned char)string[i]];
}
使用开关
语句,您可以获得相当的性能:
for (int i = 0; i != word_len ; i++) {
switch(string[i]) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':
vowel_count ++;
break;
}
}
比Dasblinkenlight更简单的优化是:
char vowels[] = "AEIOU";
vowels_len = sizeof(vowels)-1;
...
for (char c=strng[i]&~32, j = 0; j < vowels_len; ++j) {
if (c == vowels[j]) {
char元音[]=“AEIOU”;
元音_len=sizeof(元音)-1;
...
for(char c=strng[i]&~32,j=0;j<元音_len;++j){
if(c==元音[j]){
(
c&~32
在ascii中更为突出。)一个比DasLinkenLight更简单的优化是:
char vowels[] = "AEIOU";
vowels_len = sizeof(vowels)-1;
...
for (char c=strng[i]&~32, j = 0; j < vowels_len; ++j) {
if (c == vowels[j]) {
char元音[]=“AEIOU”;
元音_len=sizeof(元音)-1;
...
for(char c=strng[i]&~32,j=0;j<元音_len;++j){
if(c==元音[j]){
(<代码> C和32 是ASCII中的ToupP.)
< P >不确定你的老师是否会考虑这种作弊,但这是一种可能比使用2个嵌套循环更能优化元音的方法。char *pos;
int vowel_count=0;
pos=strng;
while(pos)
{
pos=strpbrk(pos,"aeiouAEIOU");
if(pos)
{
vowel_count++;
pos++;
}
}
不确定你的老师是否会考虑这种作弊行为,但这是一种寻找元音的方法,它比使用2个嵌套循环更为合适。
char *pos;
int vowel_count=0;
pos=strng;
while(pos)
{
pos=strpbrk(pos,"aeiouAEIOU");
if(pos)
{
vowel_count++;
pos++;
}
}
为了优化代码,您必须首先了解瓶颈是什么。在算法级别,您有以下基本性能问题:
- 您必须意识到
遍历整个字符串以搜索空终止符,因此您遍历同一字符串strlen
两次。这是低效的-最好在检查数据的同时检查空终止符strng
- 文本
是一个常量,因此您知道它在编译时的大小。无需在运行时使用strlen()计算它。您可以使用“aeiouAEIOU”
,它在编译时进行计算sizeof
- 通过同时检查大写和小写,您可以加倍工作。相反,暂时将您要查找的字符转换为大写,然后只在大写元音中查找匹配项
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
int vowels(const char str[])
{
const char VOWEL_LOOKUP[] = "AEIOU";
int vowel_count = 0;
for(; *str != '\0'; str++)
{
char ch = toupper(*str);
for(size_t i=0; i<sizeof(VOWEL_LOOKUP)-1; i++)
{
if(ch == VOWEL_LOOKUP[i])
{
vowel_count++;
break;
}
}
}
return vowel_count;
}
int main (void)
{
const char str[] = "Stack Overflow"; // 4 vowels
printf("%s: %d vowels\n", str, vowels(str));
}
#包括
#包括
#包括
int元音(const char str[])
{
常量字符元音查找[]=“AEIOU”;
int元音_计数=0;
对于(;*str!='\0';str++)
{
char ch=touper(*str);
对于(size_t i=0;i='A'&&ch为了优化代码,您必须首先了解瓶颈是什么。在算法级别上,您有以下基本性能问题:
- 您必须意识到
strlen
遍历整个字符串以搜索空终止符,因此您遍历同一字符串strng
两次。这是低效的-最好在检查数据的同时检查空终止符
- 文本
“aeiouAEIOU”
是一个常量,因此您知道它在编译时的大小。无需在运行时使用strlen()计算它。您可以使用sizeof
,它在编译时进行计算
- 通过同时检查大写和小写,您可以加倍工作。相反,暂时将您要查找的字符转换为大写,然后只在大写元音中查找匹配项
您还有一个主要错误,即函数不返回结果
因此,“天真”手动优化的第一步是这样的:
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
int vowels(const char str[])
{
const char VOWEL_LOOKUP[] = "AEIOU";
int vowel_count = 0;
for(; *str != '\0'; str++)
{
char ch = toupper(*str);
for(size_t i=0; i<sizeof(VOWEL_LOOKUP)-1; i++)
{
if(ch == VOWEL_LOOKUP[i])
{
vowel_count++;
break;
}
}
}
return vowel_count;
}
int main (void)
{
const char str[] = "Stack Overflow"; // 4 vowels
printf("%s: %d vowels\n", str, vowels(str));
}
#包括
#包括
#包括
int元音(const char str[])
{
常量字符元音查找[]=“AEIOU”;
int元音_计数=0;
对于(;*str!='\0';str++)
{
char ch=toupper(*str);
对于(size_t i=0;i='A'&&ch有史以来最快的事情
void ultravowulator(const char strng[])
{
char vowels[] = "aeiouAEIOU";
int vowelscnt = strlen(vowels);
int vocabular[256] = {0};
for(; *strng != '\0'; strng++) {
vocabular[*strng]++;
}
int total = 0;
for (int i = 0; i < vowelscnt; i++){
total += vocabular[vowels[i]];
}
cout << total << endl;
}
main()
{
char word[] = "Stack overflow";
ultravowulator(word);
}
void超调器(const char strng[]
{
字符元音[]=“aeiouAEIOU”;
int元音lscnt=strlen(元音);
int-vocabular[256]={0};
对于(;*strng!='\0';strng++){
声带[*strng]++;
}
int-total=0;
对于(int i=0;i
void ultravowulator(const char strng[])
{
char vowels[] = "aeiouAEIOU";
int vowelscnt = strlen(vowels);
int vocabular[256] = {0};
for(; *strng != '\0'; strng++) {
vocabular[*strng]++;
}
int total = 0;
for (int i = 0; i < vowelscnt; i++){
total += vocabular[vowels[i]];
}
cout << total << endl;
}
main()
{
char word[] = "Stack overflow";
ultravowulator(word);
}
void超调器(const char strng[]
{
字符元音[]=“aeiouAEIOU”;
int元音lscnt=strlen(元音);
int-vocabular[256]={0};
对于(;*strng!='\0';strng++){
声带[*strng]++;
}
int-total=0;
对于(int i=0;i 如果(strng[i]='a'| | strng[i]='e'…)可以生成一个长if语句,而不是内部for循环你可以在书中或网上了解更多关于循环展开的知识,这是循环优化的技术之一。优化的目标是什么?性能、代码大小、可维护性、可读性、兼容性?还有toupper()
或tolower()
和带有大小写'a':大小写'E':…元音_count++;break;
的switch
语句,而不是c的内部循环