문제

이것은 원래는 문제로 실행에서 작동,하지만 지금은 뭔가가 나는 단지 해결하려는 내 자신의 호기심.

고 싶은 찾을 경우 int'a'담 int'b'가장 효율적인 방법으로 가능합니다.몇 가지 코드를 썼지만,그것은 보인다 상관없이 내가 쓰,분석으로 그것이 문자열을 사용하여 다음 indexOf 은 그 일을 자극으로 이용합니다.

메모리는 문제가 되지 않습(이유 이내),정당한 투명한 처리 속도입니다.

이 코드 작성을 할 수학적으로:

private static int[] exponents = {10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };

private static boolean findMatch(int a, int b) {
    if (b > a) return false;

    if (a == b) return true;

    int needleLength = getLength(b);

    int exponent = exponents[needleLength];
    int subNum;
    while (a >= 1) {
        subNum = a % exponent;

        if (subNum == b)
            return true;

        a /= 10;
    }
    return false;
}

private static int getLength(int b) {

    int len = 0;

    while (b >= 1) {
        len++;
        b /= 10;
    }

    return len;
}

문자열은 다음과 같습니다 방법을 사용하고,보이는 트럼프의 수학적 방법을 사용:

private static boolean findStringMatch(int a, int b) {      
    return String.valueOf(a).indexOf(String.valueOf(b)) != -1;      
}

그렇지만 이것은 정말 나를 위해 필요한 완전한 나의 작업데이면 누구나 생각할 수 있는 어떤 방법을 최적화하는 내 방법으로 그 일의 수학적으로 또는 완전히 새로운 접근 방식 모두 있습니다.다시 메모리를 문제 없습니다,나는 단지 촬영을 위해 속도입니다.

나는 정말로 관심이있을 보거나 듣고도 누군가를 제공하고 있습니다.

편집: 내가 말할 때 담고 내 말은 어디 에나있을 수 있습니다,그래서 예를 들어,findMatch(1234,23)==true

편집: 모두를 위해 말하는 이 쓰레기를 읽을 수 없고 불필요:당신이 놓치고 점이다.이점을 얻을 수 있었을에 밖으로 괴짜 재미있는,문제 오지 않으로 응답에 사용되는 생산 코드입니다.

도움이 되었습니까?

해결책

이것은 Kibbee의 라인을 따라 이루어 지지만, 그가 게시하고 해결하기 전에 이것에 약간 흥미를 느꼈습니다.

long mask ( long n ) { 
    long m   = n % 10;
    long n_d = n;
    long div = 10;
    int  shl = 0;
    while ( n_d >= 10 ) { 
        n_d /= 10;
        long t = n_d % 10;
        m |= ( t << ( shl += 4 ));
    }
    return m;
}

boolean findMatch( int a, int b ) { 
    if ( b < a  ) return false;
    if ( a == b ) return true;

    long m_a = mask( a );    // set up mask O(n)
    long m_b = mask( b );    // set up mask O(m)

    while ( m_a < m_b ) {
        if (( m_a & m_b ) == m_a ) return true;
        m_a <<= 4;  // shift - fast!
        if ( m_a == m_b ) return true;
    }  // O(p)
    return false;
}       

void testContains( int a, int b ) { 
    print( "findMatch( " + a + ", " + b + " )=" + findMatch( a, b ));
}

testContains( 12, 120 );
testContains( 12, 125 );
testContains( 123, 551241238 );
testContains( 131, 1214124 );
testContains( 131, 1314124 );

300자가 논쟁하기에는 너무 적지 않기 때문에이 메인 포스트를 편집하여 pyrolistical에 응답합니다.

OP와는 달리, 나는 기본 컴파일 된 인덱스가 프리미티브가있는 Java 코드보다 빠르다는 사실에 놀라지 않았습니다. 그래서 저의 목표는 Java 코드 전체에서 Zillions Of Times라는 기본 방법보다 더 빠르다고 생각한 것을 찾는 것이 아닙니다.

OP는 이것이 생산 문제가 아니며 유휴 호기심의 선을 따라 더 많은 것을 분명히 했으므로 내 대답은 그 호기심을 해결합니다. 제 생각에는 속도가 생산에서 해결하려고 할 때 속도가 문제 였지만 유휴 호기심으로 "이 방법은 더 이상 수백만 및 수백만 번"이라고 불립니다. 그가 하나의 포스터에 대해 설명해야했기 때문에 더 이상 생산 코드로 추구되지 않으므로 복잡성은 더 이상 중요하지 않습니다.

또한 페이지에서 "551241238"에서 "123"을 찾을 수있는 유일한 구현을 제공하므로 정확성이 외부 관심사가 아니라면이를 제공합니다. 또한 "Java Primitives를 사용하여 수학적으로 문제를 해결하지만 최적화 된 기본 코드"의 솔루션 공간은 다음과 같습니다. 비어 있는.

