2014-12-13 4 views
-2

최종 사용자가 이름을 추가 할 수있는 간단한 양식을 만들었습니다. 이 프로그램은 정수를 사용할 때 정상적으로 작동합니다 (즉, 최종 사용자에게 정수를 물어 보면 목록에 추가 된 다음 목록 상자의 모든 정수가 정렬되었습니다). 이제 Strings를 작동 시키려고합니다. 즉, 이름을 물어보고 목록 상자에 추가하고 정렬을 클릭하면 삽입 정렬이 실행됩니다. 그것은,하지만, 난 항상 모듈 KernelBase.dll에서 "긴 16 진수 번호에서 액세스 위반"런타임 오류가 발생하고있어, 괜찮아요 컴파일합니다. 어!Delphi 삽입 정렬 ListBox 런타임 오류.

unit Unit4; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls; 

type 
    TForm4 = class(TForm) 
    btnAdd: TButton; 
    txtEdit: TEdit; 
    ListBox: TListBox; 
    btnSort: TButton; 
    Label1: TLabel; 
    procedure btnAddClick(Sender: TObject); 
    procedure btnSortClick(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    procedure InsertionSort(var list: array of string;first,last:integer); 
    end; 

var 
    Form4: TForm4; 
    List: array [1..10] of string; 

implementation 

{$R *.dfm} 

procedure tform4.insertionSort(var list: array of string; first,last:integer); 
var CurrentIndex, Index,count:integer; CurrentValue: string; 
begin 
    CurrentIndex:=first+1; 
    while CurrentIndex <= last do 
    begin 
     currentValue:=list[CurrentIndex]; 
     Index:=CurrentIndex-1; 
     While (list[index] > currentValue) and (index >= 0) 
     do 
     begin 
      list[Index+1]:= list[Index]; 
      Index:=Index-1; 
     end; 
     list[index+1]:=currentValue; 
     CurrentIndex:=CurrentIndex+1; 
    end; 
    listbox.Clear; 
    for count := 1 to length(list) do 
      listbox.Items.Add((list[count])); 
end; 

procedure TForm4.btnAddClick(Sender: TObject); 
begin 
listbox.Items.Add(txtEdit.Text); 
txtEdit.Text:=''; 
end; 

procedure TForm4.btnSortClick(Sender: TObject); 
var last:integer; 
begin 
last:=length(list); 
showmessage(inttostr(last)); 
insertionSort(list, 1, last); 
end; 

procedure TForm4.FormCreate(Sender: TObject); 
var step:integer; 
begin 
for step := 1 to length(list) do 
    listbox.Items.Add((list[step])); 
end; 

begin 
    list[1]:='Zulu'; 
    list[2]:='Yankee'; 
    list[3]:='XRay'; 
    list[4]:='Whiskey'; 
    list[5]:='Victor'; 
    list[6]:='Uniform'; 
    list[7]:='Tango'; 
    list[8]:='Sierra'; 
    list[9]:='Romeo'; 
    list[10]:='Quebec'; 
end. 
+0

'InsertionSort'는'문자열 배열'에서 동작합니다. 이것은 목록 색인이 0에서 시작 함을 의미합니다. 먼저 통과하고 있습니다. 1을 기준으로 중지하십시오. –

+0

큰 문제는 색인 기반에 대한 혼란으로 보입니다. 귀하의 코드에는 1을 기준으로 한 지표와 0을 기준으로 한 지표가 혼합되어 있습니다. 그러지 마. 어디에서나 0을 사용하십시오. –

+0

죄송합니다, 삽입 지점 정렬 절차에서 다음 줄을 따로 따로 1 기반으로 붙어 있다고 생각하므로 죄송합니다. _While (list [index]> currentValue) 및 (index> = 0) _ 나는 삽입 정렬 알고리즘의 실제적인 부분이라고 생각한다. – user3396486

답변

3

가장 명백한 문제는 하나의 기반 및 0 기반 배열 인덱싱을 혼합 한 것입니다. 열린 배열은 0을 기준으로합니다. 귀하의 배열은 하나를 기반으로합니다. 이 차이를 설명하지 않았습니다.

차이점에 대한 설명은 앞으로 나아갈 길이 아닙니다. 혼합 규칙은 대량 혼란을 초래합니다. 하나의 대회를 선택하고 그것에 충실하십시오. Delphi 설계자는 이미 개방형 배열과 동적 배열을 기반으로 0을 선택했기 때문에 선택이 명확합니다. 0 기반 배열을 일관되게 사용하십시오.

실제로 첫 번째 및 마지막 배열 인덱스를 전달할 필요는 없습니다. 열린 배열의 첫 번째 및 마지막 인덱스는 low()high()입니다.

While (list[index] > currentValue) and (index >= 0) 

이 조건은 잘못되었습니다. 어레이에 액세스하기 전에 index이 양성인지 테스트해야합니다.

While (index >= 0) and (list[index] > currentValue) 

정말 정렬 코드를 GUI와 분리해야합니다. 그렇게하면 정렬 코드를 다시 사용할 수 있습니다.

변수 이름 count은 루프 변수에 나쁜 선택입니다. 이 이름을 사용하여 컬렉션의 항목 수를 나타냅니다.

더 많은 오류가있을 수 있습니다. 디버거를 사용하여 찾을 수 있어야합니다.

+0

데이비드 감사합니다. 프로 시저 선언에서 매개 변수를 확인합니다. 여전히 런타임 오류가 발생합니다. – user3396486

+0

디버거를 사용하고 있습니까? 이것은 디버깅 기술을 배우는 좋은 기회가 될 것입니다. –

+0

그게 다야! 나는 두 조건의 순서가 이것에 어떻게 영향을 미치는지 이해하지 못한다. 분명히 질서는 중요하지 않습니다 ... 그것은 단순히 두 가지가 모두 사실임을 의미합니다. – user3396486