2012-08-17 4 views
0

어제 시작한 프로젝트 '나의 지옥'중 하나는 Befunge 인터프리터였습니다. 나는 가장자리의 경우를 제외하고는 대부분을 위해 일하고있다.들쭉날쭉 한 char [] []을 char [,]로 변환 하시겠습니까?

나는 게으른있어이와 비 펀지 프로그램에서 읽을하기로 결정

char[][] program = File.ReadAllLines(args[0]).Select(x => x.ToCharArray()).ToArray(); 

내가 나중에 자신을 위해 더 많은 일을 만드는 것을 알고 있었다, 그러나 나는 다른 부분에 도착하고 싶어하고 그것을 떠났다. 이제는 늦었고 program은 직사각형이 아니란 사실을 고쳐야합니다.

v v < 
    @ 
>  ^

제 1 회 및 제 3 선은 길이 9 자하지만, 2 라인은 내가 IndexOutOfBoundsException 이전을 얻을 것이다, 단지 내 비 펀지 인터프리터가 설정 한 방식으로 5입니다 :의 난이 비 펀지 프로그램을 가지고 있다고 가정 해 봅시다 프로그램이 끝나면 방향 변경으로 ^을 해석 한 후 program[1][8]에 액세스하려고 시도하고 program[1]은 길이가 5 개인 것이기 때문에 프로그램이 종료됩니다. 예외를 잡아서 주위를 춤추는 대신 을 사용하여 program을 사용하고 여분의 문자를 공백으로 채우는 방법은 무엇입니까?

나는 가장 긴 라인의 길이, 라인의 수를 결정할 수 있고, 그것들을 가지고 char [,]를 만들고 그것을 복사 할 수 있다는 것을 알고있다. 그러나 나는 조금 더 단순하고 더 우아한 것을 바라고있다. 나는 새로운 접근법이 더 좋다면 위의 라인을 버리는 것에 완전히 동의한다.

+1

난 당신이 거기 당신의 질문에 대답 생각 : 원시 형의 배열은 (당신이 어셈블러 또는 C와 경험을 가지고있는 경우) 작업의 종류에 유용 할 수있는 바이트의 플랫 버퍼로 취급 할 수있다 : "가장 긴 줄의 길이, 줄 수를 결정하고, 그걸로 char [,]를 만들고" – Almo

+0

아, Befunge 인터프리터 만들기를위한 소품 "을 복사하십시오. 그것은 멋진 esolang입니다. 나는 몇 년 전에 Carnage Heart에서와 같이 로봇을 프로그래밍 한 것과 같은 충격파 게임을 만들었습니다. – Almo

+0

하나의 솔루션 만 있으면 최상의 솔루션이되지 못합니다. C#에 대해 더 많은 것을 배울 수 있습니다. –

답변

2

지그재그 배열 전체를 다시 만드는 것이 아니라 (다소 크기가 클 수 있다고 가정하면) 래퍼를 만들 수 있습니다. 해당 랩퍼는 오류를 검사하는 것이 아니라 범위를 벗어나는 경우 한계를 검사하고 일부 기본값을 리턴 할 수 있습니다.

public class Matrix<T> 
{ 
    public T[][] UnderlyingCollection {get;set;} //should probably be readonly and set in the constructor 

    public T DefaultValue {get;set;} 

    public T this[int i, int j] 
    { 
    get 
    { 
     if(UnderlyingCollection.Length > i && UnderlyingCollection[i].Length > j) 
     return UnderlyingCollection[i][j]; 
     else 
     return DefaultValue; 
    } 
    set 
    { /*TODO implement*/ } 

    } 
} 
+0

이것은 통역사를위한 것이므로, 속도는 엄청난 요구 사항입니다. 구현시 요청이있을 때마다 i와 j의 유효성을 검사해야합니다. +1 tho, 그것은 여전히 ​​작동합니다. –

+0

@CoreyOgburn 글쎄, 단락으로 인해'i'가 유효하지 않으면'i'와'j'를 검증 할 필요는 없지만 일반적으로 yes로 확인합니다. 실제로, 그 두 가지를 검증하는 것은 매우 빠른 검사입니다. 실제로 수표와 상당한 시간 차이를 보려면 수조조의 페치를 수행해야합니다. – Servy

+0

솔루션에서 두 값이 모두 맞으면 일정 시간이 걸리고 그렇지 않은 경우 시간이 오래 걸립니다. 나는 오히려 변수가 정확하고 여분의 시간이 사용된다면 (프로그램을 종료 할 가능성이 높다) 시간이 저장되는 상황을 원합니다. 직사각형 배열을 만들기 위해 약간의 시간을 설정함으로써, 적절한 경우가 수표로 인해 느려지지 않고 방금 완료되었습니다. 내가 말하고있는 것은 매우 작고, 때로는 완전히 헤아릴 수 없다는 것을 안다. 그러나 나는 더 나은 버릇이 있다고 생각한다. –

0

사람이 당신을 위해 무엇을 찾고있는 경우, 잘 모르겠지만,이 체크 아웃 :

