123456789 = 100加入+ - * /个数不限使上面得表达式成立,编程实现求出所有答案(100分)

  • 主题发起人 主题发起人 charlyisme
  • 开始时间 开始时间
C

charlyisme

Unregistered / Unconfirmed
GUEST, unregistred user!
123456789 = 100
在123456789中间加入+ - * /,个数不限,使上面得表达式成立。有点像凑24的游戏。
先申明,答案至少有101种,你能够用个算法将其穷尽么?
 
考虑一下。。。。。。
 
以前我用VB做过任意四个数字算出24的所有公式组合的程序,记得陆陆续续写了一个多月,可惜换公司后没带出来;
 
楼主问题表达不清楚哦!能不能使用括号啊?
 
先不考虑括号吧
 
‘/’应该改为 div 吧,不然玩不下去了[:D]
 
会到是会,但我现在出差在外,楼主不急就等等吧。
 
LeeChange老师能帮忙回答最好,呵呵,已经习惯您的编程风格了……我等您!谢谢您!
 
>>共有8个位置,每个位置4种可能,所以共 4 的 8次方种可能
>>也就是 2 的16次方 共 65536种可能,
>>如果每秒钟验证 1000 种可能 只需要 一分多钟就可以测试所有的可能
>>实际上现在的计算机应该能够更快才对
>>由于运算符有优先级,所以必须实现表达式的四则运算
>>算法并不是很复杂,就是运算量比较大
修正一下,其实每个位置还可以不加运算符,
所以可能的情况共有 5 的 8 次方这么多
 
关键是实现表达式的解析运算
 
抱歉,题目我理解错了,答案当然是错的了
 
共找到303种
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Memo1: TMemo;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
function ParExpr(const Tkens: String;
var Fail: Boolean): Integer;
end;

var
Form1: TForm1;
oPrioritys: array[1..5, 1..5] of Integer = (
// +, -, *, /, _,
{+} (0, 0,-1,-1,-1),
{-} (0, 0,-1,-1,-1),
{*} (1, 1, 0, 0,-1),
{/} (1, 1, 0, 0,-1),
{_} (1, 1, 1, 1, 0)
);
function IdOfOp(C: Char): Integer;
function ValueOf(C: Char): Integer;
function PrioOfOp(C1, C2: Integer): Integer;
function Calc(N1, N2: Integer;
C: Integer;
var Fail: Boolean): Integer;
function TrimExpr(var S: String): Boolean;

implementation
{$R *.dfm}
function TrimExpr(var S: String): Boolean;
var
m: String;
i: Integer;
ct: Integer;
begin
Result := False;
m := S;
ct := 0;
for i := 1 to Length(m)do
begin
if m <> '_' then
begin
ct := ct + 1;
if Result then
begin
S[ct] := m;
end;
end
else
begin
Result := True;
end;
end;
if Length(m) <> ct then
SetLength(S, ct);
end;

function IdOfOp(C: Char): Integer;
begin
case C of
'+': Result := 1;
'-': Result := 2;
'*': Result := 3;
'/': Result := 4;
'_': Result := 5;
else
Result := 0;
end;
end;

function ValueOf(C: Char): Integer;
begin
if C in ['0'..'9'] then
Result := Ord(C) - Ord('0')
else
Result := -1;
end;

function PrioOfOp(C1, C2: Integer): Integer;
begin
if (C1 > 0) and (C2 > 0) then
Result := oPrioritys[C1, C2]
else
Result := 0;
end;

function Calc(N1, N2: Integer;
C: Integer;
var Fail: Boolean): Integer;
var
m1, m2: Integer;
n: Integer;
begin
m1 := N1;
m2 := N2;
n := C;
Result := 0;
case n of
1: Result := m1 + m2;
2: Result := m1 - m2;
3: Result := m1 * m2;
4:
begin
if (m2 = 0) then
Fail := True
else
Result := m1 div m2;
end;
5: Result := m1 * 10 + m2;
else
raise Exception.Create('invalidoperator');
end;
end;

function TForm1.ParExpr(const Tkens: String;
var Fail: Boolean): Integer;
var
i: Integer;
stk: array[0..20] of Integer;
//数据栈
opstk: array[0..20] of Integer;
//运算符栈
sp1, sp2: Integer;
op, lastop: Integer;
t, n1, n2: Integer;
begin
//解析表达式,假设每个符号或数字都是一个字符
sp1 := 0;
sp2 := 0;
n1 := 0;
n2 := 0;
for i := 1 to Length(Tkens)do
begin
t := ValueOf(Tkens);
if t >= 0 then
begin
//数字入栈
stk[sp1] := t;
sp1 := sp1 + 1;
end
else
//如果不是数字,则认为是运算符
begin
lastop := IdOfOp(Tkens);
if sp2 > 0 then
begin
op := opstk[sp2 - 1];
//循环,直到所有前面的运算都完成
if PrioOfOp(op, lastop) >= 0 then
begin
while (sp2 > 0) and (PrioOfOp(op, lastop) >= 0)do
begin
sp2 := sp2 - 1;
if sp1 > 0 then
begin
sp1 := sp1 - 1;
n2 := stk[sp1];
end;
if sp1 > 0 then
begin
sp1 := sp1 - 1;
n1 := stk[sp1];
end;
t := Calc(n1, n2, op, Fail);
stk[sp1] := t;
sp1 := sp1 + 1;
op := opstk[sp2 - 1];
end;
//运算符入栈
opstk[sp2] := lastop;
sp2 := sp2 + 1;
end
else
begin
opstk[sp2] := lastop;
sp2 := sp2 + 1;
end;
end
else
//符号入栈
begin
opstk[sp2] := lastop;
sp2 := sp2 + 1;
end;
end;
end;
while sp1 > 1do
begin
sp1 := sp1 - 1;
n2 := stk[sp1];
sp1 := sp1 - 1;
n1 := stk[sp1];
if sp2 > 0 then
begin
sp2 := sp2 - 1;
op := opstk[sp2];
stk[sp1] := Calc(n1, n2, op, Fail);
sp1 := sp1 + 1;
end;
end;
Result := stk[0];
end;

