C++ 在有多个回文的情况下查找最长但按词典编纂最小的回文
给定一个字符串,我需要找到最长的回文,它可以通过从字符串中删除或洗牌字符来构造。如果存在多个长度相同的回文,那么我需要确保输出的是词典中最小的回文。 示例:“adskassda”预期输出为:“adsasda” 我能够找到最大的回文,但如何确保在相同最大长度的多个回文的情况下,按词典编纂的最小回文作为输出 任何回文字符串都可以分为三个部分——beg、mid和end。对于奇数长度的回文字符串,例如2n+1,“beg”由字符串的前n个字符组成,“mid”将仅由1个字符组成,即第(n+1)个字符,“end”将由回文字符串的最后n个字符组成。对于偶数长度为2n的回文字符串,“mid”将始终为空。应该注意的是,“end”将与“beg”相反,以便字符串是回文的。 我也使用了同样的逻辑C++ 在有多个回文的情况下查找最长但按词典编纂最小的回文,c++,algorithm,palindrome,C++,Algorithm,Palindrome,给定一个字符串,我需要找到最长的回文,它可以通过从字符串中删除或洗牌字符来构造。如果存在多个长度相同的回文,那么我需要确保输出的是词典中最小的回文。 示例:“adskassda”预期输出为:“adsasda” 我能够找到最大的回文,但如何确保在相同最大长度的多个回文的情况下,按词典编纂的最小回文作为输出 任何回文字符串都可以分为三个部分——beg、mid和end。对于奇数长度的回文字符串,例如2n+1,“beg”由字符串的前n个字符组成,“mid”将仅由1个字符组成,即第(n+1)个字符,“en
#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);
}
#包括
使用名称空间std;
字符串最长回文组(字符串str){
映射频率字符;
对于(int i=0;i这似乎对我有效,尽管我的测试还远远不够广泛:
#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;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int main()
{
串入(“adskassda”);
地图字符;
串出;
用于(自动c:in)
{
++chars[c];
}
中弦;
用于(自动e:chars)
{
如果(例如秒>=2)
{
out.append(e.second/2,e.first);
e、 秒=e.second%2;
}
if(e.second&&middle.empty())
中间=e.第一;
}
串尾;
反向(tail.begin(),tail.end());
向外=向外+中间+尾部;
cout你只有一个简单的错误。当你想选择中间字符时,当你第一次看到一个频率为和奇数的字符时,你应该选择它,并且不要再更新它,因为这将是一个字典顺序最低的字符。这就是为什么我添加了布尔变量mid\u char\u selected
,一旦它设置为true,它就被设置为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;
}
#包括
使用名称空间std;
字符串最长回文组(字符串str){
映射频率字符;
对于(inti=0;i我在代码排序中添加了一个小的变化,只要我们得到左边的部分,就按字典顺序进行排序。
当我用java编写上述代码时,我得到的是“asdadsa”而不是“adsasda”
以下是Java中的代码:
import java.util.*;
public class Solution {
public static String longPalindrome(String a) {
Map<Character, Integer> map = new HashMap<>();
for(int i=0; i<a.length(); i++) {
map.put(a.charAt(i), map.getOrDefault(a.charAt(i), 0) + 1);
}
char mid = 0;
boolean mid_chosen = false;
StringBuilder left = new StringBuilder();
for(Map.Entry<Character, Integer> entry : map.entrySet()) {
if(!mid_chosen && entry.getValue() % 2 != 0) { //odd
mid_chosen = true;
mid = entry.getKey();
}
//Adding elements to left
for(int k=0; k<entry.getValue()/2; k++) {
left.append(entry.getKey());
}
}
//New Step added to sort it lexicographically
char[] leftChArr = left.toString().toCharArray();
Arrays.sort(leftChArr);
StringBuilder leftC = new StringBuilder(new String(leftChArr));
StringBuilder right = new StringBuilder();
//adding reverse elements to left
for(int j=leftC.length()-1; j>=0; j--) {
right.append(leftC.charAt(j));
}
if(mid_chosen == true) {
leftC.append(mid).append(right);
} else {
leftC.append(right);
}
return leftC.toString();
}
public static void main(String[] args) {
String str = "adskassda";
System.out.println(longPalindrome(str));
}
}
import java.util.*;
公共类解决方案{
公共静态字符串长回文(字符串a){
Map Map=newhashmap();
对于(int i=0;i)当您确定中间字符时,您可以/应该将std::min()
应用于先前的候选字符和新的候选字符。此外,您应该初始化中间字符
(例如,到'\0'
)识别是否已经有候选字符。如果找不到候选字符(即所有字符的频率都为偶数),这也会很有用。@Scheff查找带有中间字符的min可能不适用于当前代码方法。请参阅此以了解ref:It:.;-)只是对样式的评论,除非您正在开发libstdc++,否则不应在bits
子目录中包含
或任何其他内容。这些是库实现使用的内部文件,请使用标准定义的包含文件。请注意,我用127初始化了middle\u char
,以消除在min()
之前需要进行额外检查。您没有进行额外检查,因此您将始终以middle\u char
==0结束。在return
之前,还需要进行检查以插入(或不插入)middle_char
仅当它不再具有init.value时才返回。这是否返回最长的、以词法表示的最小回文?@0x499602D2:最长但以词法表示的最小回文是我的意图。正如我所说的,我只是对它进行了表面测试。不过,逻辑对我来说似乎是合理的。