또한, 사과를 사과와 비교했는지 여부는 확실하지 않습니다. 기능 사양은 f (int, int)-> boolean, f (string, string)-> boolean입니다 (이것은 일종의 도메인입니다. indexOf). 그래서 당신이 이와 같은 것을 테스트하지 않았다면 (여전히 내 것을 이길 수 있고, 나는 놀랍게도 놀랍지 않을 것입니다.) 추가 오버 헤드 ~할 것 같다 그 초과 중 일부를 40%먹습니다.

boolean findMatch( int a, int b ) { 
    String s_a = "" + a;
    String s_b = "" + b;
    return s_a.indexOf( s_b ) > -1;
}

동일한 기본 단계를 수행합니다. 통나무10(a) 인코딩 + 로그10(b) 인코딩 + 실제로 매치를 찾는 것, 또한 O (N) 어디 N 가장 큰 로그입니다.

다른 팁

그것 ~해야 한다 문제는 수학적이 아니라 텍스트이기 때문에 문자열 방식을 더 빨리하십시오. 당신의 "포함 된"관계는 숫자에 대해 아무 말도하지 않으며, 그들의 것에 대해서만 말합니다. 소수 표현.

또한 작성하려는 기능은 읽을 수 없을 것입니다. 다른 개발자는 자신이하는 일을 결코 이해하지 못할 것입니다. (여기서 어떤 문제가 있었는지 참조) 문자열 버전은 완벽하게 명확합니다.

내가 생각할 수있는 유일한 최적화는 자신의 String으로 변환하고 변환 할 때 숫자 (오른쪽에서 왼쪽)를 비교하는 것입니다. 먼저 B의 모든 자릿수를 변환 한 다음 B의 첫 번째 숫자 (오른쪽에서)에서 일치하는 것을 찾을 때까지 오른쪽에서 A에서 변환하십시오. 모든 B 경기가 발생할 때까지 비교하거나 불일치에 부딪칩니다. 불일치에 부딪히면 B의 첫 번째 숫자와 일치하는 지점으로 역 추적하고 A를 시작하고 다시 시작하십시오.

indexof는 기본적으로 왼쪽을 제외하고 동일한 백 추적 알고리즘을 수행해야합니다. 실제 숫자에 따라 더 빠를 수 있습니다. 숫자가 무작위라면 모든 a를 변환 할 필요가없는 경우가 많아야하기 때문에 있어야한다고 생각합니다.

당신의 기능이 실제로 잘하고있는 것처럼 보이지만 작은 개선은 다음과 같습니다.

private static boolean findMatch(int a, int b) {
        if (b > a) return false;

        if (a == b) return true;

        int needleLength = getLength(b);

        int exponent = exponents[needleLength];
        int subNum;
        while (a > b) {
                subNum = a % exponent;

                if (subNum == b)
                        return true;

                a /= 10;
        }
        return false;
}

일단 A가 B보다 작기 때문에 계속 가치가 없기 때문에 계속 보이지 않습니까? 해결책을 찾으면 행운을 빕니다!

이것은 흥미로운 문제입니다. 많은 String.class의 함수는 실제로 기본적으로 Beating String을 어려운 제안으로 만듭니다. 그러나 여기에 몇 가지 도우미가 있습니다.

간단한 정수 작업은 속도가 다릅니다.

샘플 프로그램의 빠른 계산에 의해 다음과 같습니다.

% ~ T
* ~ 4T
/ ~ 7T

따라서 곱셈이나 모듈로에 찬성하여 가능한 한 작은 분열을 사용하고 싶습니다. 빼기, 첨가 및 비교 연산자는이 모든 것을 물 밖으로 날려 버린 원인이 표시되지 않습니다. 또한 "최종"을 가능한 한 많이 사용하면 JVM이 특정 최적화를 수행 할 수 있습니다. "GetLength"기능 속도를 높이십시오 :

private static int getLength(final int b) {        
   int len = 0;
   while (b > exponents[len]) {
       len++;
   }
   return len + 1
}

이는 기능이 약 7 배 향상됩니다. 지수의 최대 B> 최대 인 인덱스 아웃 토프 바운드 예외가 나타납니다. 그것을 해결하기 위해 다음을 가질 수 있습니다.

private static int getLength(final int b) {        
   int len = 0;
   final int maxLen = exponents.length;
   while (len < maxLen && b > exponents[len]) {
       len++;
   }
   return len + 1;
}

B가 너무 크면 약간 느리고 길이가 잘못되지만 예외는 없습니다.

불필요한 객체/원시 생성 및 방법 호출은 런타임에 추가됩니다.

"getlength"는 다른 곳에서 호출되지 않았기 때문에 최적화 관점에서 별도의 기능을 갖는 것이 좋을 수도 있지만 불필요한 방법 호출 및 객체 "Len"의 생성입니다. 우리는 그 코드를 사용하는 곳에 바로 넣을 수 있습니다.

