java - Java:使用自定义符号在基数之间进行转换
问题描述
我想知道您是否可以使用自己的符号创建自定义基础,而不是使用Integer.parseInt
(0-9
和A-P
.)应用于您的 Java
我在想这样的事情:
public class Base {
private String symbols;
public Base(String symbols) {
this.symbols = symbols;
}
// for example: new Base("0123456789"); would represent base 10
public static String convertBases(Base from, Base to, String toConvert) {
// Takes toConvert which is encoded in base "from" and converts it to base "to"
}
}
我不确定如何实现这一点。有没有人有这个的代码?
解决方案
为此,您需要首先解析基础中的输入文本from
,然后格式化基础中的值to
,就像使用标准基础“字母表”时需要做的那样。
public static String convertBases(int fromRadix, int toRadix, String text) {
int value = Integer.parseInt(text, fromRadix);
return Integer.toString(value, toRadix);
}
所以,首先你实现parse
and toString
,然后实现convertTo
很容易:
public class Base {
private final String symbols;
private final BigInteger radix;
private final Map<Character, Integer> symbolIndex;
public Base(String symbols) {
if (symbols.length() <= 1)
throw new IllegalArgumentException("Must provide at least 2 symbols: length=" + symbols.length());
this.symbols = symbols;
this.radix = BigInteger.valueOf(symbols.length());
this.symbolIndex = new HashMap<>(symbols.length() * 4 / 3 + 1);
for (int i = 0; i < symbols.length(); i++) {
Integer prevIndex = this.symbolIndex.putIfAbsent(symbols.charAt(i), i);
if (prevIndex != null)
throw new IllegalArgumentException("Duplicate symbol at index " + prevIndex +
" and " + i + ": " + symbols.charAt(i));
}
}
public BigInteger parse(String text) {
BigInteger value = BigInteger.ZERO;
for (int i = 0; i < text.length(); i++) {
Integer index = this.symbolIndex.get(text.charAt(i));
if (index == null)
throw new IllegalArgumentException("Not a valid number: " + text);
value = value.multiply(this.radix).add(BigInteger.valueOf(index));
}
return value;
}
public String toString(BigInteger value) {
if (value.signum() < 0)
throw new IllegalArgumentException("Negative value not allowed: " + value);
if (value.signum() == 0)
return this.symbols.substring(0, 1);
StringBuilder buf = new StringBuilder();
for (BigInteger v = value; v.signum() != 0; v = v.divide(this.radix))
buf.append(this.symbols.charAt(v.mod(this.radix).intValue()));
return buf.reverse().toString();
}
public String convertTo(Base newBase, String text) {
return newBase.toString(parse(text));
}
}
测试
Base base3 = new Base("012");
Base base6alpha = new Base("ABCDEF");
System.out.println(base3.convertTo(base6alpha, "0")); // 0 -> A
System.out.println(base3.convertTo(base6alpha, "2")); // 2 -> C
System.out.println(base3.convertTo(base6alpha, "10")); // 3 -> D
System.out.println(base3.convertTo(base6alpha, "200")); // 18 -> DA
输出
A
C
D
DA
测试 2
Base obscure = new Base("^JsdloYF9%");
Base base64 = new Base("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
BigInteger value = new BigInteger("123456789012345678901234567890"); // Too large for int and long
String obscureValue = obscure.toString(value);
String base64Value = base64.toString(value);
System.out.println(obscureValue);
System.out.println(base64Value);
System.out.println(base64.convertTo(obscure, base64Value));
System.out.println(obscure.convertTo(base64, obscureValue));
输出
JsdloYF9%^JsdloYF9%^JsdloYF9%^
BjukP9sNz4O5OPwrS
JsdloYF9%^JsdloYF9%^JsdloYF9%^
BjukP9sNz4O5OPwrS
推荐阅读
- mongodb - 在 Azure DevOps Pipeline CI 中使用 MongoDB
- java - 将列表中的随机值插入 Spark 的数据框列
- javascript - localhost:3000 和 Internet 上的生产服务器 (localhost:5000) 上的代码相同但行为不同
- react-native - MapViewDirections 错误:GMAPS 路由请求错误:TypeError:网络请求失败
- cobol - COBOL 中的快乐数字
- python - 张量导入错误,keras 错误代码 -1073741795
- c# - 5 分钟后 .NET Core 3.1 API 上的 AntiForgery
- javascript - 如何在 window.open 中使用 noreferrer 功能并获得对子窗口的非空引用?
- swift - 上一个查询出错:[确保在此操作之前使用 /playback/source 设置源。(SOURCE_NOT_SET)]
- bash - 用变量定义 osascript 路径