최근 데이터 구조를 살펴보면 시퀀스 테이블의 Delete () 메서드가 생각과 다른 것을 발견하여 테스트를했는데 프로그래머의 과실로 오류가 발생한 것 같습니다.
인터넷에서 몇 가지 정보를 검색했는데 대부분이 같은 실수였습니다.
public interface IListDS <T>
{ int GetLength (); // 길이 찾기 void Clear (); // clear operation bool IsEmpty (); // 선형 테이블이 비어 있는지 확인 void Append (T item); // additional operation void Insert (T item, int i); // Insert operation T Delete (int i); // Delete operation T GetElem (int i); // Fetch table element int Locate (T value); // 값으로 찾기 )
public class SeqList <T> : IListDS <T>
{ private int maxsize; // 시퀀스 테이블의 용량 private T [] data; // 시퀀스 테이블에 데이터 요소를 저장하는 데 사용되는 배열 private int last; // 시퀀스 테이블을 나타내는 마지막 요소의 위치
// 索引 器
public T this [int index]
{ get { return data [index]; } set { data [index] = value; } }
// 마지막 요소 위치 위치 속성
public int Last
{ get { return last; } }
//
容量属性public int Maxsize
{ get { return maxsize; } set { maxsize = value; } }
//
构造器public SeqList (int size)
{ data = new T [size]; maxsize = 크기; 마지막 = -1; }
// 시퀀스 테이블의 길이 찾기
public int GetLength ()
{ return last + 1; }
// 시퀀스 테이블
지우기 public void Clear ()
{ last = -1; }
// 시퀀스 테이블이 비어 있는지 확인
public bool IsEmpty ()
{ if (last == -1) { return true; } return false; } // 시퀀스 테이블이 꽉 찼는 지 확인 public bool IsFull () { if (last = = maxsize-1) { true 반환; }
거짓 반환;
}
// 시퀀스 테이블 끝에 새 요소
추가 public void Append (T item)
{ if (IsFull ()) { Console.WriteLine ( "List is full"); return; } data [++ last] = item ; }
// 시퀀스 테이블에서 i 번째 데이터 요소의 위치에 데이터 요소를
삽입 합니다. public void Insert (T item, int i)
{ if (IsFull ()) { Console.WriteLine ( "List is full"); return ; } else if (i <1 || i> last + 2) { Console.WriteLine ( "Position is erro"); return; } else if (i == last + 2) { data [++ last] = item ; } else { for (int j = last; j> = i-1; j--) {
데이터 [j + 1] = 데이터 [j];
}
데이터 [i-1] = 항목;
}
last ++;
}
// 删除 顺序 表 的 第 i 个 元素 ——— 问题 所在
public T Delete (int i)
{ T temp = default (T); if (IsEmpty ()) { Console.WriteLine ( "목록이 비어 있습니다"); 반환 온도; } if (i <1 || i> last + 1) { Console.WriteLine ( "Positions is error"); 반환 온도; } if (i == 마지막 + 1) {
임시 = 데이터 [마지막-]; // 错误 1
}
else
{ temp = data [i-1]; for (int j = i; j <= last; ++ j) // 错误 2 { data [j] = data [j + 1]; } }
--마지막;
반환 온도;
}
// 시퀀스 테이블의 i 번째 데이터 요소
가져 오기 ; public T GetElem (int i)
{ T temp = default (T); if (IsEmpty () || i <1 || i> last + 1) { Console .WriteLine ( "List is empty or Position is erro!"); return temp; } return data [i-1]; }
// 시퀀스 테이블에서 값이 값인 데이터 요소를
찾습니다. public int Locate (T value)
{ if (IsEmpty ()) { Console.WriteLine ( "List is empty!"); return -1; }
int i = 0;
for (i = 0; i <= 마지막; i ++)
{ if (value.Equals (data [i])) { break; } } if (i> last) { return -1; }
반환 i;
}
}
여기에서 삭제 () 기능을 확인하세요.
// 시퀀스 테이블의 i 번째 요소 삭제 ——— 문제는
public T Delete (int i)
{ T temp = default (T); if (IsEmpty ()) { Console.WriteLine ( "List is empty" ); return temp; } if (i <1 || i> last + 1) { Console.WriteLine ( "Positions is error"); return temp; } if (i == last + 1) { temp = data [last -]; // 오류 1 } else { temp = data [i-1];
for (int j = i; j <= last; ++ j) // 错误 2
{ data [j] = data [j + 1]; } }
--마지막;
반환 온도;
}
오류 1 :
오류 1에서 last는 반환 값 (last--) 이후 1 씩 감소했습니다.
그러나 마지막 코드 줄에서 last가 다시 감소하는 것을 볼 수 있습니다 (--last) 이번에는 감소가 조건문에 포함되지 않기 때문에 마지막 요소가 삭제 될 때 프로그램의 흐름은 다음과 같습니다.
먼저 입력
if (i == last + 1)
{ temp = data [last--]; } 그런 다음 마지막 else 문을 건너 뛰고 코드의 마지막 두 줄을 직접 실행합니다.
--last;
return temp;
이것은 마지막 감소를 두 번 만듭니다. 따라서 마지막 요소가 삭제되면 반환 된 시퀀스 테이블은 원래 요소보다 2 개 적습니다.
오류 2 :
else
{ 임시 = 데이터 [i-1]; for (int j = i; j <= last; ++ j) // 错误 2 { data [j] = data [j + 1]; } }
temp = date [i-1]에서 그가 반환하는 것은 데이터에서 i-1 좌표를 갖는 요소, 즉 데이터의 i 번째 요소 (데이터의 좌표가 0에서 시작하기 때문에)임을 알 수 있습니다. 여기에는 잘못된 것이 없습니다.
하지만 다음 코드를 살펴 보겠습니다.
for (int j = i; j <= last; ++ j) // Error 2
{ data [j] = data [j + 1]; } 그는 i 번째 좌표에서 데이터 요소를 앞으로 이동합니다. i-1 좌표가있는 요소가 아니라 삭제 된 데이터에서 i 좌표가있는 요소. 분명히 데이터의 i 번째 요소를 좌표가 i 인 요소와 혼동하는 것은 프로그래머입니다. 데이터의 i 번째 요소는 데이터 좌표가 0부터 시작하므로 데이터 좌표가 i-1 인 요소입니다. 좌표가 i 인 데이터 요소는 데이터의 i + 1 번째 요소입니다.
이 메서드의 올바른 형식은 다음과 같아야합니다 (하나만 수정하는 방법은 여러 가지가 있음).
// 시퀀스 테이블의 i 번째 요소 삭제
public T Delete (int i)
{ T temp = default (T); if (IsEmpty ()) { Console.WriteLine ( "목록이 비어 있습니다"); 반환 온도; } if (i <1 || i> last + 1) { Console.WriteLine ( "Positions is error"); 반환 온도; } if (i == 마지막 + 1) { 임시 = 데이터 [i-1]; } else { 임시 = 데이터 [i-1]; for (int j = i-1; j <= last; ++ j)
{ 데이터 [j] = 데이터 [j + 1]; } }
--마지막;
반환 온도;
}
테스트 케이스 (다음 코드를 사용하여 두 개의 Delete () 메서드를 테스트 할 수 있습니다) :
SeqList <int> testIlist = new SeqList <int> (5);
for (int i = 1; i <6; i ++)
{ testIlist.Append (i); } for (int i = 0; i <5; i ++) { Console.WriteLine ( "data 第 i {0} 个 元素 为 {1}", i + 1, testIlist [i]); } int temp = testIlist.Delete (5);
// 테스트 오류 1 오류
Console.WriteLine ( "마지막 요소 {0} 삭제 후 testIlist에 남아있는 요소 수, 삭제 된 요소는 {1}입니다.", testIlist.GetLength (), temp);
temp = testIlist.Delete (2);
// 테스트 오류 2 오류
Console.WriteLine ( "두 번째 요소 삭제, 삭제 된 요소의 값은 {0}", temp);
Console.WriteLine ( "두 번째 요소를 삭제 한 후 testIlist의 요소");
for (int i = 0; i <testIlist.GetLength (); i ++)
{ Console.WriteLine ( "di {0} ge yuan su wei {1}", i + 1, testIlist [i]); }
위의 코드를 사용하여 오류를 쉽게 테스트 할 수 있습니다.