字符串处理的问题. 理解问题能力超强的朋友请进.(100分)

  • 主题发起人 主题发起人 m911
  • 开始时间 开始时间
M

m911

Unregistered / Unconfirmed
GUEST, unregistred user!
类似这样的字符串 62 C7 2C A2 92 0E DC 85 98 EE .......
将每组的两字符分开,并换成相对应的字符,并按每10组递进改变整个字符串的内容, 最高效的代码应该怎么写

对应表如下

第一组 第一个字符对应表
A = F
B = E
C = 9
D = 8
E = B
F = A
0 = 5
1 = 4
2 = 7
3 = 6
4 = 1
5 = 0
6 = 3
7 = 2
8 = D
9 = C

第一组 第二个字符对应表

A = 8
B = 9
C = E
D = F
E = C
F = D
0 = 2
1 = 3
2 = 0
3 = 1
4 = 6
5 = 7
6 = 4
7 = 5
8 = A
9 = B
...................................
第二组 第一个字符对应表
A = 5
B = 4
C = 3
D = 2
E = 1
F = 0
0 = F
1 = E
2 = D
3 = C
4 = B
5 = A
6 = 9
7 = 8
8 = 7
9 = 6

第二组 第二个字符对应表
A = D
B = C
C = B
D = A
E = 9
F = 8
0 = 7
1 = 6
2 = 5
3 = 4
4 = 3
5 = 2
6 = 1
7 = 0
8 = F
9 = E
...................................
第三组 第一个字符对应表
A = B
B = A
C = D
D = C
E = F
F = E
0 = 1
1 = 0
2 = 3
3 = 2
4 = 5
5 = 4
6 = 7
7 = 6
8 = 9
9 = 8
 
mei ren hui
 
汗 ~~~ 楼上这位大哥请说国语好吗? [:D]
 
二楼说的是纯正的拼音

一楼说的虽然是国语,可是到底要说啥,偶仔细瞄了几分钟,还是没看明白
[:D]
 
这十组数据你可以用十个字符数组存贮,然后根据字符串写循环替换就可以了
 
的确很难看明白
 
to 潇雨, 这位朋友的理解能力的确强

我是新手,不知道该如何处理,能否将代码贴出? 谢谢
 
to m911:
既然你说要求高效, 那估计这个序列很长. 这样的话用查映射表的做法比较快, 但耗空间比较多. 示范程序如下 (假定只有两组)

========================

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

const

MaxGroup = 2;
CharMap : array[1..MaxGroup, 1..2] of string[16] =
(('FE98BA54761032DC', '89EFCD23016745AB'),
('543210FEDCBA9876', 'DCBA9876543210FE')
);

var
Form1: TForm1;
CharMappingTable : array[1..MaxGroup, 1..2, 48..122] of char;
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var i, j, k : integer;
begin
for i := 1 to MaxGroup do
for j := 1 to 2 do
for k := 1 to 16 do
begin
if (k<=6) then
begin
CharMappingTable[i,j,64+k] := CharMap[i,j,k];
CharMappingTable[i,j,96+k] := CharMap[i,j,k];
end
else CharMappingTable[i,j,k-7+48] := CharMap[i,j,k]
end;
end;



procedure TForm1.Button1Click(Sender: TObject);
var
str : array [1..500] of string[2];
i : integer;
begin
str[1] := '62';
str[2] := 'C7';

for i := 1 to MaxGroup do
begin
str := CharMappingTable[i,1,Ord(str[1])] + CharMappingTable[i,2,Ord(str[2])];
ShowMessage(str);
end;
end;

end.
 
const
vl:array[0..9,0..15] of char =
(('F','E','9','8','B','A','5','4','7','6','1','0','3','2','D','C'),
('8','9','E','F','C','D','2','3','0','1','6','7','4','5','A','B'),
('5','4','3','2','1','0','F','E','D','C','B','A','9','8','7','6')
……
);

var
i,j:integer;
ls:string;
begin
ls:=s;
for i:=0 to length(s)-1 do
for j:=0 to 15 do
if vl[i,j]=ls then
ls:=vl[i,j];
//最后ls就是你要的那个结果
end;
 
to boy2002cn, 这个方法好像不错啊, 但是好像有点问题, 每组应该是2个字符哦
 
ls='62C72CA2920EDC8598EE';
你那个只能做成这样子,就中间都没有空格的形式,我就没有区分是第几个,一共就是是10*2个呀,那我从0到20还不行吗?
上面代码里的s就是这样定义的
const s='62C72CA2920EDC8598EE';
然后就是下面的了,你只在把s改了,Vl那个静态数组改了就能用了
 
下面是我改的 但是得不到正确的结果
procedure TForm1.Button1Click(Sender: TObject);
var
i,j:integer;
ls:string;
begin
ls:=edit1.text;
for i:=0 to length(ls)-1 do
for j:=0 to 15 do
if vl[i,j]=ls then
ls:=vl[i,j];

edit2.text := ls;
end;
麻烦帮忙更正一下哦

还有就是比较长的字符串 可以递进的处理吗?
 
把你那个数组发出来
 
