题目
我们定义,在以下情况时,单词的大写用法是正确的:
- 全部字母都是大写,比如 “USA” 。
- 单词中所有字母都不是大写,比如 “leetcode” 。
- 如果单词不只含有一个字母,只有首字母大写,比如 “Google” 。
给你一个字符串 word
。如果大写用法正确,返回 true
;否则,返回 false
。
示例 1:
输入:word = “USA”
输出:true
示例 2:
输入:word = “FlaG”
输出:false
提示:
- 1 <= word.length <= 100
- word 由小写和大写英文字母组成
代码
完整代码
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
bool isBig(char c) {
return (c >= 'A' && c <= 'Z');
}
bool isSmall(char c) {
return (c >= 'a' && c <= 'z');
}
bool detectCapitalUse(char* word) {
bool isBeginBig = isBig(word[0]);
bool mix = false;
for (int i = 1; i < strlen(word); i++) {
if (isBeginBig) {
if (!mix && isSmall(word[i])) {
if (i != 1) { // 不是第二个开始就是小写
return false;
}
mix = true;
}
if (mix) {
if (isBig(word[i])) { // 有小写且非首字母有大写
return false;
}
}
} else {
if (isBig(word[i])) { // 非首字母有大写
return false;
}
}
}
return true;
}
// int main(void)
// {
// printf("a = %d",'a');
// printf("A = %d",'A');
// }
思路分析
这套代码用了模拟的方法。
- 首先,判断第一个字母是否是大写字母。
- 遍历整个字符串,检查是否符合所有大写或所有小写的规则。
- 如果第一个字母是大写,则后续字符可以全为小写或全为大写。
- 如果第一个字母是小写,则后续字符必须全为小写。
- 在遍历过程中,如果发现任何不符合上述规则的情况,则返回
false
,否则返回true
。
拆解分析
isBig
函数
bool isBig(char c) {
return (c >= 'A' && c <= 'Z');
}
判断字符是否为大写字母。
isSmall
函数
bool isSmall(char c) {
return (c >= 'a' && c <= 'z');
}
判断字符是否为小写字母。
detectCapitalUse
函数
bool detectCapitalUse(char* word) {
bool isBeginBig = isBig(word[0]);
bool mix = false;
for (int i = 1; i < strlen(word); i++) {
if (isBeginBig) {
if (!mix && isSmall(word[i])) {
if (i != 1) { // 不是第二个开始就是小写
return false;
}
mix = true;
}
if (mix) {
if (isBig(word[i])) { // 有小写且非首字母有大写
return false;
}
}
} else {
if (isBig(word[i])) { // 非首字母有大写
return false;
}
}
}
return true;
}
主要函数,遍历字符串,判断是否符合大写规则。
复杂度分析
- 时间复杂度:O(n),其中
n
为字符串的长度,需要遍历每个字符。 - 空间复杂度:O(1),不需要额外的空间,仅使用了几个额外变量。
一题多解
正则表达式解法
完整代码
#include <stdbool.h>
#include <regex.h>
bool detectCapitalUse(char* word) {
regex_t regex;
int reti;
// 编译正则表达式
reti = regcomp(®ex, "^[A-Z]+$|^[a-z]+$|^[A-Z][a-z]+$", REG_EXTENDED);
if (reti) {
return false; // 如果正则表达式编译失败,返回 false
}
// 执行正则表达式
reti = regexec(®ex, word, 0, NULL, 0);
regfree(®ex);
if (!reti) {
return true; // 如果正则表达式匹配,返回 true
} else if (reti == REG_NOMATCH) {
return false; // 如果正则表达式不匹配,返回 false
} else {
return false; // 如果正则执行中发生其他错误,返回 false
}
}
思路分析
这套代码用了正则表达式的方法。
- 使用正则表达式来匹配符合大写规则的字符串。
- 正则表达式
^[A-Z]+$|^[a-z]+$|^[A-Z][a-z]+$
分别匹配全部大写、全部小写和首字母大写的情况。
拆解分析
- 编译正则表达式
// 编译正则表达式
reti = regcomp(®ex, "^[A-Z]+$|^[a-z]+$|^[A-Z][a-z]+$", REG_EXTENDED);
if (reti) {
return false; // 如果正则表达式编译失败,返回 false
}
编译用于匹配大写规则的正则表达式。
- 执行正则表达式
// 执行正则表达式
reti = regexec(®ex, word, 0, NULL, 0);
regfree(®ex);
if (!reti) {
return true; // 如果正则表达式匹配,返回 true
} else if (reti == REG_NOMATCH) {
return false; // 如果正则表达式不匹配,返回 false
} else {
return false; // 如果正则执行中发生其他错误,返回 false
}
执行正则表达式,并根据匹配结果返回对应的布尔值。
复杂度分析
- 时间复杂度:O(n),其中
n
为字符串的长度,正则表达式匹配需要遍历每个字符。 - 空间复杂度:O(1),不需要额外的空间。