c++ - 在最少的操作中实现字符串所有字符的相同频率。(所有字符都从 'a' 到 'z')
问题描述
我们需要找到使给定字符串中所有字符的频率相等所需的最小替换次数,其中替换意味着我们可以将字符串中的任何字符替换为其他字符。
**所有字符应从“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
解决方案
注意:我在最后提出了一个建议,但关于 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 处 :-)
推荐阅读
- typescript - 从 React Native 过渡到 Flutter 时最重要的方面
- java - 如何在 javafx 多文件选择器中维护选定文件的顺序
- vue.js - v-treeview展开折叠实现
- r - 在 R 中解释夏皮罗威尔克测试
- c# - Fluent Validation 从不适用于任何条件 MVC 5
- curl - 使用 cygwin 和 curl 使用 crontab 将文件上传到 ftp
- ios - Xcode11:无法安装“AppName”
- python - 如何改进这个预测给定数字是奇数还是偶数的 Keras 模型
- javascript - 如何在表单验证中显示角度模板中的元素?
- python - PySpark Column 获取连接为字符串的值