2011-08-29 2 views
0

안녕하세요. 먼저 내 자신을 소개합니다. 내 이름은 Mattia이고 나는 컴퓨터 과학의 학생입니다.C# 코드를 F # 코드로 변환하십시오.

for 및 while과 같은 명령형 루프를 사용하여 다른 프로그래밍 언어 (C# 및 Python)로 이미 구현 한 세 가지 기능에 문제가 있습니다.하지만 그 중 하나를 변환해야합니다. 재귀 적 스타일.

C에서 # 함수

은 :

  • resetList 두리스트 주어, 상기 방법은 제리스트의 개체의 내부에 카운터를 초기화하고, 상기 제리스트에서 새로운 객체를 넣어.

    public static List<myObject> resetList(List<myObject> inList, List<myObject> outList, bool flag) 
    { 
        foreach (myObject myObj in inList) 
        { 
         myObj.FirstCounter= 0; 
    
         if (flag) 
          myObj.SecondCounter= 0; 
         outList.Add(myObj); 
        } 
        return outList; 
    } 
    
  • randomIntList는 : 주어진 두 정의 개체 : 본 방법은과 n은 1과 56

    int i = 0; 
    while (i < n) 
    { 
        int randomNumber = randomizer.Next(1, 56 + 1); 
    
        if (!listOut.Contains(randomNumber)) 
        { 
         listOut[I] = randomNumber; 
         i++; 
        } 
    } 
    
  • compareRule 사이에 선택이 끝난 임의의 정수리스트를 반환 (n)를 생성하기 위해 정수의 숫자를 부여 , 메소드는 그 (것)들 사이에 첫번째 동등한 특성을 찾아 낸다.

    int index = myObject1.Index; 
    char myChar = myObject1.getChar(); 
    
    while ((index < 6) && !(myObject2.getChar().Equals(myChar))) 
    { 
        index++; 
        myChar= myObject1.getCharAt(index); 
    } 
    
    myObject1.Counter++; 
    

나는 예를 들어, 재귀 스타일에 필수적 루프 스타일로 변환 할 수는 없지만 :

  • resetList :

(Imperative version) 

let resetList inList flag = 
    let mutable outList = [] 

    for myObj in inList do 
     if flag = true then 
      outList <- outList @ [new myObject(myObj.Index, 0, myObj.Chars, 0)] 
     else 
      outList <- outList @ [new myObject(myObj.Index, 0, myObj.Chars, myObj.Counter)] 
outList 

(Recursive version: try...) 

let resetList listaIn flag = 
    let mutable outList = [] 

    let rec resetListRec inList = 
     match inList with 
     | [] -> outList 
     | head :: tail -> 
      if flag = true then 
       outList <- outList @ [new myObject(head.Index, 0, head.Chars, 0)] 
      else 
       outList <- outList @ [new myObject(head.Index, 0, head.Chars, head.Counter)] 
    resetListRec tail 
전혀 주셔서 감사합니다 , Mattia.

솔루션 :

  • resetList :

    let rec resetList list flag = 
        match list with 
        | [] -> [] 
        | (myObj : myObject) :: myObjs -> 
         let myObj = 
          if flag then 
           new myObject(myObj.Index, 0, myObj.Chars, 0) 
          else 
           new myObject(myObj.Index, 0, myObj.Chars, myObjs.Counter) 
    
        myObj :: (resetList myObjs flag) 
    
  • findCharEqual :

    let rec findCharEqual index (myObj1 : myObject) (myObj2 : myObject) = 
        let char1 = myObj1.GetChar() 
        let char2 = myObj1.GetChar(index) 
    
        if (index < 6) && (char1 <> char2) then 
         findCharEqual (index + 1) myObj1 myObj2 
        else 
         new myObject(myObj2.Index, index, myObj2.Chars, myObj2.Counter + 1) 
    
  • randomList :

    ,
    let randomList n = 
        let randomizer = new Random() 
        Seq.initInfinite (fun _ -> randomizer.Next(1, MAX_N + 1)) 
        |> Seq.distinct 
        |> Seq.take n 
        |> Seq.toList 
    

업데이트 : 지금 내가 재귀 형태로 변환하기 위해 노력하고있어이 (마지막) while 루프와 함께 일하고 있어요.

(... declaration of listIn, listOut, listTemp...) 

while (listOut.Length < n) do 
    let mutable myObj1 = new myObject(0, 0, Array.empty, 0) 
    let mutable myObj2 = new myObject(0, 0, Array.empty,0) 

    if (listIn.Length = 0) then 
     if (listOut.Length > 1) then 
      myObj1 <- listOut.[listOut.Length - 2] 

      myObj2 <- new myObject(listOut.[listOut.Length - 1].Index, listOut.[listOut.Length - 1].Char + 1, listOut.[listOut.Length - 1].Chars, listOut.[listOut.Length - 1].Counter) 

      listOut <- removeObject (listOut.Length - 1) listOut 

      if (myObj2.Counter < 2) then 
       listIn <- listIn @ resetObject listTemp false 
       listTemp <- List.empty<myObject> 

      else 
       myObj1 <- new myObject(listOut.Head.Index, listOut.Head.Char + 1, listOut.Head.Chars, listOut.Head.Counter) 

       listOut <- List.empty<myObject> 
       listOut <- listOut @ [myObj1] 

       listIn <- listIn @ resetObject listTemp true 

       listTemp <- List.empty<myObject> 

       myObj2 <- listIn.Head 
       listIn <- removeObject 0 listIn 
     else 
      myObj1 <- listOut.[listOut.Length - 1] 
      myObj2 <- listIn.Head 

      listIn <- removeObject 0 listIn 

     let mutable indFxDx = myObj2.Char 
     myObj2 <- fingEqualChar indFxDx myObj1 myObj2 

     if (myObj2.Char < 6) then 
      if (myObj1.leftChar = myObj2.rightChar) then 
       listOut <- listOut @ [myObj2] 

       if (listTemp.Length > 0) then 
        listIn <- listIn @ resetObject listTemp false 
        listTemp <- List.empty<myObject> 

     else 
      listTemp <- listTemp @ [myObj2] 

(... 작동하지 솔루션 ...)

(... declaration of listIn, listOut, listTemp...) 
let rec findSolution i = 
    if i < n then 
     (... function atre the while declaration, to the end...) 
    findSolution (i + 1) 

listOut <- findSolution 0 

문제는 내가 세 가지 목록을 수정해야하고 이것이 가능하지 재귀 스타일, sombody이 어떤 생각을 가지고있다 ?

마티아 아래

답변

0

당신이 할 수있는 일이다 : 당신이 F 번호를 학습하는 경우

let resetList inList outList flag = 
    outList @ inList |> List.map (fun i -> i.FirstCounter = 0; 
              match flag with 
              | true -> i.SecondCounter = 0; i 
              | _ -> i) 


let randomList n = 
    let rnd = new Random() 
    seq {while true do yield rnd.Next(1,56)} 
    |> Seq.distinct 
    |> Seq.take n 
    |> Seq.toList 


let findCharEqual obj1 obj2 = 
    let c = obj1.getChar() 
    let d = obj2.getChar() 
    if c = d then 
     c 
    else 
     findCharEqual obj1 obj2 

가 반복적으로 또는 반복적으로 생각하기 전에 고차 기능에 대해 생각

2

그것은 처음에 유용 자신에게 몇 가지 재귀 함수를 작성하십시오. 나중에 많은 것들이 기존 패턴과 일치하고 (Ankur의 솔루션에서와 마찬가지로) List.map과 같은 함수를 사용할 것임을 알게 될 것입니다.

그래서,이 같은 것을 할 것, 재귀 resetList 함수를 작성 :

let rec resetList inList flag = 
    match inList with 
    | [] -> [] // For empty list, we can only return emtpy list 
    | x::xs -> 
     // For non-empty list, create an object depending on the 'flag' 
     let obj = 
      if flag then new myObject(myObj.Index, 0, myObj.Chars, 0) 
      else new myObject(myObj.Index, 0, myObj.Chars, myObj.Counter) 
     // Process the rest of the list (recursively) and then add 
     // object we just created to the front 
     obj :: (resetList xs flag) 

이 구현되지 않습니다 꼬리 재귀, 그것은 반복적으로 restList를 호출 한 후 무언가를 의미합니다 (이것은 추가 값을 앞에 붙이십시오). 긴 목록을 처리하는 경우 문제가 될 수 있지만 현재 걱정할 필요가 없을 것입니다.

자세한 내용은 & 일부 소개는 working with functional lists, see this MSDN article입니다.

0

첫 번째 함수는 복사 한 목록을 반복하고 그 안에있는 객체에 몇 가지 부작용을 수행합니다. 또한 Seq.iter 또는 List.iter 또는 핸드 롤 List.iter에서 같은 재귀 루프를 사용할 수

let resetList inList flag = 
    for o in inList do 
    o.FirstCounter <- 0 
    if flag then 
     o.SecondCounter <- 0 
    inList 

: 관용적 번역 그래서 그들이 불변이기 때문에 아무 소용이 F 번호 목록을 복사하는 없습니다.

let rec loop index myChar = 
    if index < 6 && not (myObject2.getChar().Equals myChar) then 
    myObject1.getCharAt index |> loop (index + 1) 
myObject1.getChar() |> loop myObject1.Index 
myObject1.Counter <- myObject1.Counter + 1 
: 다음 while 루프

let rec loop i = 
    if i < n then 
    let randomNumber = randomizer.Next(1, 56 + 1) 
    if listOut.Contains randomNumber then 
     listOut.[i] <- randomNumber 
     loop (i + 1) 

동일 : 술어가 만족 될 때 루프 본체를 실행 재귀 재귀 함수에 상당하지만

관련 문제