Java 将单词排列成回文格式

Java 将单词排列成回文格式,java,arrays,palindrome,sequences,Java,Arrays,Palindrome,Sequences,您好,我一直在尝试从输入中形成回文: String[] text ={"ivcci", "oyotta", "cecarar","bbb","babbbb"}; getPalindrome(text); 我需要重新排列数组中的所有单词以产生这个输出 civic -1 rececar bbb bbabb 该方法希望接收字符串数组,如 public static String getPalindrome(String[] text){} “returning-1表示数组中的i.g“oyotta

您好,我一直在尝试从输入中形成回文:

String[] text ={"ivcci", "oyotta", "cecarar","bbb","babbbb"};
getPalindrome(text);
我需要重新排列数组中的所有单词以产生这个输出

civic
-1
rececar
bbb
bbabb
该方法希望接收字符串数组,如

public static String getPalindrome(String[] text){}
“returning-1表示数组中的i.g“oyotta”不能形成palíndrome

我一直在测试这段代码,它可以工作,但i.g“cecarar”并没有生成“racecar”,因为我在java中有点新,我使用了一个字符串和一个字符串数组,有人能帮助正确地编写这段代码吗

非常感谢

public static String getPalindrome(String s) {

    if (s == null)
        return null;
    Map<Character, Integer> letters = new HashMap<Character, Integer>();

    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        if (!letters.containsKey(c))
            letters.put(c, 1);
        else
            letters.put(c, letters.get(c) + 1);
    }

    char[] result = new char[s.length()];
    int i = 0, j = result.length - 1;
    Character middle = null;
    for (Entry<Character, Integer> e : letters.entrySet()) {
        int val = e.getValue();
        char c = e.getKey();

        if (val % 2 != 0) {
            if (middle == null && s.length() % 2 != 0) {
                middle = c;
                val--;
            } else
                return "-1";
        }
        for (int k = 0; k < val / 2; k++) {
            result[i++] = c;
            result[j--] = c;
        }
    }
    if (middle != null)
        result[result.length / 2] = middle;
    return new String(result);
}
public静态字符串getPalindrome(字符串s){
如果(s==null)
返回null;
映射字母=新HashMap();
对于(int i=0;i
为了使一组字符能够产生回文,其中只有一个字母可以重复奇数次,因此可以先将其剔除

在不为您编写实际代码的情况下,我将使用以下算法:

创建到计数器的字符映射。可以执行
int[]counts=new int[26];
检查输入字符串中的每个字符,并增加计数:
++counts[character.toLower(c)-'a'];
然后遍历每个字符,看看它的奇数
if(counts[i]&1!=0){if(oddIndex!=-1){return-1;}oddIndex=i;}
如果有两个或更多的奇数,它将返回-1。 然后,您可以创建一个StrigBu建器,并从中间的ODDeCKET开始,如果它存在的话。 然后检查计数,并将计数[i]/2添加到字符串生成器的前面和后面

这将从原始输入中得到一个对称字符串

现在,如果你真的需要单词,那么你必须有一个回文字典。你可以对所有回文进行预处理,得到一个“排序字符串”=>“回文”的映射

类回文检查器
{
最终映射回文=新HashMap();
公共回文检查器(Iterable All回文){
for(字符串回文:所有回文){
char[]chars=回文。getChars();
数组。排序(字符);
回文数.put(String.valueOf(chars),回文数);
}
}
公共字符串getPalindrome(字符串输入){
char[]chars=input.getChars();
数组。排序(字符);
返回回文.get(String.valueOf(chars));
}
}

正如其他用户所指出的,只有当最多有一个字符出现奇数次时,才能将字符串重新排列为回文

一旦确认字符串可以转换为回文,就可以按如下方式构造回文(当然这只是许多方法中的一种):

  • 将可以获得的所有字符对放置在字符串的两侧
  • 将遗漏的单个字符放在字符串中间,以防有此类字符
例如:

public class Palindromes {

    public static void main(String[] args) {
        String[] text = {"ivcci", "oyotta", "cecarar","bbb","babbbb"};
        for(String str : text){
            evaluatePalindrome(str);
        }
    }

    private static void evaluatePalindrome(String str){
        PalindromeCandidate pc = new PalindromeCandidate(str);
        if(pc.isPalindrome()){
            System.out.println(pc.getPalindrome());
        } else {
            System.out.println("-1");
        }
    }
}
公共类回文候选{
私有final CharacterCount CharacterCount;
公共回文候选(字符串originalString){
this.characterCount=新的characterCount(原始字符串);
}
公共布尔值isAlindrome(){
集合计数=characterCount.asMap().values();
int=0;
用于(整数计数:计数){
OddCountOccurrencess+=(计数%2);
}
返回(1){
追加(ch);
发生次数-=2次;
}
如果(出现次数>0){
中间附加(ch);
}
}
StringBuilder rightSide=新的StringBuilder(leftSide).reverse();
返回leftSide.append(中间).append(右边).toString();
}
}
/**
*地图周围的薄包装。用于计算发生次数
*人物的性格。
*/
公共类字符计数{
私人最终地图;
公共字符计数(字符串str){
this.map=新的HashMap();
for(字符ch:str.toCharArray()){
增量(ch);
}
}
专用无效增量(字符ch){
this.map.put(ch,getCount(ch)+1);
}
私有整数getCount(字符ch){
if(集装箱地图(ch)){
返回map.get(ch);
}否则{
返回0;
}
}
公共地图asMap(){
返回新的HashMap(map);
}
}

ivcci
cecarar
Babbb
都不是回文。我确信他是说
civic
racecar
。不管他的意思是什么,程序都不会知道这些意图…有了这些输入。你得到的输出是什么?我猜目的是找到那些可以转换为回文并这样做。
public class Palindromes {

    public static void main(String[] args) {
        String[] text = {"ivcci", "oyotta", "cecarar","bbb","babbbb"};
        for(String str : text){
            evaluatePalindrome(str);
        }
    }

    private static void evaluatePalindrome(String str){
        PalindromeCandidate pc = new PalindromeCandidate(str);
        if(pc.isPalindrome()){
            System.out.println(pc.getPalindrome());
        } else {
            System.out.println("-1");
        }
    }
}
public class PalindromeCandidate {

    private final CharacterCount characterCount;

    public PalindromeCandidate(String originalString) {
        this.characterCount = new CharacterCount(originalString);
    }

    public boolean isPalindrome(){
        Collection<Integer> counts = characterCount.asMap().values();
        int oddCountOccurrences = 0;
        for(Integer count : counts){
            oddCountOccurrences += (count%2);
        }
        return (oddCountOccurrences <= 1);
    }

    public String getPalindrome(){
        if(!isPalindrome()){
            throw new RuntimeException("Cannot be rearranged as a palindrome.");
        }
        Map<Character, Integer> counts = characterCount.asMap();
        StringBuilder leftSide = new StringBuilder();
        StringBuilder middle = new StringBuilder();
        for(Character ch : counts.keySet()){
            int occurrences = counts.get(ch);
            while(occurrences > 1){
                leftSide.append(ch);
                occurrences -= 2;
            }
            if(occurrences > 0){
                middle.append(ch);
            }
        }
        StringBuilder rightSide = new StringBuilder(leftSide).reverse();
        return leftSide.append(middle).append(rightSide).toString();
    }
}
/**
 * Thin wrapper around a Map<Character, Integer>. Used for counting occurences
 * of characters.
 */
public class CharacterCount {

    private final Map<Character, Integer> map;

    public CharacterCount(String str) {
        this.map = new HashMap<>();
        for(Character ch : str.toCharArray()){
            increment(ch);
        }
    }

    private void increment(Character ch){
        this.map.put(ch, getCount(ch) + 1);
    }

    private Integer getCount(Character ch){
        if(map.containsKey(ch)){
            return map.get(ch);
        } else {
            return 0;
        }
    }

    public Map<Character, Integer> asMap(){
        return new HashMap<>(map);
    }
}