2017-10-03 1 views
0
public static enum Action { 
    No, LToM, MToL, MToR, RToM 
} 

public static int hanoiProblem2(int num, String left, String mid, String right) { 
    Stack<Integer> lS = new Stack<Integer>(); 
    Stack<Integer> mS = new Stack<Integer>(); 
    Stack<Integer> rS = new Stack<Integer>(); 
    lS.push(Integer.MAX_VALUE); 
    mS.push(Integer.MAX_VALUE); 
    rS.push(Integer.MAX_VALUE); 
    for (int i = num; i > 0; i--) { 
     lS.push(i); 
    } 
    Action[] record = { Action.No }; 
    int step = 0; 
    while (rS.size() != num + 1) { 
     step += fStackTotStack(record, Action.MToL, Action.LToM, lS, mS, left, mid); 
     step += fStackTotStack(record, Action.LToM, Action.MToL, mS, lS, mid, left); 
     step += fStackTotStack(record, Action.RToM, Action.MToR, mS, rS, mid, right); 
     step += fStackTotStack(record, Action.MToR, Action.RToM, rS, mS, right, mid); 
    } 
    return step; 
} 

public static int fStackTotStack(Action[] record, Action preNoAct, 
           Action nowAct, Stack<Integer> fStack, Stack<Integer> tStack, 
           String from, String to) { 
    if (record[0] != preNoAct && fStack.peek() < tStack.peek()) { 
     tStack.push(fStack.pop()); 
     System.out.println("Move " + tStack.peek() + " from " + from + " to " + to); 
     record[0] = nowAct; 
     return 1; 
    } 
    return 0; 
} 

public static void main(String[] args) { 
    int num = 4; 

    // solution 2 
    int steps2 = hanoiProblem2(num, "left", "mid", "right"); 
    System.out.println("It will move " + steps2 + " steps."); 
    System.out.println("==================================="); 

} 

하노이 타워를 푸는 코드입니다. 3 개의 스택을 사용하여 3 개의 타워를 시뮬레이션합니다. 제 질문은 왜 그것은 레코드 변수를 배열로 정의합니까? 작업 [] record = {Action.No}; record [0] = nowAct;스택을 사용하여 하노이 타워 해결하기 (자바)

으로 변경하려고했습니다. 액션 레코드 = 액션입니다. 아니요. record = nowAct; 코드를 실행하지 못했습니다.

이유를 모르겠습니다. 누군가가 그 이유를 설명 할 수 있다면 정말 고맙습니다. 감사합니다. .

+1

은 : 한 번에 왼쪽에서 오른쪽으로 또는 오른쪽에서 왼쪽에서 디스크를 이동할 수 없습니다. 가운데에서 왼쪽으로 오른쪽에서 오른쪽으로 또는 왼쪽에서 오른쪽으로 두어야합니다. –

+0

'{Action.No}'는 하나의 요소를 포함하는 배열이고, Action []을 입력합니다. 그것은'Action.No'와 같지 않습니다.'Action'을 입력하십시오. –

+0

레코드 [0] 만 사용했다는 의미입니다. 배열에서 변수에 '레코드'를 변경할 수 있습니까? 고맙습니다. –

답변

0

예에서 record은 값이 fStackTotStack 메서드 내에서 변경되기 때문에 배열로 정의됩니다. 자바 참조 의해서도, 하여 변수를 전달하기 때문에

이에 대한 간단한 설명이다. Object 참조를 값으로 전달합니다.

포획, 예를 들어, 다음 코드를

public void foo(int bar) { 
    bar += 4; 
    System.out.println("Foo's bar: " + bar); 
} 

public static void main(String[] args) { 
    int bar = 5; 
    new Foo().foo(bar); 
    System.out.println("Main's bar: " + bar); 
} 

이 인쇄됩니다

Foo's bar: 9 
Main's bar: 5 

를 이것은 foo 기능 내부의 bar 변수가 내부가 아닌 다른 변수 때문에 main 기능. 메서드가 호출 될 때 값이 복사됩니다.

당신이 배열을 전달

는 변수 자체는 여전히 다른 : foo는 바이의 메인 바는 다른 때문에

public void foo(int[] bar) { 
    bar = new int[]{9}; 
    System.out.println("Foo's bar: " + bar[0]); 
} 

public static void main(String[] args) { 
    int[] bar = {5}; 
    new Foo().foo(bar); 
    System.out.println("Main's bar: " + bar[0]); 
} 

이, 이전과 동일한 결과를 얻을 것입니다.

그러나 개체 참조는 값으로 전달됩니다. 즉, 변수가 다르더라도 변수가 나타내는 값은 동일합니다. 따라서이 :

public void foo(int[] bar) { 
    bar[0] += 4; 
    System.out.println("Foo's bar: " + bar[0]); 
} 

public static void main(String[] args) { 
    int[] bar = {5}; 
    new Foo().foo(bar); 
    System.out.println("Main's bar: " + bar[0]); 
} 

이전보다 다른 무언가를 출력합니다

Foo's bar: 9 
Main's bar: 9 

foo는의 bar 변수의 주요 bar 변수가 다른 변수를하는 동안, 그들은 동일한 기본 객체를 가리 때문입니다. 따라서 변수뿐만 아니라 객체 자체에 대한 변경 사항은 유지됩니다.

위 예에서 Action[] record = { Action.No }; 행은 fStackTotStack 방법으로 전달되는 배열을 생성합니다. 변수 record은 자체적으로 변경되지 않으므로 (아무데도 record = new Action[] {}이 없음), 그것이 가리키는 배열은 여전히 ​​전달 된 배열과 동일합니다. 즉, 개체 자체 (이 경우 배열)를 변경할 수 있습니다.나는이 문제의 또 하나 개의 조건이 언급하는 것을 잊지

Here is an article that can explain it better than I can.