描述
Compare two strings by comparing the sum of their values (ASCII character code).
For comparing treat all letters as UpperCase
null/NULL/Nil/None should be treated as empty strings
If the string contains other characters than letters, treat the whole string as it would be empty
Your method should return true, if the strings are equal and false if they are not equal.
"AD", "BC" -> equal
"AD", "DD" -> not equal
"gf", "FG" -> equal
"zz1", "" -> equal (both are considered empty)
"ZzZz", "ffPFF" -> equal
"kl", "lz" -> not equal
null, "" -> equal
测试用例
#include<string>
Describe(Tests)
{
It(ExampleTests)
{
Assert::That(compare("AD", "BC"), Equals(true));
}
It(MoreTests)
{
Assert::That(compare("AD", "DD"), Equals(false));
Assert::That(compare("gF", "FG"), Equals(true));
Assert::That(compare("Ad", "DD"), Equals(false));
Assert::That(compare("zz1", ""), Equals(true));
Assert::That(compare("ZzZz", "ffPFF"), Equals(true));
Assert::That(compare("kl", "lz"), Equals(false));
Assert::That(compare("", ""), Equals(true));
Assert::That(compare("!!", "7476"), Equals(true));
Assert::That(compare("##", "1176"), Equals(true));
}
It(RandomTests)
{
srand(time(0));
for(int i = 0; i < 40; i++)
{
char letter1 = char(65 + rand()%26);
char letter2 = '1';
do
{
letter2 = char(65 + rand()%26);
}
while(letter1 == letter2);
if(rand()%2 == 0)
{
std::string testString1 = std::string(5, std::toupper(letter1)) + letter2;
std::string testString2 = letter2 + std::string(5, std::tolower(letter1));
Assert::That(compare(testString1, testString2), Equals(true));
}
if(rand()%2 == 0)
{
std::string testString1 = std::string(4, std::toupper(letter1)) + letter2 + letter2;
std::string testString2 = letter2 + std::string(5, std::tolower(letter1));
Assert::That(compare(testString1, testString2), Equals(false));
}
}
}
};
解决方案
一般遍历
// Calculate the char-value of the string
int charvalue(std::string s){
int sum = 0;
for(char &c : s){
if(!std::isalpha(c))
return 0;
sum += std::toupper(c);
}
return sum;
}
bool compare(std::string s1, std::string s2)
{
return charvalue(s1) == charvalue(s2);
}
algorithm库
#include <numeric>
#include <algorithm>
#include <cctype>
int sumValues(std::string const &s) {
if (!std::all_of(s.begin(), s.end(), [](char c) { return std::isalpha(c); })) return 0;
return std::accumulate(s.begin(), s.end(), 0, [](int sum, char c) { return sum + std::toupper(c); });
/* 还可以写成
if (std::all_of(s.begin(), s.end(), isalpha))
{
return std::accumulate(s.begin(), s.end(), 0, [](int acc, char c){return acc + toupper(c);});;
}
return 0;
*/
}
bool compare(std::string s1, std::string s2)
{
return sumValues(s1) == sumValues(s2);
}
使用algorithm库,实际遍历的次数变多,但代码量小,如果熟练使用,也是一个不错的选择。
algorithm 头文件中定义了 3 种算法,用来检查在算法应用到序列中的元素上时,什么时候使谓词返回 true。这些算法的前两个参数是定义谓词应用范围的输入迭代器;第三个参数指定了谓词。
all_of() 算法会返回 true,前提是序列中的所有元素都可以使谓词返回 true。
any_of() 算法会返回 true,前提是序列中的任意一个元素都可以使谓词返回 true。
none_of() 算法会返回 true,前提是序列中没有元素可以使谓词返回 true。
这个谓词是一个 lambda 表达式 返回布尔值
accumulate定义在#include中,作用有两个,一个是累加求和,另一个是自定义类型数据的处理
int sum = accumulate(vec.begin() , vec.end() , 42);
accumulate带有三个形参:头两个形参指定要累加的元素范围,第三个形参则是累加的初值。
accumulate函数将它的一个内部变量设置为指定的初始值,然后在此初值上累加输入范围内所有元素的值。accumulate算法返回累加的结果,其返回类型就是其第三个实参的类型。
第四个形参 是定义应用到总数和元素之间的二元函数对象