C++ 使字符串的不同字符相等的最小步骤数

C++ 使字符串的不同字符相等的最小步骤数,c++,algorithm,C++,Algorithm,我正试图编写一个程序,要求用户输入字符串,我的工作是打印出使字符串中不同字符的频率相等所需的最小步数。 示例 输入 6 aba abba abbc abbbc codedigger codealittle 1 0 1 2 2 3 输出 6 aba abba abbc abbbc codedigger codealittle 1 0 1 2 2 3 这是我的节目: #include <iostream> #include <st

我正试图编写一个程序,要求用户输入字符串,我的工作是打印出使字符串中不同字符的频率相等所需的最小步数。
示例
输入

6
aba  
abba  
abbc  
abbbc  
codedigger  
codealittle 
1
0
1
2
2
3
输出

6
aba  
abba  
abbc  
abbbc  
codedigger  
codealittle 
1
0
1
2
2
3
这是我的节目:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;

int main()
{
    unordered_map<char, int >m;
    vector<int> vec1, vec2;
    string s;
    int n;

    cin >> n;
    cin.ignore();

    for (int i = 0; i < n; ++i)
    {
        m.clear();
        vec1.clear();
        getline(cin, s);
        for (int i = 0; i < s.size(); i++)
            m[s[i]]++;

        for (auto itr : m)
            vec1.push_back(itr.second);

        sort(vec1.begin(), vec1.end());

        int mid = vec1[vec1.size() / 2];
        int ans = 0;

        for (auto itr : vec1)
            ans += abs(mid - itr);

        vec2.push_back(ans);
    }
    for (int i = 0; i < vec2.size(); ++i)
        cout << vec2[i] << endl;
}

我不明白为什么我会得到错误的结果,有人能帮我吗?谢谢你的帮助

问题在于,您的算法没有找到最佳步数

考虑您为以下内容获得错误答案的字符串:
codedigger
。它有4个频率为1的字母(
coir
)和3个频率为2的字母(
ddeegg
)。 最佳的方法是不要将频率2的一半字母转换成某些新字符(字符串中不存在)以使所有频率为1。据我所知,您的实现正在计算这将需要的步骤数。 相反,考虑一下:

c[o]dedigge[r]

如果我将
o
替换为
c
,将
r
替换为
I
,我将获得:

ccdediggei

它已经具有均衡的字符频率。您会注意到,我只执行了2次编辑


因此,如果不给你一个解决方案,我相信这仍然可以回答你的问题?考虑到这一点,您可能会想出一种不同的算法,能够找到最佳的编辑次数。

您的代码正确地测量每个字母的频率,作为重要信息

但当时主要有两个问题:

  • 主要目标值(最终均衡频率)不一定等于中值。特别是,此值必须除以字母总数
  • 对于给定的目标高度值,您计算的步数不正确。你必须注意不要计算两次相同的突变。此外,一般公式是不同的,取决于不同字母的最终数量是否等于、小于或大于原始字母数量
下面的代码关注的是正确性,而不是效率。它考虑了目标高度(频率)的所有可能值,即字母总数的所有除数

如果效率实际上是一个关注点(在文章中没有提到),那么例如,可以认为最佳值不太可能与初始平均频率值相差很远。

#包括
#包括
#包括
#包括
#包括
#包括
//计算给定目标的步数
//此代码假定频率按降序排序。
int n_步数(标准::向量和频率,int目标,int nchar){
整数和=0;
int n=频率大小();
int m=nchar/target;//新字符数
int imax=std::min(n,m);
对于(int i=0;in)和+=m-n;
总和/=2;
回报金额;
}
int main(){
std::无序的_mapm;
std::vec1,vec2;
std::字符串s;
int n;
标准:cin>>n;
std::cin.ignore();
对于(int i=0;i>s;
对于(int i=0;i对于(int target=1;target那么,当您使用调试器逐行检查代码时,您观察到了什么?是否所有变量都按照您的预期进行了更改?您应该详细说明在每个步骤中允许执行哪些操作。例如,是否允许您添加新字符?@Damien,不允许您添加新字符,just更改字符串的字符,使所有不同字符的频率相同。我不知道为什么这个问题被关闭。我相信我理解OP的问题,并且我已经为它编写了一个答案,我现在无法发布。在我看来,他/她的问题不是他/她的代码“不工作”的原因但是为什么算法不是最优的。我投票重新打开这篇文章是因为以下原因:代码应该做什么现在已经很清楚了。OP提出了一个非常接近好的算法。我们有一个mre。我们有一个简单的测试用例,有正确/错误的答案。