我们需要找到使给定字符串中所有字符的频率相等所需的最少替换数,其中替换意味着我们可以将字符串中的任何字符替换为其他字符。
**所有字符应从范围“ a”到“ z”。
我找到了字符串中所有字符的频率,然后对其排序以找到中位数,然后以中位数为参考来计算实现相同频率所需的成本。 我不知道我要去哪里错了。不是实际的逻辑,但会得到一点点想法。
#include <bits/stdc++.h>
using namespace std;
long int min(int A[], long int n)
{
long int cost = 0;
sort(A, A + n);
long int K = A[n / 2];
for (long int i = 0; i < n; ++i) {
if (A[i] - K)
cost += abs(A[i] - K);
}
if (n % 2 == 0) {
long int tempcost = 0;
K = A[(n / 2) - 1];
for (long int i = 0; i < n; ++i) {
if (A[i] - K)
tempcost += abs(A[i] - K);
}
cost = min(cost, tempcost);
}
return cost;
}
int main()
{
int t;
cin >> t;
while (t--) {
string s;
cin >> s;
long int arr[26];
for (int i = 0; i < 26; i++) {
arr[i] = 0;
}
long int n = s.length();
long int count = 0;
for (long int i = 0; i < n; i++) {
arr[s[i] - 'a']++;
}
for (int i = 0; i < n; i++) {
if (arr[i]) {
count++;
}
}
int a[count], j = 0;
for (long int i = 0; i < n; i++) {
if (arr[i]) {
a[j++] = arr[i];
}
}
cout << min(a, count) << endl;
}
return 0;
}
预期结果:输入:1 aaaaabbbbccd 输出:3
答案 0 :(得分:0)
注意:最后我提出了一个建议,但涉及OP程序:
所有字符应从范围“ a”到“ z”
在主要
arr[s[i] - 'A']++;
必须
arr[s[i] - 'a']++;
执行更改是:
pi @ raspberrypi:/ tmp $ ./a.out
1
aab
1
long int arr[26];
for (int i = 0; i < 26; i++) {
arr[i] = 0;
}
可以就是这样:
long int arr[26] = { 0 };
使用蛮力
的解决方案#include <iostream>
#include <string>
using namespace std;
bool isAsolution(const string & s)
{
int count['z' - 'a' + 1] = { 0 };
for (auto c : s)
count[c - 'a'] += 1;
string::const_iterator it = s.begin();
int count0 = count[*it++ - 'a'];
while (it != s.end())
if (count[*it++ - 'a'] != count0)
return false;
return true;
}
void search(string & s, size_t pos, unsigned nChanges, unsigned & minChanges, string & sol)
{
if (pos == s.length()) {
// nChanges < minChanges, useless to check
if (isAsolution(s)) {
minChanges = nChanges;
sol = s;
}
}
else if (nChanges < (minChanges - 1)) {
for (char c = 'a'; c <= 'z'; c += 1) {
// the string is modified to avoid a lot of copies
char old = s[pos];
s[pos] = c;
search(s, pos + 1, (old == c) ? nChanges : (nChanges + 1), minChanges, sol);
s[pos] = old;
}
}
}
int main(int argc, char ** argv)
{
if (argc == 1) {
cout << "Usage : " << *argv << " <string> ... <string>" << endl;
return 0;
}
while (*++argv) {
string s = *argv;
for (auto c : s) {
if ((c < 'a') || (c > 'z')) {
cout << "invalid input, chars must be between a and z" << endl;
return 0;
}
}
if (s.empty() || isAsolution(s))
cout << s << " is already a solution" << endl;
else {
unsigned min = ~0u;
string sol;
search(s, 0, 0, min, sol);
cout << min << " changes to do " << sol << " from " << s << endl;
}
}
return 0;
}
比起先读取字符串的数目然后再读取它们在参数中给出的数字,它更实用
示例:
pi@raspberrypi:/tmp $ g++ -pedantic -Wall c.cc
pi@raspberrypi:/tmp $ ./a.out aab aze aaaaabbbbccd
1 changes to do aaa from aab
aze is already a solution
2 changes to do aaaacbbbbccc from aaaaabbbbccd
在 valgrind 下:
pi@raspberrypi:/tmp $ valgrind ./a.out aab aze aaaaabbbbccd
==8364== Memcheck, a memory error detector
==8364== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8364== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==8364== Command: ./a.out aab aze aaaaabbbbccd
==8364==
1 changes to do aaa from aab
aze is already a solution
2 changes to do aaaacbbbbccc from aaaaabbbbccd
==8364==
==8364== HEAP SUMMARY:
==8364== in use at exit: 0 bytes in 0 blocks
==8364== total heap usage: 2 allocs, 2 frees, 21,248 bytes allocated
==8364==
==8364== All heap blocks were freed -- no leaks are possible
==8364==
==8364== For counts of detected and suppressed errors, rerun with: -v
==8364== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
您看到的 aaaaabbbbccd 只需2个更改,而不是3:-)