private static boolean findMatch(int a, final int b) {
        if (b > a) return false;
        if (a == b) return true;
        int needleLength = 0;
        while (b > exponents[len]) {
            needleLength ++;
        }
        needleLength++;

        final int exponent = exponents[needleLength];
        int subNum;
        while (a >= 1 && a <= b) {
                subNum = a % exponent;
                if (subNum == b)
                        return true;
                a /= 10;
        }
        return false;
}

또한 "A <= B"도 포함하도록 하단 루프를 변경했습니다. 나는 그것을 테스트하지 않았으며, 당사자 페널티가 당신이 반복을 낭비하지 않는다는 사실을 능가하는지 확실하지 않습니다. 영리한 수학을 사용하여 부서를 제거 할 수있는 방법이 있다고 확신하지만 지금은 생각할 수 없습니다.

Umm,아마도 저는 완전히 오해 질문,하지만.....

// Check if A is inside B lol
bool Contains (int a, int b)
{
    return (a <= b);
}

지 않는 한 당신이 알고 싶은 경우에는 특정 숫자의 시퀀스에서 다른 일련의 숫자.

이 경우에는,그것을 변환하는 문자열이 될 것보다 더 빨리 하는 수학을 알아낼 것입니다.

이것은 결코 당신의 질문에 대답하지 않지만 어쨌든 그것은 조언입니다 :-)

메소드 이름 findMatch 그다지 설명이 아닙니다. 이 경우 정적 방법이 있습니다 ContainerBuilder.number(int), 이는 a ContainerBuilder, 방법이 있습니다 contains 그 위에. 이런 식으로 코드는 다음과 같습니다.

boolean b = number(12345).contains(234);

장기에 대한 조언을 주행합니다!

오 그래, 나도 말하려고 했어 "포함"의 의미를 정의하십시오.

이진에서 이것을 계산하는 방법이 있습니까? 분명히 다른 캐릭터의 이진 정수를 포함하는 정수의 이진 값은 Decical이 동일하다는 것을 의미하지는 않습니다. 그러나 사용할 수있는 이진 속임수가 있습니까? 12345에서 00011111100 0101과 같은 숫자를 변환 한 다음 23 (0010 0011)이 포함되어 있는지 알아 내기 위해 약간의 이동을 수행 할 수 있습니다. 문자 세트는 10 자에 불과하기 때문에 단일 바이트에서 2 자 값을 저장하여 계산 시간을 줄일 수 있습니다.

편집하다

이 아이디어를 조금 확장합니다. 2 개의 정수 A 및 B가 있고 A가 B를 포함하는지 알고 싶다면 먼저 두 가지를 확인합니다. a가 b보다 작 으면 a는 B를 포함 할 수 없습니다. a = b라면 a는 B를 포함합니다. A가 B와 동일한 수의 문자 숫자를 포함하면 A는 B를 포함하지 않지만 동일하지 않으면 B를 포함하지 않지만 동일하지 않으면 여기에 있지 않으므로 두 줄이 같은 길이 인 경우 A는 B를 포함하지 않습니다. . 이 시점에서 A의 길이는 B보다 길다. 따라서 이제이 게시물의 첫 부분에서 언급 한 것처럼 문자열을 포장 된 이진 값으로 변환 할 수 있습니다. 이 값을 정수 배열에 저장하십시오. 이제 배열에서 약간과 정수 값을 수행하고 결과가 A 인 경우 A는 B를 포함합니다. 이제 B의 정수 배열을 왼쪽 4 비트로 바꾸고 다시 Conparison을 수행합니다. B의 왼쪽에서 비트가 터질 때까지 이렇게하십시오.

* 이전 단락 에서이 단계 에서이 단계를 건너 뛸 수 있음을 의미합니다. 문자열을 전혀 사용하지 않고이 작업을 수행 할 수있는 방법이있을 수 있습니다. 첫 번째 단락에서 논의한 포장 된 이진 표현을 얻기 위해 할 수있는 멋진 이진 트릭이있을 수 있습니다. 사용할 수있는 이진 트릭이 있거나, 정수를 이전에 논의한 소수점 값으로 변환하는 빠른 수학이 있어야합니다.

코드 에서이 기능을 어디에 사용하고 있는지 물어봐도 될까요? 아마도 현재 해결하고있는 문제를 해결하는 또 다른 방법이있을 수 있습니다. 이것은 내 친구가 나에게 그의 기타를 완전히 다시 조정 해달라고 요청했을 때와 마찬가지로, 나는 전체 단계로 바닥 줄을 낮추고 동등한 결과를 얻을 수 있다는 것을 깨닫기 전에 그것을했다.

참고로

http://refactormycode.com/

당신을 위해 일할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top