C++ 在单个字符串中查找重复次数最多和次最多的字符
我可以找到重复次数最多的字符,但是我找不到第二个重复次数最多的字符 我不明白找到第二重复字符的逻辑C++ 在单个字符串中查找重复次数最多和次最多的字符,c++,C++,我可以找到重复次数最多的字符,但是我找不到第二个重复次数最多的字符 我不明白找到第二重复字符的逻辑 void most_frequent_letter(string str, struct frequents result[]) int len = str.length(); int max = 0, i = 0, k = 0, Secmax = 0, m = 0; for (i = 0 ; i <= len; ++i) { if (str[i] >
void most_frequent_letter(string str, struct frequents result[])
int len = str.length();
int max = 0, i = 0, k = 0, Secmax = 0, m = 0;
for (i = 0 ; i <= len; ++i)
{
if (str[i] >= 48 && str[i] <= 57)
{
result[0].count = 0;
break;
}
if(str[i] >= 65 && str[i] <= 90)
{
str[i] += 32;
}
result[i].letter = str[i];
result[i].count++;
if (result[i].count > max && result[i].letter != ' ')
{
max = result[i].count;
result[0].count = result[i].count;
result[0].letter = str[i];
}
}
cout << result[0].letter << endl;
void most\u frequents\u字母(string str,struct frequents result[])
int len=str.length();
int max=0,i=0,k=0,Secmax=0,m=0;
对于(i=0;i=48&&str[i]=65&&str[i]max&&result[i]。字母!=“”)
{
max=结果[i]。计数;
结果[0]。计数=结果[i]。计数;
结果[0],字母=str[i];
}
}
cout没有给出struct frequents
背后的详细信息,但从提供的代码中,我猜只考虑了字母(isalpha()
)。
虽然问题中的代码看起来像C,但它被标记为C++,使用了<代码> STD::String >,因此这里提出C++解决方案。
建议的解决方案使用每个字母带有一个计数器的向量('a'
到'z'
)。
第一阶段包括计算句子中字母的每次出现次数(忽略大小写)。
然后在该向量中找到最大元素,得到重复次数最多的字母。
在取消相应计数器后,同一向量中的下一个最大元素给出第二个重复次数最多的字母
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
#include <algorithm>
std::vector<int> // letter counts
count_letters(const std::string &str)
{
auto counts=std::vector<int>(1+'z'-'a');
for(const auto &c: str)
{
if(std::isalpha(c))
{
++counts[std::tolower(c)-'a'];
}
}
return counts;
}
int
main()
{
const auto txt=std::string{"Here is a sentence"};
auto counts=count_letters(txt);
const auto max_iter=std::max_element(cbegin(counts), cend(counts));
const auto max_index=std::distance(cbegin(counts), max_iter);
std::cout << "max: " << char('a'+max_index)
<< " (" << counts[max_index] << ")\n";
counts[max_index]=0; // cancel first max found
const auto second_max_iter=std::max_element(cbegin(counts), cend(counts));
const auto second_max_index=std::distance(cbegin(counts), second_max_iter);
std::cout << "second max: " << char('a'+second_max_index)
<< " (" << counts[second_max_index] << ")\n";
return 0;
}
struct frequents
后面的细节没有给出,但从提供的代码中,我猜只考虑了字母(isalpha()
)
虽然问题中的代码看起来像C,但它被标记为C++,使用了<代码> STD::String >,因此这里提出C++解决方案。
建议的解决方案使用每个字母带有一个计数器的向量('a'
到'z'
)。
第一阶段包括计算句子中字母的每次出现次数(忽略大小写)。
然后在该向量中找到最大元素,得到重复次数最多的字母。
在取消相应计数器后,同一向量中的下一个最大元素给出第二个重复次数最多的字母
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
#include <algorithm>
std::vector<int> // letter counts
count_letters(const std::string &str)
{
auto counts=std::vector<int>(1+'z'-'a');
for(const auto &c: str)
{
if(std::isalpha(c))
{
++counts[std::tolower(c)-'a'];
}
}
return counts;
}
int
main()
{
const auto txt=std::string{"Here is a sentence"};
auto counts=count_letters(txt);
const auto max_iter=std::max_element(cbegin(counts), cend(counts));
const auto max_index=std::distance(cbegin(counts), max_iter);
std::cout << "max: " << char('a'+max_index)
<< " (" << counts[max_index] << ")\n";
counts[max_index]=0; // cancel first max found
const auto second_max_iter=std::max_element(cbegin(counts), cend(counts));
const auto second_max_index=std::distance(cbegin(counts), second_max_iter);
std::cout << "second max: " << char('a'+second_max_index)
<< " (" << counts[second_max_index] << ")\n";
return 0;
}
这是一个很好的例子,如果您愿意,可以对其进行优化
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <iterator>
void find_most_repeated(std::string strData)
{
std::map<char, int> mChars;
for (int i = 0; i < strData.size(); i++)
mChars[strData[i]] ++;
std::vector<std::pair<char, int>> v{ std::make_move_iterator(begin(mChars)), std::make_move_iterator(end(mChars)) };
std::sort(begin(v), end(v),
[](const std::pair<char, int>& p1, const std::pair<char, int>& p2) {return p1.second > p2.second; });
std::cout << v[0].first << " " << v[1].first << std::endl;
}
int main()
{
find_most_repeated(std::string("asdaaaasssaaaaa"));
}
#包括
#包括
#包括
#包括
#包括
#包括
void find_most_repeated(std::string strData)
{
标准::map mChars;
对于(int i=0;ip2.second;});
std::cout这是一个运行良好的示例,如果您愿意,可以对其进行优化
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <iterator>
void find_most_repeated(std::string strData)
{
std::map<char, int> mChars;
for (int i = 0; i < strData.size(); i++)
mChars[strData[i]] ++;
std::vector<std::pair<char, int>> v{ std::make_move_iterator(begin(mChars)), std::make_move_iterator(end(mChars)) };
std::sort(begin(v), end(v),
[](const std::pair<char, int>& p1, const std::pair<char, int>& p2) {return p1.second > p2.second; });
std::cout << v[0].first << " " << v[1].first << std::endl;
}
int main()
{
find_most_repeated(std::string("asdaaaasssaaaaa"));
}
#包括
#包括
#包括
#包括
#包括
#包括
void find_most_repeated(std::string strData)
{
标准::map mChars;
对于(int i=0;ip2.second;});
std::cout例如,我认为您可以将字母计数器存储为std::map
。然后您只需对字符串进行迭代,如果计数器已经包含当前的char
,您可以将其递增,否则添加它并将值设置为零
然后:
- 搜索最高的计数值:您将获得最频繁的字母
- 删除贴图中的相应元素
- 再次搜索最高的计数值:您将得到第二个最频繁的字母
下面的例子应该更加明确:
#include <map>
#include <algorithm>
bool compare(const std::pair<char, int> & a, const std::pair<char, int> & b)
{
return (a.second < b.second);
}
bool most_frequent_letter(const std::string & str, std::pair<char, char> & results)
{
if(str.length() >= 2)
{
std::map<char, int> counter;
for(const char & c : str)
++counter[c];
std::map<char, int>::const_iterator it_max = std::max_element(counter.cbegin(), counter.cend(), &compare);
char c_max = it_max->first;
counter.erase(it_max);
it_max = std::max_element(counter.cbegin(), counter.cend(), &compare);
char c_second = it_max->first;
results = std::make_pair(c_max, c_second);
return true;
}
else
return false;
}
我测试了它,它成功地工作了
我试图使这个例子尽可能简单,我希望它会有所帮助。我想你可以将一个字母计数器存储为一个std::map
。然后你只需迭代你的字符串,如果计数器已经包含当前的char
,你可以增加它,否则你可以添加它并将值设置为零
然后:
- 搜索最高的计数值:您将获得最频繁的字母
- 删除贴图中的相应元素
- 再次搜索最高的计数值:您将得到第二个最频繁的字母
下面的例子应该更加明确:
#include <map>
#include <algorithm>
bool compare(const std::pair<char, int> & a, const std::pair<char, int> & b)
{
return (a.second < b.second);
}
bool most_frequent_letter(const std::string & str, std::pair<char, char> & results)
{
if(str.length() >= 2)
{
std::map<char, int> counter;
for(const char & c : str)
++counter[c];
std::map<char, int>::const_iterator it_max = std::max_element(counter.cbegin(), counter.cend(), &compare);
char c_max = it_max->first;
counter.erase(it_max);
it_max = std::max_element(counter.cbegin(), counter.cend(), &compare);
char c_second = it_max->first;
results = std::make_pair(c_max, c_second);
return true;
}
else
return false;
}
我测试了它,它成功地工作了
我试图使这个示例尽可能简单,希望它能有所帮助。在获取字符串中最频繁的前两个字符时,这里有一个稍微不同的转折点。由于std::map
是一个按键排序的关联容器,请参见,在创建初始映射后,列出中每个字符的频率de>std::map
,您只需将成员转过来(即
,并将第一个映射的结果添加到第二个映射,指定std::greer
排序(而不是默认的std::less
排序顺序)
例如:
void find_most_repeated (std::string str)
{
std::map<char, int> mchars;
std::map<int, char, std::greater<int>> mfreq;
size_t nmostfreq = 0;
for (const auto& c : str) /* fill char/occurrence map */
mchars[c]++;
if (mchars.size() < 2) { /* validate 2 unique chars in str */
std::cerr << "error: str consists of a single character.\n";
return;
}
for (const auto& pair : mchars) /* fill sorted occurrence/char map */
mfreq[pair.second] = pair.first;
for (const auto& pair : mfreq) { /* output 2 most frequent chars */
std::cout << " " << pair.second;
if (++nmostfreq == 2)
break;
}
std::cout << '\n';
}
我相信可能还有十几种方法可以解决这个问题。在获取字符串中最常见的前两个字符时,这里有一个稍微不同的方法。由于std::map
是一个按键排序的关联容器,请参见,在创建初始映射后,列出std::map中每个字符的频率
,您只需将成员转过来(即
并将第一个映射的结果添加到第二个映射,指定std::greer
排序(而不是默认的std::less
排序顺序)
例如:
void find_most_repeated (std::string str)
{
std::map<char, int> mchars;
std::map<int, char, std::greater<int>> mfreq;
size_t nmostfreq = 0;
for (const auto& c : str) /* fill char/occurrence map */
mchars[c]++;
if (mchars.size() < 2) { /* validate 2 unique chars in str */
std::cerr << "error: str consists of a single character.\n";
return;
}
for (const auto& pair : mchars) /* fill sorted occurrence/char map */
mfreq[pair.second] = pair.first;
for (const auto& pair : mfreq) { /* output 2 most frequent chars */
std::cout << " " << pair.second;
if (++nmostfreq == 2)
break;
}
std::cout << '\n';
}
我相信可能还有十几种方法可以解决这个问题。不要使用“幻数”,比如65
,而是使用'a'
等。更好的方法是:使用isdigit
,isalpha
,toupper
等。还有用于(I=0;I用于(I=0;I
还有其他一些问题。你不觉得吗