在Java中如何组合Unicode字符?

4
我正在开发一个随机名称生成器,用于我正在开发的游戏中。问题是不同的物种有不同的命名风格,我希望一个单一的名称生成器可以适用于所有物种。我已经解决了这个问题的第一部分——名称生成器使用一系列模板,每个玩家/NPC物种对应一个模板集。
我的主要问题是有些元音需要随机选取重音符号。我已经搜索了很多,但我找不到一种方法来随机选择一个字符然后再将重音符号应用于它。那么,有哪些方法可以通过选择字母然后再应用重音符号来组成带重音符号的字母呢?

如果您知道应该用重音标记哪些元音字母,请编写一个方法来检查该元音字母的重音。例如,如果您有一个要应用重音的 a 字符,则可以使用 vowelsWithAccent.getAccent('a') 方法将其更改为 á。该方法可以使用 Map<Character,Character> 来提供带有重音的元音字母。 - Luiggi Mendoza
请参见http://stackoverflow.com/a/29111105/32453。 - rogerdpack
3个回答

4
Unicode有“组合”字符,代表了大多数的重音类型。从一个由组合字符组成的数组中随机选择一个组合字符是非常容易的。然后,你可以将任何你喜欢的字符上加上任何重音。

http://en.wikipedia.org/wiki/Combining_character

由于它们是由代码点表示的,因此您可以将它们视为自己的字符:
String s = "a" + "\u0300"; // latin lowercase letter a + combining grave accent
char combining_grave_accent = '\u0300';

很遗憾,似乎Java没有一个API可以允许使用String s = LATIN_LETTER_A | ACCENT_GRAVE或类似的语法。 - Lady Serena Kitty
这可以在Java中完成,只需要知道组合字符的字符编码。这很棒,因为我可以在名称生成的最后一步添加重音标记,然后规范化字符串。 - Lady Serena Kitty

1
也许可以使用2D数组并创建一个转换表,其中将有2列和多行(有多少重音字符),现在在第一列中存储每个重音值,在第二列中存储非重音值即a、e、i、o、u,并且当生成名称的元音时,您可以随机选择是否使用重音。如果您选择使用重音,则会遍历2D数组,获取所有使用“ a”或其他字符的带重音值,并通过在数组的第二列中获取和检查值(以便选择所有带重音的a)然后随机选择一个来使用...
这是一个比较冗长的方法,我不知道在Java中有什么捷径。
编辑:这里是一些代码与我的建议相匹配:
import java.util.ArrayList;

/**
 *
 * @author David
 */
public class JavaApplication145 {

    static char[][] chars = new char[6][6];

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        createConversionTable();

        char c = 'u';

        ArrayList<String> charsList = getAccentedChar(c);

        for (int i = 0; i < charsList.size(); i++) {
            System.out.println(charsList.get(i));
        }

    }

    private static void createConversionTable() {
        chars[0] = new char[]{'ù', 'ü', 'é', 'ê', 'ä', 'à'};
        chars[1] = new char[]{'u', 'u', 'e', 'e', 'a', 'a'};
    }

    private static ArrayList getAccentedChar(char c) {

        ArrayList<String> charsList = new ArrayList<>();

        for (int i = 0; i < chars[0].length; i++) {

            for (int x = 0; x < chars[1].length; x++) {

                if (chars[i][x] == c) {
                    charsList.add(chars[i - 1][x] + "");
                }

            }
        }
        return charsList;
    }
}

1
不要使用2个数组,最好使用Map<Character,Character>(易于维护,访问速度更快)。尽管如此,您的观点也是很好的。 - Luiggi Mendoza
是的,那会更有效率,不是吗?+1... 希望原帖作者能理解并采纳这个建议。 - David Kroukamp
也许是,也许不是,我们不能确定。但是,你应该看一下Java集合,并通过实际代码练习学习另一种实现更易维护和性能更好的代码的方法。正如我对你说的那样,至少有这个想法是好的,但在现实世界中,你需要更多的东西才能生存:)。 - Luiggi Mendoza
Java集合包含一些非常棒和快速的实用工具。 - Lady Serena Kitty

-1

我也需要同样的东西,所以最终我自己做了这个:

        /**
 * Given a letter and an accent, return the char with the accent included.
 * 
 * @param accentCode: The accent char; i.e '~', '´';
 * @param letter: Letter to put accent in it.
 * @return: Char with {@code letter} with accent if it was a valid letter.
 */
public static int getAccent(char accentChar, int letter) {
    int index = 0;
    boolean upperCase = false;
    for (char vogal : vogalList) {
        if (letter == vogal) {
            if (index >= 5) {
                index -= 5;
                upperCase = true;
            }
            for (int accentType = 0; accentType < convertTable.length; accentType++) {
                if (convertTable[accentType][0] == accentChar) {
                    char converted = convertTable[accentType][index + 1];
                    if (converted != '-') {
                        if (upperCase)
                            converted = Character.toUpperCase(converted);

                        return converted;
                    }
                }
            }
        }
        index++;
    }
    return letter;
}

/**
 * Verify if {@code charID} is an accent character;
 * 
 * @param charID: Character code id to be verified.
 * @return: true in case {@code charID} is an accent character id.
 */
public static boolean isAccent(int charID) {
    for (int i = 0; i < convertTable.length; i++) {
        if (convertTable[i][0] == charID)
            return true;
    }
    return false;
}

private static final char[] vogalList = { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' };
private static final char[][] convertTable = { { '´', 'á', 'é', 'í', 'ó', 'ú' }, { '`', 'à', 'è', 'ì', 'ò', 'ù' }, { '^', 'â', 'ê', 'î', 'ô', 'û' }, { '~', 'ã', '-', '-', 'õ', '-' }, { '¨', 'ä', 'ë', 'ï', 'ö', 'ü' } };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接