在java中如何将字符映射到数字位置?

在java中如何将字符映射到数字位置?,java,Java,例如 输入:['A','Z','F','D',…] 输出:[0,25,5,3,…] 在C语言中,我只是从“A”中减去char,但在java中我似乎无法做到这一点。您也可以在java中用char做简单的数学运算: System.out.println('A' - 'A'); 将输出0。对字符串对象使用indexOf方法。比如说, “abcdefghijklmnopqrstuvxyz”。indexOf('F') 返回5。您所期望的输出只是大写字母相对于'a'的偏移量。因此,只需从需要偏

例如

  • 输入:['A','Z','F','D',…]
  • 输出:[0,25,5,3,…]

在C语言中,我只是从“A”中减去char,但在java中我似乎无法做到这一点。

您也可以在java中用char做简单的数学运算:

    System.out.println('A' - 'A');

将输出0。

对字符串对象使用
indexOf
方法。比如说,

“abcdefghijklmnopqrstuvxyz”。indexOf('F')


返回5。

您所期望的输出只是大写字母相对于
'a'
的偏移量。因此,只需从需要偏移量的字母的Unicode值中减去
'A'
的Unicode值即可

String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return alphabet.indexOf( myChar );

示例:
'B'-'A'=1

以下是以对数时间运行的不同实现:

课程

import java.util.Arrays;
import java.util.Collections;

public class CharacterIndex {
    private char[] characters = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
    public int index(char character) {
        assert characters != null;
        return Arrays.binarySearch(characters, Character.toUpperCase(character));                
    }
}
单元测试

import org.junit.Before;
import org.junit.Test;

import static junit.framework.Assert.assertEquals;

public class CharacterIndexTest {
    private CharacterIndex characterIndex;
    @Before
    public void createIndex() {
        characterIndex = new CharacterIndex();
    }
    @Test
    public void testIndexOfLetterA() {
        assertEquals(0, characterIndex.index('A'));
        assertEquals(0, characterIndex.index('a'));
    }
    @Test
    public void testNotALetter() {
        assertEquals(-1, characterIndex.index('1'));
    }

}

实际上,这里其他解决方案的弱点在于它们涉及到字符串创建

public enum Alphabet {
    A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
}
现在,您可以使用序数函数来获取此处的偏移量。e、 g.字母表L.序数()

然而,由于我假设您正在处理函数,这里有一个更有用的定义

public enum Alphabet {
    A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z;

    public static int getNum(String targ) {
        return valueOf(targ).ordinal();
    }

    public static int getNum(char targ) {
        return valueOf(String.valueOf(targ)).ordinal();
    }    
}
注意:与其他语言不同,您可以像类一样在自己的文件中声明枚举。实际上,如上所示的枚举也可以包含字段和方法,这些字段是静态创建的,很难打破。事实上,建议使用仅包含本地方法和变量的枚举以及名为INSTANCE的单一枚举类型来创建单例,因为它即使通过反射也无法破坏

如果不控制对函数的调用,您可能还需要考虑在其中插入toUppercase()调用


如果您希望更动态地创建字母表,而不是使用预定义的字母表,那么您应该查看地图

您可以使用
java.lang.Character.toUpperCase('a')-65

请注意,这些必须是字符,而不是字符串。单引号很重要。“这将返回域外字符的伪值。”。C语言也将如此。@Stefan-整个问题(由OP提出)是脆弱的。“字符的数字位置”的概念包含关于字符集的假设、关于什么是有效字符的假设等。请记住,他来自C背景…@Stefan,这是定义良好的。。。Java使用UTF-16字符,字母“A”…“Z”在ASCII兼容范围内。@Stefan:如果添加一个简单的
result=(result<0 | | result>25)-1:result
此方法返回的结果与您建议的解决方案完全相同。@Stefan,这是一个糟糕的解决方案,因为您在字母表中进行线性搜索。当然,这是一个固定的时间,因为你有一个固定大小的字母表,但它是不必要的慢。此外,-1代表对其他人的投票。这太令人讨厌了。然后使用字符到数值的映射。此解决方案需要26个字符的比较(平均13个),而不是调用hashcode,因此在速度方面最多只能节省少量。但是,如果不需要范围检查,“F”-“a”会更快。不要忘记考虑错误情况——如果indexOf返回-1,则意味着它得到的字符不在字符串中(在本例中,除了大写字母以外的内容)。Thilo--不明显。搜索域的大小限制为26个字符;计算机速度很快。我刚刚在我的桌面计算机上运行了一次快速检查;对于最坏的情况(查找“Z”),我的方法在5毫秒内完成,而你的方法在1毫秒内完成。(事实上,无论我们在搜索哪个字母,这些数字都是有效的;在这个小小的搜索域中,两种方法实际上都是常数时间。)如果这种情况发生了无数次,那么是的,你会想把它剃掉——否则我认为你在过早地进行优化。实际上,你也可以用“F”-“a”进行范围检查,看看结果是否在0到25之间。你可以用hashmap获得类似的结果,用(也许)更好的执行时间。您真的需要4毫秒吗?如果需要,您可能会从其他优化中受益,例如缓存。@Stefan:我将只对大写字母应用上面的内容。不适用于任何字符。“固有错误”有点强。它假定输入来自正确的范围,但这并没有错。实际上,即使输入无效,也不会发生任何不好的情况。您只会得到一个超出范围0..25的数字,这与indexOf()完全相同解决方案……但它允许其他人轻易破坏该方法。这样编写的函数不能保证它所期望的不变量。它是可破坏的、脆弱的,而且是穷人的解决方案。