public static class CharArrayExtension 
{ 
    public static char[,] FormatMatrix(this char[][] matrix) 
    { 
     int TotalColumns = matrix.Length; 
     int TotalLines = 0; 

     //Get the longest line of the current matrix 
     for (int column = 0; column < TotalColumns; column++) 
     { 
      int line = matrix[column].Length; 

      if (line > TotalLines) 
       TotalLines = line; 
     } 

     //Instantiate the resulting matrix 
     char[,] Return = new char[TotalColumns, TotalLines]; 

     Return.Initialize(); 

     //Retrieve values from the current matrix 
     for (int CurrentColumn = 0; CurrentColumn < TotalColumns; CurrentColumn++) 
     { 
      int MaxLines = matrix[CurrentColumn].Length; 

      for (int CurrentLine = 0; CurrentLine < MaxLines; CurrentLine++) 
      { 
       Return[CurrentColumn, CurrentLine] = matrix[CurrentColumn][CurrentLine]; 
      } 
     } 

     return Return; 
    } 
} 

사용법 :

 char[] Length5 = new char[]{ 'a', 'b', 'c', 'd', 'e'}; 
     char[] Length10 = new char[10]; 

     char[][] Matrix = new char[2][]; 
     Matrix[0] = Length5; 
     Matrix[1] = Length10; 

     char[,] FormattedMatrix = Matrix.FormatMatrix(); 

모든 의견을 이해할 수있을 것이다 .


UPDATE는

니콜라스는 성능 문제를 지적했다. 나는 관심이 있어요, 그래서 나는 다음과 같은 마이크로 약한 벤치마킹을했다 : 나는 여러 번 실행 한

 char[] Length5 = new char[]{ 'a', 'b', 'c', 'd', 'e'}; 
     char[] Length10 = new char[10]; 

     char[][] Matrix = new char[2][]; 
     Matrix[0] = Length5; 
     Matrix[1] = Length10; 

     Stopwatch stopWatch = new Stopwatch(); 

     stopWatch.Start(); 

     for (int i = 0; i < 5000; i++) 
     { 
      char[,] FormattedMatrix = Matrix.FormatMatrix(); 
     } 

     stopWatch.Stop(); 

     Console.WriteLine(string.Format("Andre Calil: {0} ms", stopWatch.ElapsedMilliseconds)); 

     stopWatch.Reset(); 

     stopWatch.Start(); 

     for (int i = 0; i < 5000; i++) 
     { 
      char[,] FormattedMatrix = RectArrayFromJagged<char>(Matrix); 
     } 

     stopWatch.Stop(); 

     Console.WriteLine(string.Format("Nicholas Carey: {0} ms", stopWatch.ElapsedMilliseconds)); 

     Console.ReadLine(); 

, 평균 결과였다

Andre Calil: 3 ms 
Nicholas Carey: 5 ms 

나는을 알고 이것은 적절한 벤치마킹이 아니지만 결국 내 솔루션과 같은 루크는 성능면에서별로 나쁘지 않습니다.

+0

당신의 대답은 제가 제 질문의 마지막 부분에서하고 싶지 않았다고 말한 것과 정확하게 같습니다. –

+0

@CoreyOgburn 당신은 * 당신이 * 더 우아하고 단순한 것을 선호한다고 * 당신이 원하지 않는다고 말하지 않았습니다. 의미가 완전히 다른 나는 downvote가 부적절하다고 생각합니다. 문제가 생겼을 때, 해결책을 제안했습니다. –

2

@ AndreCalil의 이전 답변을 바탕으로 작성하면 특히 프리미티브 유형의 대형 배열의 경우 더 효과적 일 수 있습니다.

static void Main(string[] args) 
{ 
    string[][] jagged = new string[][] { new string[] { "alpha" ,            } , 
              new string[] { "bravo" , "charlie" ,         } , 
              new string[] { "delta" , "echo" , "foxtrot" ,      } , 
              new string[] { "golf" , "hotel" , "india" , "juliet" ,   } , 
              new string[] { "kilo" , "lima" , "mike" , "nancy" , "oscar" , } , 
             } ; 
    string[,] rectangular = RectArrayFromJagged<string>(jagged) ; 

    return; 
} 

public static T[,] RectArrayFromJagged<T>(T[][] a) 
{ 
    int rows = a.Length; 
    int cols = a.Max(x => x.Length); 
    T[,] value = new T[ rows , cols ] ; 

    value.Initialize() ; 

    if (typeof(T).IsPrimitive) 
    { 
     int elementSizeInOctets = Buffer.ByteLength(value)/value.Length ; 
     for (int i = 0 ; i < rows ; ++i) 
     { 
      int rowOffsetInOctets = i * cols * elementSizeInOctets ; 
      int rowLengthInOctets = a[i].Length * elementSizeInOctets ; 
      Buffer.BlockCopy(a[i] , 0 , value , rowOffsetInOctets , rowLengthInOctets) ; 
     } 
    } 
    else 
    { 
     for (int i = 0 ; i < rows ; ++i) 
     { 
      int rowLength = a[i].Length ; 
      for (int j = 0 ; j < rowLength ; ++j) 
      { 
       value[i,j] = a[i][j] ; 
      } 
     } 
    } 
    return value ; 
} 
+0

+1 통찰력. 적어도 아이디어에 대한 당신의 투표가 좋을 것 = =) –

+0

죄송합니다! 됐어. –

+0

아니요. 고마워 친구. 우리 솔루션으로 마이크로 벤치마킹을 할 것입니다. –

관련 문제