[Kata 7 C++]Compare Strings by Sum of Chars

描述

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算法返回累加的结果,其返回类型就是其第三个实参的类型。
第四个形参 是定义应用到总数和元素之间的二元函数对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值