procedure TForm1.Button1Click(Sender: TObject);
const
ops: String = '+-*/_';
var
m: array[1..20] of Integer;
st: Integer;
t, v: String;
tc, pc: Integer;
t1, t2, n: Integer;
Fail: Boolean;
begin
//ShowMessage(IntToStr(ParExpr(Edit1.Text)));
//for test
t := '1,2,3,4,5,6,7,8,9';
Memo1.Lines.begin
Update;
Memo1.Lines.Clear;
t1 := GetTickCount;
for st := 1 to 20do
m[st] := 1;
st := 1;
tc := 0;
pc := 0;
while m[st] <= 5do
begin
t[st * 2] := ops[m[st]];
st := st + 1;
if st > 8 then
begin
tc := tc + 1;
Fail := False;
n := ParExpr(t, Fail);
if not Fail and (n = 100) then
begin
v := t;
TrimExpr(v);
Memo1.Lines.Add(v);
pc := pc + 1;
end;
st := st - 1;
m[st] := m[st] + 1;
while (st > 1)and (m[st] > 5)do
begin
m[st] := 1;
st := st - 1;
m[st] := m[st] + 1;
end;
end;
Application.ProcessMessages;
if Application.Terminated then
Break;
end;
t2 := GetTickCount;
Memo1.Lines.EndUpdate;
Caption := Format('%d/%d, Time: %d', [pc, tc, t2-t1]);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
s: String;
begin
s := '13_32_34';
TrimExpr(s);
ShowMessage(s);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
m: Integer;
n: Boolean;
begin
n := False;
m := ParExpr(Edit1.Text, n);
if n then
Caption := 'fail'
else
Caption := IntToStr(m);
end;

end.
 
谁帮忙验证几个,看算法是否正确:
123-4-5-6-78/9
123-4-5-6*7/8-9
123-4*5+6+7/8-9
123-4*5+6-7/8-9
123-45-67+89
123*4-56*7+8/9
123*4-56*7-8/9
123*4/5-6+7-8+9
123*4/5-6+78/9
123/4-5+6+78-9
123/4-5+678/9
123/4*5-67+8+9
 
呵呵,好像都不对
 
修正算法,上面的代码已更新,
共303中结果,
function ParExpr(const Tkens: String;
var Fail: Boolean): Integer;
var
i: Integer;
stk: array[0..20] of Integer;
//数据栈
opstk: array[0..20] of Integer;
//运算符栈
sp1, sp2: Integer;
op, lastop: Integer;
t, n1, n2: Integer;
begin
//解析表达式,假设每个符号或数字都是一个字符
sp1 := 0;
sp2 := 0;
n1 := 0;
n2 := 0;
for i := 1 to Length(Tkens)do
begin
t := ValueOf(Tkens);
if t >= 0 then
begin
//数字入栈
stk[sp1] := t;
sp1 := sp1 + 1;
end
else
//如果不是数字,则认为是运算符
begin
lastop := IdOfOp(Tkens);
if sp2 > 0 then
begin
//取符号栈顶元素
op := opstk[sp2 - 1];
//循环,直到所有前面的运算都完成
if PrioOfOp(op, lastop) >= 0 then
begin
//将前面运算优先级高的运算全部完成
while (sp2 > 0) and (PrioOfOp(op, lastop) >= 0)do
begin
sp2 := sp2 - 1;
if sp1 > 0 then
begin
//从栈中弹出操作数2
sp1 := sp1 - 1;
n2 := stk[sp1];
end;
if sp1 > 0 then
begin
//从栈中弹出操作数1
sp1 := sp1 - 1;
n1 := stk[sp1];
end;
//进行计算
t := Calc(n1, n2, op, Fail);
//计算结果入栈
stk[sp1] := t;
sp1 := sp1 + 1;
//再取符号栈顶元素,直到前面优先级高的运算全部完成
op := opstk[sp2 - 1];
end;
//运算符入栈
opstk[sp2] := lastop;
sp2 := sp2 + 1;
end
else
begin
//符号入栈
opstk[sp2] := lastop;
sp2 := sp2 + 1;
end;
end
else
//符号入栈
begin
opstk[sp2] := lastop;
sp2 := sp2 + 1;
end;
end;
end;
//处理栈中剩余的所有数值和运算符
while sp1 > 1do
begin
sp1 := sp1 - 1;
n2 := stk[sp1];
sp1 := sp1 - 1;
n1 := stk[sp1];
if sp2 > 0 then
begin
sp2 := sp2 - 1;
op := opstk[sp2];
stk[sp1] := Calc(n1, n2, op, Fail);
sp1 := sp1 + 1;
end;
end;
Result := stk[0];
end;
 
我的算法不知道对不对
 
后退
顶部