被修改
我正在尝试使用hashmap在我的程序中实现以下函数。
获取
GETBIT
这是代码。
static HashMap<String, Object> hashmap = new HashMap<String, Object>();
public static String dictGet(String key){
String val = (String) hashmap.get(key);
return val;
}
public static int dictGet(String key, int pos){
String val = (String) hashmap.get(key);
byte[] bytes = val.getBytes();
byte byt = bytes[pos /8];
System.out.println("Byte : "+byt);
return (byt >> (pos % 8) ) & 1;
}
public static void dictSet(String key, String val){
hashmap.put(key, val);
}
public static void dictSet(String key, int pos, byte bitval){
String val = (String) hashmap.get(key);
byte[] bytes = val.getBytes();
byte byt = bytes[pos /8];
if(bitval == 1){
bytes[pos /8] = (byte) (bytes[pos /8]| (1 << (pos % 8)));
}
else if(bitval == 0){
bytes[pos /8] = (byte) (bytes[pos /8] & ~(1 << (pos % 8)));
}
hashmap.put(key, new String(bytes));
}
我希望为每个这些函数实现 O(1)复杂度。但目前getBit()
和setBit()
函数的时间复杂度为O(n)。
任何帮助表示赞赏。
答案 0 :(得分:2)
不,这不是O(1)的复杂性,它是O(n),其中n
是字符串的长度。原因是您从bytes
收到的getBytes()
必须始终是副本;否则,String
的不变性会受到损害。
这可以通过查看源代码来确认:getBytes
调用encode
,调用Arrays.copyOf
:
static byte[] encode(Charset cs, char[] ca, int off, int len) {
StringEncoder se = new StringEncoder(cs, cs.name());
char[] c = Arrays.copyOf(ca, ca.length); // <<=== Copying an array is O(n)
return se.encode(c, off, len);
}
要获得O(1)摊销的复杂性(假设您要访问字符串的大多数位),您需要额外的存储空间 - HashMap<String,byte[]>
这将是一个&#34;并行映射&#34;到原始哈希映射,存储&#34;缓存&#34; getBytes()
次来电的值。首先寻找缓存的表示;如果不存在,请转到实际值,调用getBytes()
,然后缓存结果。其余的代码将保持不变。
byte[] bytes = cache.get(key);
if (bytes == null) {
String val = (String) hashmap.get(key);
bytes = val.getBytes();
cache.put(key, bytes);
}
byte byt = bytes[pos /8];
System.out.println("Byte : "+byt);
return (byt >> (pos % 8) ) & 1;
请注意,cache
的维护工作在您身上:每次修改hashmap
时,您都需要从cache
删除相应的密钥。
答案 1 :(得分:2)
这是非常低效的。 var myUser=$scope.AuthObj.$getAuth();
将分配新数组(实际上不止一个),并在每次调用时将整个字符串编码到其中。这可能是此片段中最昂贵的操作。
此外,此代码混合了两个完全不同的表示。为了明确你的意图并避免错误,你应该坚持一个。如果要对字节进行操作,请在哈希映射中存储val.getBytes()
。如果您想对字符或代码点进行操作,请使用charAt或codePointAt。如果您需要在这些表示之间进行转换,请在初始化期间执行一次。
另请注意,getBytes使用平台的默认字符集对字符串进行编码。如果使用UTF-16,这很可能不是你想要的,你的代码也会破坏。
以下是使用byte[]
的示例,请注意,在Java StringBuilder
中有16位且此代码使用了整个范围:
char
答案 2 :(得分:0)
我知道这与您的答案无关,但如果您使用的是Java,则应使用泛型类型,以便不需要强制转换。
回答你的问题,String.getBytes()的复杂性取决于String的长度。以这种方式思考,getBytes()方法将String中的每个字符转换为一个字节。因此,复杂度为O(L),其中L是字符串的长度。