给出一个字符串,我需要找到可以通过从字符串中删除或改组字符来构造的最长回文。如果存在多个相同长度的回文,那么我需要确保按字典顺序给出最小的回文。 示例:“ adskassda”,预期输出为:“ adsasda”
我能够找到最大的回文,但是如何确保在最大相同的最大长度的情况下,按字典顺序最小的输出作为输出?
任何回文串可以分为三部分–乞g,中音和结尾。对于奇数长度的回文字符串,例如2n + 1,“ beg”由字符串的前n个字符组成,“ mid”仅由1个字符组成,即第(n + 1)个字符,“ end”由后n个字符组成回文字符串。对于长度为2n的回文串,“ mid”将始终为空。应当注意,“ end”将与“ beg”相反,以便使字符串成为回文。 我也为此使用了相同的逻辑。
#include <bits/stdc++.h>
using namespace std;
string longestPalindrome(string str){
map<char,int> frequencyChar;
for(int i=0;i<str.length();i++){
frequencyChar[str[i]]++;
}
char middle_character;
string leftStr;
for(auto it: frequencyChar){
char currentChar=it.first;
int frequencyCurrentChr = it.second;
if(frequencyCurrentChr%2!=0){
middle_character=currentChar;
}
leftStr.append(frequencyCurrentChr/2,currentChar);
}
string rightStr(leftStr.rbegin(),leftStr.rend());
return leftStr + middle_character + rightStr;
}
int main() {
string str = "adskassda";
cout<<longestPalindrome(str);
}
我正在获取“ adsssda”,但预期是“ adsasda”
答案 0 :(得分:0)
这似乎对我有用,尽管我的测试还远远不够:
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
int main()
{
string in("adskassda");
map<char, int> chars;
string out;
for (auto c : in)
{
++chars[c];
}
string middle;
for (auto e : chars)
{
if (e.second >= 2)
{
out.append(e.second/2, e.first);
e.second = e.second%2;
}
if (e.second && middle.empty())
middle = e.first;
}
string tail(out);
reverse(tail.begin(), tail.end());
out = out + middle + tail;
cout << in << endl;
cout << out << endl;
}
答案 1 :(得分:0)
您只有一个简单的错误。当您要选择中间字符时,第一次看到具有奇数频率的字符时,就应该选择它,并且永远不要再对其进行更新,因为它将是字典顺序最低的那个。这就是为什么我添加了布尔变量mid_char_chosen
并将其设置为true不会再次更新的原因。您还没有考虑另一个极端的情况:如果所有频率都是偶数,则不会有中间字符,并且结果将有偶数个字符。因此,输出应省略中间字符。经过这些小的修改,我认为代码可以运行:
#include <bits/stdc++.h>
using namespace std;
string longestPalindrome(string str){
map<char,int> frequencyChar;
for(int i=0;i<str.length();i++){
frequencyChar[str[i]]++;
}
char middle_character;
string leftStr;
bool mid_char_chosen = false;
for(auto it: frequencyChar){
char currentChar=it.first;
int frequencyCurrentChr = it.second;
if(!mid_char_chosen and frequencyCurrentChr%2!=0){
middle_character=currentChar;
mid_char_chosen = true;
}
leftStr.append(1*(frequencyCurrentChr/2),currentChar);
}
string rightStr(leftStr.rbegin(),leftStr.rend());
if (mid_char_chosen)
return leftStr + middle_character + rightStr;
else
return leftStr + rightStr;
}
int main() {
string str = "adskassda";
cout<<longestPalindrome(str) << endl;
}
答案 2 :(得分:0)
我在代码中添加了一个小改动 - 一旦我们得到左边的部分,就按字典顺序排序。这在 Java 中可能是必需的。 当我用java写上面的代码时,我得到了“asdadsa”而不是“adsasda”
Java 代码如下:
use Drupal\Component\Utility\Html;
可能需要进行一些重构,例如使用 Java 中的现有库在 StringBuilder 中添加重复字符。但是上面的代码提供了解决方案。