假设您给了一个字符串“香蕉”。
您想找出在“香蕉”中可以找到“ ana”的次数。因此,该数字为2。
string s = "banana";
int num = 0,pos = 0;
pos = s.find("ana");
while(pos!=string::npos) {
num++;
pos = s.find("ana",pos+1);
}
cout<<num<<endl;
问题是,我想为此编写较短的代码。可以使用哪些功能?我尝试使用search(),但这不是我想要的。 Count()仅用于字符。
还有其他功能可以帮助我做到这一点吗? (不允许在比赛中使用助推器,因此不允许。)
答案 0 :(得分:1)
假设最终您还打算计算一个短语的任何可能的复制,那么这里有3个通用函数模板,它们几乎适用于任何容器或指针/数组,只要为它们提供了正确的first / last迭代器而不是容器!
#include <iterator>
#include <algorithm>
#include <map>
#include <vector>
//finding the occurrence for an specific case within a range
template<typename rng_t__, typename dif_t__ = typename std::iterator_traits<rng_t__>::difference_type>
dif_t__ occurrence(const rng_t__ rng_fst_, const rng_t__ rng_lst_, const rng_t__ schd_fst_, const rng_t__ schd_lst){
dif_t__ counter = 0;
for (rng_t__ it = rng_fst_; (it = std::search(it, rng_lst_, schd_fst_, schd_lst))++ != rng_lst_; ++counter);
return counter;
}
//finding the replications for all subsets with certain length within a range
template<typename rng_t__, typename dif_t__ = typename std::iterator_traits<rng_t__>::difference_type, typename val_t__ = typename std::iterator_traits<rng_t__>::value_type>
dif_t__ replications(const rng_t__ rng_fst_, const rng_t__ rng_lst_, dif_t__ lnt_){
if(!lnt_ or lnt_ >= std::distance(rng_fst_, rng_lst_)) return 0;
rng_t__ it_lst = rng_fst_;
for (--lnt_; lnt_--; ++it_lst);
std::map<std::vector<val_t__>, dif_t__> cases;
for (rng_t__ it_fst = rng_fst_; it_lst++ != rng_lst_; ++it_fst){
auto it_rslt_pair = cases.insert({{it_fst, it_lst}, 0});
if(! it_rslt_pair.second) ++(it_rslt_pair.first->second);
}
dif_t__ counter = 0;
for (const auto& a_case : cases) counter += a_case.second;
return counter;
}
//finding the replications for all subsets with all possible lengths within a range
template<typename rng_t__, typename dif_t__ = typename std::iterator_traits<rng_t__>::difference_type, typename val_t__ = typename std::iterator_traits<rng_t__>::value_type>
dif_t__ replications(const rng_t__ rng_fst_, const rng_t__ rng_lst_){
const dif_t__ rng_lnt = std::distance(rng_fst_, rng_lst_);
dif_t__ counter = 0;
for (dif_t__ a_lnt = 0; ++a_lnt < rng_lnt; counter += replications(rng_fst_, rng_lst_, a_lnt));
return counter;
}
#include <string>
int main(int argc, char** argv) {
std::string range = "banana", searched = "ana";
std::cout<< "total occurrence for the ana" << std::endl;
std::cout<< occurrence("banana", "banana" + 6, "ana", "ana" +3) << std::endl;
std::cout<< occurrence(range.begin(), range.end(), searched.begin(), searched.end()) << std::endl;
std::cout<< "total replications for every phrase from banana with length of 3" << std::endl;
std::cout<< replications("banana", "banana" + 6, 3) << std::endl;
std::cout<< replications(range.begin(), range.end(), 3) << std::endl;
std::cout<< "total replications for every phrase from banana with every possible length" << std::endl;
std::cout<< replications("banana", "banana" + 6) << std::endl;
std::cout<< replications(range.begin(), range.end()) << std::endl;
return 0;
}
可能的输出:
total occurrence for the ana
2
2
total replications for every phrase from banana with length of 3
1
1
total replications for every phrase from banana with every possible length
6
6
祝你比赛顺利!
答案 1 :(得分:0)
我想为此编写较短的代码
您要使用while (true)
和break
:
std::string s{"banana"};
std::string::size_type pos{0};
int num{0};
while (true) {
pos = s.find("ana", pos);
if (pos == std::string::npos) break;
pos += 2; // next possible place for an "ana";
++num;
}
std::cout << num << "\n";
答案 2 :(得分:0)
您可以为此使用for
循环:
string s = "banana";
int num = 0;
for (auto pos = s.find("ana"); pos != string::npos; pos = s.find("ana",pos+1))
num++;
cout << num << endl;
如您所见,我使用auto
作为pos
的类型,因此它将具有正确的类型std::string::size_type
。
答案 3 :(得分:0)
大概最简单的代码而不牺牲可读性是这样的:
std::string s = "banana";
int num = 0;
size_t pos = 0;
while ((pos = s.find("ana", pos)) != std::string::npos)
{
num++;
pos++;
}
std::cout << num << "\n";
或作为for循环:
std::string s = "banana";
int num = 0;
for (size_t pos = 0; (pos = s.find("ana", pos)) != std::string::npos; num++, pos++)
{
}
std::cout << num << "\n";