ランダムのNumberが4つあるとします。
例) No.2、No.14、No.5、No.17
このNo.はそれぞれ値をもっていてこれもランダムの値を持っています。
No.2→3 No.14→4 No.5→6 No.17→5
ここで、No.をそれぞれ比較してNo.が一番小さいNoの値を一番大きいNoで積をとりたいと考えています。
次に2番目に小さいNoの値と2番目に大きいNoをかけるといった具合にしてやりたいです。
この例でいいますと
3(No.2の値) *17(1番目に大きいNo.) = 51;
6(No.5の値) *14(2番目に大きいNo.) = 84;
4(No.14の値)* 5(3番目に大きいNo.) = 20;
5(No.17の値)* 2(4番目に大きいNo.) = 10;
これは一例になりますが、もっと要素数が増えた場合などにも対応できるようにスマートなやり方はありますでしょうか?
よろしくお願いします。
① Noの入った配列を小さい順にソート
② ランダム値の入った配列を大きい順にソート
for I:=0 to 3 do
begin
答え = Noの入った配列[I] * ランダム値の入った配列[I];
end;
KHE00221さん
大きい順、小さい順にソートする簡単な方法ってありますか?
一つ一つ比較しなければならないのでしょうか?
すいません 例を間違えていたので訂正します。
No.の値をそれぞれ比較してNo.が一番小さいNoの値を番目に大きいNo.の値のNoで積をとりたいと考えています。
3(1番目に小さいNo.の値) * 5(1番目に大きいNo.の値のNo) = 15;
4(2番目に小さいNo.の値) *17(2番目に大きいNo.の値のNo)= 68;
5(3番目に小さいNo.の値) *14(3番目に大きいNo.の値のNo)= 70;
6(4番目に小さいNo.の値) * 2(4番目に大きいNo.の値のNo)= 12;
ソートというのは必ず一つ一つ比較を行います。
アルゴリズムは複数ありますしFAQですので割愛します。
VCLを使ってアルゴリズムを考えずお手軽にやりたいのであれば、
TListにソートが実装されていますのでそれを使って下さい。
ほれ、
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
TBuffer = array of array of Integer;
ERangeError = class(Exception)
public
ErrorCode: Integer;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
resourcestring
SOutOfRangeBuffer = 'Indexが配列の範囲を超えています';
SDataNothing = 'その順位のデータは存在しません';
function Get(Buffer: TBuffer;Index1,Index2: WORD): Integer;
var
I,J,K,K2: Integer;
E: ERangeError;
Save1,Save2: Integer;
begin
//範囲チェック
if (Index1 < (High(Buffer)-Low(Buffer))+2 ) and (Index1 > 0) then
begin
//ソート(データ量が多ければ QuickSort にでも変更)
for I:= Low(Buffer) to High(Buffer) do
begin
for J:= Low(Buffer) to High(Buffer) do
begin
if Buffer[I,0] < Buffer[J,0] then //小さい順
begin
K := Buffer[I,0];
K2 := Buffer[I,1];
Buffer[I,0] := Buffer[J,0];
Buffer[I,1] := Buffer[J,1];
Buffer[J,0] := K;
Buffer[J,1] := K2;
end;
end;
end;
//取り出す
I := Low(Buffer);
J := 1;
while (Index1 <> 0) and (I <= High(Buffer) ) do
begin
if Buffer[I,0] <> Save1 then
begin
Save1 := Buffer[I,0];
Dec(Index1);
Inc(J);
end;
Inc(I);
end;
//ソート(データ量が多ければ QuickSort にでも変更)
for I:= Low(Buffer) to High(Buffer) do
begin
for J:= Low(Buffer) to High(Buffer) do
begin
if Buffer[I,0] > Buffer[J,0] then //大きい順
begin
K := Buffer[I,0];
K2 := Buffer[I,1];
Buffer[I,0] := Buffer[J,0];
Buffer[I,1] := Buffer[J,1];
Buffer[J,0] := K;
Buffer[J,1] := K2;
end;
end;
end;
//取り出す
I := Low(Buffer);
J := 1;
while (Index2 <> 0) and (I <= High(Buffer) ) do
begin
if Buffer[I,1] <> Save2 then
begin
Save2 := Buffer[I,1];
Dec(Index2);
Inc(J);
end;
Inc(I);
end;
Result := Save1 * Save2;
//該当するデータが存在しない
if (Index1 <> 0) or (Index2 <> 0) then
begin
E := ERangeError.CreateRes(@SDataNothing);
E.ErrorCode := 2;
raise E;
end;
end
else
begin
//配列の範囲外が指定された
E := ERangeError.CreateRes(@SOutOfRangeBuffer);
E.ErrorCode := 1;
raise E;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Buffer: TBuffer;
I: Integer;
begin
SetLength(Buffer,4);
for I:=0 to 4 do
begin
SetLength(Buffer[I],3);
end;
Buffer[0,0] := 3; Buffer[0,1] := 2;
Buffer[1,0] := 4; Buffer[1,1] := 14;
Buffer[2,0] := 5; Buffer[2,1] := 17;
Buffer[3,0] := 6; Buffer[3,1] := 5;
Caption := IntToStr(Get(Buffer,4,4));
end;
end.
すいません、回答ありがとうございます。
一つ一つ計算していくことによってソートしなければいけないのですね。
またTistにソート機能があることも知れました。
ありがとうございます。
ツイート | ![]() |