比如是这样的
62 C7 2C A2 92 0E DC 85 98 EE 63 C6 2D A3 93 0F DD 84 99 EF 60 C5 2E A0 90 0C DE 87 9A EC 61 C4 2F A1 91

但平时的 不一定多少位啊! 只是按每10组 循环回来就可以
 
明天再说吧,下班了
 
刚刚忙着下班, 随便写了下代码就贴了, 现在整理一下:
全局定义部分
const
MaxGroup = 2; //最大组数
CharMap : array[1..MaxGroup, 1..2] of string[16] = //改变MaxGroup时需要同时改变转换表定义
(('FE98BA54761032DC', '89EFCD23016745AB'),
('543210FEDCBA9876', 'DCBA9876543210FE')
);


函数:

procedure MakeTable; //建立映射表,只需在开始运行一次,转换期间不用运行
var i, j, k : integer;
begin
for i := 1 to MaxGroup do
for j := 1 to 2 do
for k := 1 to 16 do
begin
if (k<=6) then
begin
CharMappingTable[i,j,byte('a')-1+k] := CharMap[i,j,k];
CharMappingTable[i,j,byte('A')-1+k] := CharMap[i,j,k];
end
else CharMappingTable[i,j,k-7+byte('0')] := CharMap[i,j,k]
end;
end;

procedure Convert(var s : string); //为了照顾效率, 采用直接写变量参数的的做法. 最后结果在传入的参数中
var i, k : integer;
begin
MakeTable; //建立映射表
i := 1; //字符指针
k := 1; //当前用的转换表组号
while i <= length(s) do
begin
s := CharMappingTable[k, 1 , Byte(s)];
inc(i); //指向第二个字符, 若s符合格式, 必定不会出界
s := CharMappingTable[k, 2, Byte(s)];
inc(i,2); //跳过空格, 到下一组第一个字符
if k < MaxGroup then inc(k) else k:=1;
end;
end;

========================================
To m911:
如果你追求的高效是编写源码效率, 可以用boy2002cn的做法, 一共要做[字符串长度]乘15次比较 (不过暂时看来好象有点错)
如果你追求的是执行效率而你要转换的字符串非常长, 可以考虑我的做法, 主体部分一共要做[字符串长度/3]次比较. 如果还要提高执行效率,可考虑用PChar类型做当前字符指针.

========================================
To boy2002cn:
if vl[i,j]=ls then
ls:=vl[i,j];
这里好像写错了? if A=B then B:=A ?

另外ls是string, 第一个字符应该是ls[1]吧?
 
呵呵,加密算法啊,建议采用标准加密算法更好!
 
不好意思, 刚刚因为家里DELPHI还没装上 (该死的木马, 顶它个肺), 上面的代码是直接在这里打的, 过不了编译. 现在把调试过的代码贴下:

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
cmbSource: TComboBox; //在Form上放个ComboBox作为输入
memResult: TMemo; //在Form上放个Memo作为输出
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject); //在Form上放个按钮触发运算
private
{ Private declarations }
public
{ Public declarations }
end;

const
MaxGroup = 2; //最大组数
CharMap : array[1..MaxGroup, 1..2] of string[16] = //改变MaxGroup时需要同时改变转换表定义
(('FE98BA54761032DC', '89EFCD23016745AB'),
('543210FEDCBA9876', 'DCBA9876543210FE')
);

var
Form1: TForm1;
CharMappingTable : array[1..MaxGroup, 1..2, 48..122] of char;

implementation

{$R *.dfm}

procedure MakeTable; //建立映射表,只需在开始运行一次,转换期间不用运行
var i, j, k : integer;
begin
for i := 1 to MaxGroup do
for j := 1 to 2 do
for k := 1 to 16 do
begin
if (k<=6) then
begin
CharMappingTable[i,j,byte('a')-1+k] := CharMap[i,j,k];
CharMappingTable[i,j,byte('A')-1+k] := CharMap[i,j,k];
end
else CharMappingTable[i,j,k-7+byte('0')] := CharMap[i,j,k]
end;
end;

procedure Convert(var s : string); //为了照顾效率, 采用直接写变量参数的的做法. 最后结果在传入的参数中
var i, k : integer;
begin
//MakeTable; //建立映射表
//因已在Form.OnCreate建立了映射表, 这里不用重复建立
i := 1; //字符指针
k := 1; //当前用的转换表组号
while i <= length(s) do
begin
s := CharMappingTable[k, 1 , Byte(s)];
inc(i); //指向第二个字符, 若s符合格式, 必定不会出界
s := CharMappingTable[k, 2, Byte(s)];
inc(i,2); //跳过空格, 到下一组第一个字符
if k < MaxGroup then inc(k) else k:=1;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var s : string;
begin
//转换
s := self.cmbSource.Text;
Convert(s);
self.memResult.Text := s;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
MakeTable; //建立全局映射表

//初始化调试数据
self.cmbSource.Items.Add('62 C7 2C A2 92 0E DC 85 98 EE 63 C6 2D A3 93 0F DD 84 99 EF 60 C5 2E A0 90 0C DE 87 9A EC 61 C4 2F A1 91');
self.cmbSource.ItemIndex := 0;
end;

end.
 
先谢谢你啊 我编译一下
 
已经能用啦! 谢谢
 

Similar threads

后退
顶部