2017-12-09 32 views
0

고유 한 문자열 집합을 고유 ID로 변환하는 스칼라 코드를 작업 중입니다. HashCode()를 적용했지만 음수를 얻었고 양수 만 사용해야합니다. 음수 값을 없애기 위해 math.abs를 사용해야한다는 것을 알고 있지만 이것이 올바른 해결책인지 확실하지 않습니다. 이 같은 뭔가가 내 문제 해결 전에 내가 읽은 경우 는hashCode()를 적용 할 때 긍정적 인 결과 만 얻는 방법?

math.abs(hashCode()) * constant % size 

는 어떻게 올바른 일정을 확인할 수 있습니까? 크기는 총 문자열 수를 의미합니까?

위의 질문은 math.abs 만 사용하여 질문을 해결했지만 총 문자열 수가 큰 경우 오버플로가 발생할 수 있고 음수를 얻을 기회가 있습니다. 결과에 상수를 곱하고 크기의 mod를 취하면 도움이 될 수 있습니다. 이것이 상수와 크기를 결정하는 방법을 이해해야하는 이유입니다.

고유 한 문자열에 대해 고유 번호를 얻는 또 다른 방법이 있습니까?

+1

[고유 ID에 해시 코드 사용] (https://stackoverflow.com/questions/21368492/using-hashcode-for-a-unique-id) – Piro

+0

내 질문에 대한 답변을 얻지 못했습니다. 언급 한 게시물. – saad

+0

Math.abs() 혼자서 사용하는 것에 결함이 있다는 이유는 무엇입니까? 항상 양수가 반환되는 것은 아니므로 해시 코드가 고유하지 않다고 설명하는 것이 어떻습니까? – Piro

답변

0

다른 방법으로 문제를 표현할 수 있습니다. 동일한 범위의 부호가있는 번호에서 부호없는 번호를 얻는 방법은 무엇입니까?

정수를 사용한다고 가정합니다. 당신은 0으로 위쪽으로 범위를 이동하는 일정을 ADD
:이 값은 이제 2147483647


1 단계로 양의 범위를 0으로이 값을 변환 할 필요가 -2147483648에서 2147483647까지 간다 값에 2147483648을 추가하여이를 수행 할 수 있습니다. 하지만 이제는 가능한 가장 높은 값이 MAX보다 훨씬 큽니다.

2 단계 :
따라서 MODULO를 사용하여 값을 필요한 범위로 다시 이동하십시오. 예를 들어


의 값을 고려 -2000 및 2000000000.

| STEP    | MIN VALUE | EXAMPLE 1 | EXAMPLE 2 | MAX VALUE | 
|-------------------|------------|------------|------------|------------| 
| original   |-2147483648 | -2000 | 2000000000 | 2147483647 | 
| add 2147483648 |  0  | 2147481648 | 4147483648 | 4294967295 | 
| modulo 2147483648 |  0  | 2147481648 | 2000000001 | 2147483647 | 

그래서 최종 수식은 다음

(NUMBER + 2147483648) % 2147481648 

경고 :
해시 코드는 고유 한 값을 제공하도록 설계되지 않았습니다. 두 개의 다른 문자열에 대해 동일한 해시를 가져올 가능성이 있습니다. 또한 해시에 대한 모든 스케일링 연산 (나눗셈, 모듈로)은 고유성을 더욱 감소시킬 수 있습니다.

0

Int에서 기호를 제거하려면 .abs 만 사용할 수 있습니다.그것은 Int.MinValue에 휴식 않지만, 당신은 단지 특별한 경우 수 그것을 :

def stripSign(n: Int) = math.abs(n) max 0 

또는 단순히 부호 비트 드롭 :

def stripSign2(n: Int) = n & Int.MaxValue 

또는 단지는 음수를 사용합니다 (어떤 어쨌든 그들과 함께 잘못?). 당신이 경우 다른 질문에

, 당신은, int 치의 고유 문자열의 무리를 변환하고, 별개의 Int의 이상 문자열이 있다는 단순한 이유에 대한 중복 (없을 것이라는 점을 보장, 그렇게 할 수 없습니다 각각에 고유 한 int를 할당하려고했습니다. 문자열을 다 쓰기 전에 int가 부족한 경우), 가끔씩은 충돌을 처리 할 수 ​​있어야합니다.

해시를 길게 만들어서 충돌 확률을 낮추는 경우에만 촬영할 수 있습니다 (32 비트 해시 코드로 약 75000 개의 문자열 인구에서 충돌 가능성이 약 50 %이고 31 비트 (음수가 필요하지 않은 경우)는 55000이지만 해시 함수가 충분하고 64 비트 해시 인 경우 "마법 수"는 약 5 billion입니다. 매우 균등하게 분배 됨).