LeetCode算法题:字符串中元音字符翻转。
题目
LeetCode:LeetCode 75 -
学习计划-05-反转字符串中的元音字母
给你一个字符串 s
,仅反转字符串中的所有元音字母,并返回结果字符串。
元音字母包括
'a'、'e'、'i'、'o'、'u',且可能以大小写两种形式出现不止一次。
思路
待查找字符已知,从左右两端搜索对应值即可。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| int isVowels(char ch);
char* reverseVowels(char* s) { assert(s);
char* left = s; char* right = s + strlen(s) - 1;
while(right - left > 0) { if(isVowels(*left)) { left++; } else if(isVowels(*right)) { right--; } else { int tmp = *left; *left = *right; *right = tmp; left++; right--; } } return s; }
const char arrVowels[10] = {'a','A','o','O','e','E','i','I','u','U'}; int isVowels(char ch) { for(int i=0;i<sizeof(arrVowels)/sizeof(char);i++) { if(arrVowels[i] == ch) { return 0; } } return 1; }
|
该方案使用const数组对字符进行封装,适合多次调用时功能的扩展移植。功能采用单个while循环完成,但内部if-else会影响流水线,因此进行优化为双重循环。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| char* reverseVowels(char* s) { assert(s);
char* left = s; char* right = s + strlen(s) - 1;
while(right - left > 0) { while(isVowels(*left)) { left++; } while(isVowels(*right)) { right--; } else { int tmp = *left; *left = *right; *right = tmp; left++; right--; } } return s; }
|
如果向修改isVowels函数,可以调整为如下:
1 2 3 4 5 6 7 8 9 10 11 12
| const char arrVowels[10] = {'a','A','o','O','e','E','i','I','u','U'}; bool isVowels(char ch) { for(int i=0;i<sizeof(arrVowels)/sizeof(char);i++) { if(arrVowels[i] == ch) { return false; } } return true; }
|
而若调用次数不多,可使用以下代码,逻辑或||相对于逻辑与&&减少判断次数,加快运行时间:
1 2 3 4 5 6 7 8 9 10
| bool isVowels(char ch) {
return (ch=='a'|| ch=='A'|| ch=='o'|| ch=='O'|| ch=='e'|| ch=='E'|| ch=='i'|| ch=='I'||ch=='u'|| ch=='U'); }
|
————————— End —————————
缺月挂疏桐,漏断人初静。–《卜算子·黄州定慧院寓居作》