现在我有26个元素a...z
我想自由生成相关的组合
从一位起
a
a+b
a+b+c
a+b+c+d
......
生成所有组合对顺序没有要求,即a+b 和 b+a可以当同一条,不用重复出现
我想自由生成相关的组合
从一位起
a
a+b
a+b+c
a+b+c+d
......
生成所有组合对顺序没有要求,即a+b 和 b+a可以当同一条,不用重复出现
解决方案 »
- 如何让TWebBrowser按Del键时会删除所选全部内容﹖
- missing operator or semicolon错误提示
- 请问如何把一段文本复制起来
- ADO 的Lookup Field 问题
- 有没有代码编辑器的控件?就是输入了关键字或对象名之后,可以自动出现一个代码提示(下拉)框?
- 如何使用程序在SQL表中指定位置添加一列?
- DBGrid中的某列能显示图片吗?
- 本来想在DB2版,提这个问题的,可是看那边的人气实在是不怎么样!只好来这里问了,还望大家帮个忙!
- 小问,在线等待
- 这到底是为什么?谁能告诉我?
- 怎样保持idhttp始终登录状态
- 创建窗体动态链接库,成功运行,在文件夹里找不到后缀是.dll的对象
program Project4;{$APPTYPE CONSOLE}uses
SysUtils;var
myArr : array [0..25] of AnsiString = ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
var
i , j : integer;
s : AnsiString;
begin
try
for i := 0 to {2的26次方} do
begin
s := '';
for j := 0 to 25 do
begin
if (i and (1 shl j) <> 0 ) then
begin
s := s + myArr[j] + '+';
end ; end;
writeln(s);
end;
{这里把 字符串最后一个 + 要去掉,我就不去掉了}
Readln(s); except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
program Project1;{$APPTYPE CONSOLE}var
a:array [0..26] of char;
s:set of char;
j:integer;procedure print(n:integer);//打印过程
var
i:integer;
begin
for i:=1 to n-1 do write(a[i],'+');
writeln(a[n]);
end;procedure Search(num:Integer;t:integer);//回溯过程
var
ch:char;
begin
if t>num then
begin
print(num);
exit;
end;
for ch:=a[t-1] to 'z' do
if ch in s then
begin
s:=s-[ch];
a[t]:=ch;
search(num,t+1);
s:=s+[ch];
end;
end;begin
assign(output,'output.out');rewrite(output);
//初始化数据
a[0]:='a';
s:=['a'..'z'];
for j:=1 to 26 do search(j,1);//主过程,j越大会越久,因为是递归调用
close(output);
end.
只能用WinHex或UltraEdit打开。。但无法计算行数
结果的总字节数应该:872415232,加上67108863(或67108862)个回车换行计134217726(或134217724),总计应该是1006632958(1006632956),0.9375GB,即便使用Unicode,约为1.875GB,也不会是1.7G
A,AB,ABC这样的顺序,而是A,B,AB,AC
var
aLineBuffer : Array [0..26-1 + 2] of AnsiChar;
hFile : THandle;
sBuf : AnsiString;
iBufSize : integer;
iBufUseSize : integer;
//返回位数,字符串保存于aLineBuffer中,返回位数中包含回车换行符
Function IndexToBuffer(Index : DWORD) : integer;
asm
XOR ECX , ECX
LEA EDX , aLineBuffer
@@Loop:
BTR EAX , ECX
JNC @@Next
MOV [EDX] , CL
ADD [EDX] , 'A'
INC EDX
@@Next:
TEST EAX , EAX
JZ @@Break
INC ECX
CMP ECX , 26
JNZ @@Loop
@@Break:
MOV [EDX].WORD , $0A0D
LEA EAX , aLineBuffer
SUB EDX , EAX
LEA EAX , [EDX+2]
end;//初始化文件
Function InitSaveFile(Const FileName : AnsiString) : Boolean;
begin
hFile := CreateFile(PAnsiChar(FileName),GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL , 0);
Result := hFile<>INVALID_HANDLE_VALUE;
end;//写入缓冲区到硬盘
procedure SaveToFile;
var
D : DWORD;
begin
WriteFile(hFile , Pointer(sBuf)^ , iBufUseSize , D , NIL);
iBufUseSize := 0;
end;//把当前行增加到缓冲区中
procedure AppendToBuf(LineSize : integer);
begin
if LineSize+iBufUseSize>iBufSize then SaveToFile;
Move(aLineBuffer , Ptr(Integer(sBuf) + iBufUseSize)^ , LineSize);
iBufUseSize := iBufUseSize + LineSize;
end;procedure TForm1.Button1Click(Sender: TObject);
var
Index , n , nCount , nTime : DWORD;
begin
if not InitSaveFile('E:\dd.dat') then exit; iBufSize := 20 * 1024 * 1024; //缓冲区 20M
iBufUseSize := 0;
SetLength(sBuf , iBufSize); nTime := GetTickCount();
nCount := 0;
Index := 1;
while True do begin
n := IndexToBuffer(Index);
Inc(nCount , n);
AppendToBuf(n);
if n=28 then Break;
Inc(Index);
end;
nTime := GetTickCount() - nTime;
Caption := '总字节数:' + IntToStr(nCount) + ' 耗时:' + IntToStr(nTime) + '豪秒';
if iBufUseSize<>0 then SaveToFile;
SetLength(sBuf , 0);
CloseHandle(hFile);
end;总共60秒,不写盘20秒,不写缓冲区13秒,可见瓶颈,如果用IOCP写文件估计会好一点 1.6的烂CPU
文件大小 1006632958 Bytes 吻合 僵哥的计算
不过没加加号,加了也就我那个答案。
我是从算法的角度去分析。。
还有,文件操作可用Assign(),不然有点麻烦。。
asm
XOR ECX , ECX
LEA EDX , aLineBuffer
@@Loop:
BTR EAX , ECX
JNC @@Next
MOV [EDX] , CL
ADD [EDX].Byte , 'A'
INC EDX
TEST EAX , EAX
JZ @@Break
@@Next:
INC ECX
CMP ECX , 26
JNZ @@Loop
@@Break:
MOV [EDX].WORD , $0A0D
LEA EAX , aLineBuffer
SUB EDX , EAX
LEA EAX , [EDX+2]
end;
可知你的结果数量为 ∑n!/((n-m)!*m!) n=26 m=1...26
共 67108863 个具体到每一个的值,建议你先看一下“高效的10移动算法”,无递归
//{$define NEED_SPLIT_CHAR}{$ifdef NEED_SPLIT_CHAR}
{$define LINE_BREAK} //分隔符都要了,换行符你就别省了
{$endif}{$ifdef LINE_BREAK}
//{$define LINE_BREAK_UNIX_LIKE} //类Unix的标准当中只有换行0x0a,没有回车0x0d
{$endif}
function DataToText( OffSet: DWORD (*缓冲区偏移*)
; Data: DWORD (*当前值*)
; Buffer : PAnsichar (*缓冲区基址*)
):DWORD;
asm
//保护他人的劳动成果人人有责
push ebx@@LOOP:
BSF EBX, EDX //从右至左取首个有效比特位(即bit=1),结果存入EBX (取值:0..31)
JZ @@RET //如果整个EDX都没有一个big=1,则ZF标志被设置,别犹豫了,结束吧
BTR EDX, EBX //取走么,自然是真的拿走的啦
ADD EBX, 'A' //转成字母,才更方便查看嘛
{$ifdef NEED_SPLIT_CHAR}
MOV BH, '+' //有人说需要中间的分隔符呢,这个么...不是问题,你想要就给你加上,反正我不要
Mov WORD PTR [ECX + EAX], BX //没啥好说,写到缓冲区保存成果,要不然没有会知道的
ADD EAX, 2 //写了两个字节,自然就要报告两个字节,这个时候不需要谦虚
{$else}
Mov Byte PTR [ECX + EAX], BL //报告,这是组合当中的其中一个元素
Inc EAX //写了一个字节
{$endif}
jmp @@LOOP //还没结束呢,继续吧
@@RET:
{$ifdef NEED_SPLIT_CHAR}
//占用最后一个'+'的位置
{$ifdef LINE_BREAK}
{$ifdef LINE_BREAK_UNIX_LIKE}
MOV Byte PTR [ECX + EAX - 1], $0a
{$else}
MOV Word PTR [ECX + EAX - 1], $0a0d
Inc EAX
{$endif}
{$else}
Dec EAX //吃多了吧,赶紧吐出来
{$endif}
{$else}
{$ifdef LINE_BREAK}
{$ifdef LINE_BREAK_UNIX_LIKE}
MOV Byte PTR [ECX + EAX], $0a
Inc EAX
{$else}
MOV Word PTR [ECX + EAX], $0a0d
ADD EAX, 2
{$endif}
{$endif}
{$endif} //归还他人的劳动成果也是我们应尽的义务
pop ebx
end;
procedure TForm1.Button1Click(Sender: TObject);
var
I:DWORD;
i64Start, i64End, i64Freq : Int64;
D: array of AnsiChar;
L: DWORD;
M, N, E, T: DWORD;
begin
M := 26; //这个不用解释(M <= 32)
L := 1024; //预置缓冲区大小(写文件的话,请自行调整) QueryPerformanceFrequency(i64Freq); QueryPerformanceCounter(i64Start); //计时开始 E := $FFFFFFFF shr (32 - M); //计算个数 //实际缓冲区大小,比预置多分配 (M字节 + (M - 1)个"+" + 0x0a0d回车换行) (这里面只是应大众的使用习惯)
SetLength(D, L + M + (M - 1) + 2); T := 0; //字节数统计 N := 0; //单批写入字节数
for I := 1 to E do begin
N := DataToText(N, I, @D[0]);
if N >= L then begin //缓冲写满,请进行保存N个字节
//... T := T + N; //这里只做统计
N := 0; //重头开始写入
end;
end;
//如果N > 0,请进行保存N个字节
//...
T := T + N; //这里只做统计 QueryPerformanceCounter(i64End); //计时结束 ShowMessage('总字节数:' + IntToStr(T) +' 耗时:' + IntToStr((i64End - i64Start)(*秒*) * 1000 (*毫秒*) * 1000 (*微秒*) div i64Freq (*时钟频率*)) + '微秒');end;
你真的用你贴出的算法计了一次吗。的确利害!1。7G真的想不到这么大
program Project1;{$APPTYPE CONSOLE}uses
SysUtils,
windows;
function GetOverlappedResult(hFile: THandle; const lpOverlapped: POverlapped;
var lpNumberOfBytesTransferred: DWORD; bWait: BOOL): BOOL; stdcall; external kernel32;
{$define LINE_BREAK} //要不要换行符自己选//要不要分隔符,自己决定
{$define NEED_SPLIT_CHAR}{$ifdef NEED_SPLIT_CHAR}
{$define LINE_BREAK} //分隔符都要了,换行符你就别省了
{$endif}{$ifdef LINE_BREAK}
//{$define LINE_BREAK_UNIX_LIKE} //类Unix的标准当中只有换行0x0a,没有回车0x0d
{$endif}
function DataToText( OffSet: Cardinal (*缓冲区偏移*)
; Data: Cardinal (*当前值*)
; Buffer : PAnsichar (*缓冲区基址*)
):Cardinal;
asm
//保护他人的劳动成果人人有责
push ebx@@LOOP:
BSF EBX, EDX //从右至左取首个有效比特位(即bit=1),结果存入EBX (取值:0..31)
JZ @@RET //如果整个EDX都没有一个bit=1,则ZF标志被设置,别犹豫了,结束吧
BTR EDX, EBX //取走么,自然是真的拿走的啦
ADD EBX, 'A' //转成字母,才更方便查看嘛
{$ifdef NEED_SPLIT_CHAR}
MOV BH, '+' //有人说需要中间的分隔符呢,这个么...不是问题,你想要就给你加上,反正我不要
Mov WORD PTR [ECX + EAX], BX //没啥好说,写到缓冲区保存成果,要不然没有会知道的
ADD EAX, 2 //写了两个字节,自然就要报告两个字节,这个时候不需要谦虚
{$else}
Mov Byte PTR [ECX + EAX], BL //报告,这是组合当中的其中一个元素
Inc EAX //写了一个字节
{$endif}
jmp @@LOOP //还没结束呢,继续吧
@@RET:
{$ifdef NEED_SPLIT_CHAR}
//占用最后一个'+'的位置
{$ifdef LINE_BREAK}
{$ifdef LINE_BREAK_UNIX_LIKE}
MOV Byte PTR [ECX + EAX - 1], $0a
{$else}
MOV Word PTR [ECX + EAX - 1], $0a0d
Inc EAX
{$endif}
{$else}
Dec EAX //吃多了吧,赶紧吐出来
{$endif}
{$else}
{$ifdef LINE_BREAK}
{$ifdef LINE_BREAK_UNIX_LIKE}
MOV Byte PTR [ECX + EAX], $0a
Inc EAX
{$else}
MOV Word PTR [ECX + EAX], $0a0d
ADD EAX, 2
{$endif}
{$endif}
{$endif} //归还他人的劳动成果也是我们应尽的义务
pop ebx
end;var
I:cardinal;
i64Start, i64End, i64Freq : Int64;
D: array of AnsiChar;
L: cardinal;
M, N, E, T: cardinal; OutputFile: THandle;
ovl:OVERLAPPED ;
Size: Cardinal;begin
try
{ TODO -oUser -cConsole Main : Insert code here }
M := 26; //这个不用解释(M <= 32)
L := 512*1024; //预置缓冲区大小(写文件的话,请自行调整) QueryPerformanceFrequency(i64Freq); QueryPerformanceCounter(i64Start); //计时开始 //创建文件
OutputFile:= CreateFile( 'G:\Test.dat',
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ,
nil,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED, (*Overlapped为重叠IO支持,异步写入*)
0);
//常规写法应当要判断OutputFile的值是否为Invalid_Handle_value,即创建文件是否失败
//... fillchar(ovl, sizeof(ovl), 0); //初始化重叠结构
ovl.hEvent := CreateEvent(NIL,true,true,Nil); //异步IO事件通知模式 E := $FFFFFFFF shr (32 - M); //计算个数 //实际缓冲区大小,比预置多分配 (M字节 + (M - 1)个"+" + 0x0a0d回车换行) (这里面只是应大众的使用习惯)
SetLength(D, L + M + (M - 1) + 2); T := 0; //字节数统计 N := 0; //单批写入字节数
for I := 1 to E do begin
N := DataToText(N, I, @D[0]);
if N >= L then begin //缓冲写满,请进行保存N个字节
WriteFile( OutputFile,D[0],N,Size,@ovl); //异步提交一次写操作,正规写法应当判断返回值
WaitForSingleObject(ovl.hEvent,INFINITE); //等待完成事件
GetOverlappedResult( OutputFile, @ovl, Size, true); //取异步操作结果,实际写入字节数
ovl.Offset := ovl.Offset + Size; //设置下一次写入的起始文件偏移
SetFilePointer(OutputFile, Size, NIL, FILE_CURRENT); //设置文件偏移 T := T + N; //这里只做统计
N := 0; //重头开始写入
end;
end;
//如果N > 0,请进行保存N个字节
WriteFile( OutputFile,D[0],N,Size,@ovl);
WaitForSingleObject(ovl.hEvent,INFINITE);
GetOverlappedResult( OutputFile, @ovl, Size, true);
SetFilePointer(OutputFile, Size, NIL, FILE_CURRENT);
SetEndOfFile(OutputFile); //设置文件结尾
closeHandle(ovl.hEvent); //关闭事件句柄
CloseHandle(OutputFile); //关闭文件句柄,释放文件操作权
T := T + N; //这里只做统计 QueryPerformanceCounter(i64End); //计时结束 writeln('总个数:'+IntToStr(E)+' 总字节数:' + IntToStr(T) +' 耗时:' + IntToStr((i64End - i64Start)(*秒*) * 1000 (*毫秒*) * 1000 (*微秒*) div i64Freq (*时钟频率*)) + '微秒'); except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
end.
在你的汇编代码当中,需要注意保护被你使用的常规寄存器,
例如"Function IndexToBuffer(Index : DWORD) : integer;"这个函数当中,只是告诉了编译器你会占用EAX,而实际当中你却使用了ECX和EDX,当启用了编译器的优化功能之后,这个函数就非常危险,因为被无故地修改了ECX和EDX寄存器的内容,就会造成不可预知的后果。而这种代码往往是在调试状态(DEBUG版本)当中所有一切都正常,便是当发布了release版本到客户现场之后,莫名其妙的问题就来了,死循环,内存写异常,程序崩溃无不皆有可能。
[code]生成所有组合对顺序没有要求,即a+b 和 b+a可以当同一条,不用重复出现[/code]
BSF有效减少了循环,直接把Buffer的当前位置传进去当作当前写的地址,避免了Move,大大提高的效率,真棒。 至于ECX,EDX未保护的情况,确实存在问题,不严禁,应该带上在函数定义处,带上assembler关键字即可避免这类情况。
a
ab
abc
...
abc...Zb
bc
bcd
...
bcd...z依次类推算法很简单这样理解对吗?
写硬盘程序运行时间:30秒 (普通机械硬盘)
不写硬盘运行时间:4秒 (仅写入输出缓存)
输出文件大小:895 MB (939,524,095 bytes)(含“,”分隔符)
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hFile = INVALID_HANDLE_VALUE;
char timebuf[20] = {0};
DWORD TimeStart;
DWORD TimeEnd;
DWORD TimeUsed; system("pause");
TimeStart = GetTickCount(); hFile = CreateFileA( "./output.txt",
GENERIC_WRITE|GENERIC_READ,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL); if (INVALID_HANDLE_VALUE == hFile)
return FALSE; for (DWORD i=1; i<67108864; i++)
PrintStr(i, hFile);
CloseHandle(hFile); TimeEnd = GetTickCount();
TimeUsed = TimeEnd - TimeStart;
printf("67108863 records, time costs: %ld(ms)\n", TimeUsed);
system("pause"); return 0;
}void PrintStr(DWORD n, HANDLE hFile)
{
/* 26 bits for a ~ z: | 8bits | 8bits | 8bits | 8bits |
|------00|00000000|00000000|00000000|
| zy|xwvutsrq|ponmlkji|hgfedcba| a ~ z: 97 ~ 122 */ static char buf[28*1024*1024] = {0}; //28mb
static int datalen = 0; DWORD temp = 1;
char ch = 'a'; for (int i=0; i<26; i++)
{
if (n & temp)
buf[datalen++] = ch; ch++;
temp = temp << 1;
} buf[datalen++] = ','; if ((datalen > (28*1024*1024 - 28)) || 67108863 == n)
{
DWORD wtlen = 0;
WriteFile(hFile, buf, datalen, &wtlen, 0);
memset(buf, 0, sizeof(buf));
datalen = 0;
}
}
运行时间:30秒 (写入硬盘文件) 文件大小:895 MB (939,524,095 bytes)含“,”分隔符
运行时间:4秒 (不写硬盘只写入输出缓存)
void PrintStr(DWORD n, HANDLE hFile);int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hFile = INVALID_HANDLE_VALUE;
char timebuf[20] = {0};
DWORD TimeStart;
DWORD TimeEnd;
DWORD TimeUsed; system("pause");
TimeStart = GetTickCount(); hFile = CreateFileA( "./output.txt",
GENERIC_WRITE|GENERIC_READ,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL); if (INVALID_HANDLE_VALUE == hFile)
return FALSE; for (DWORD i=1; i<67108864; i++)
PrintStr(i, hFile);
CloseHandle(hFile); TimeEnd = GetTickCount();
TimeUsed = TimeEnd - TimeStart;
printf("67108863 records, time costs: %ld(ms)\n", TimeUsed);
system("pause"); return 0;
}void PrintStr(DWORD n, HANDLE hFile)
{
/* 26 bits for a ~ z: | 8bits | 8bits | 8bits | 8bits |
|------00|00000000|00000000|00000000|
| zy|xwvutsrq|ponmlkji|hgfedcba| a ~ z: 97 ~ 122 */ static char buf[28*1024*1024] = {0}; //28mb
static int datalen = 0; DWORD temp = 1;
char ch = 'a'; for (int i=0; i<26; i++)
{
if (n & temp)
buf[datalen++] = ch; ch++;
temp = temp << 1;
} buf[datalen++] = ','; if ((datalen > (28*1024*1024 - 28)) || 67108863 == n)
{
DWORD wtlen = 0;
WriteFile(hFile, buf, datalen, &wtlen, 0);
memset(buf, 0, sizeof(buf));
datalen = 0;
}
}
运行时间:30秒 (写入硬盘文件) 文件大小:895 MB (939,524,095 bytes)含“,”分隔符
运行时间:4秒 (不写硬盘只写入输出缓存)
void PrintStr(DWORD n, HANDLE hFile);int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hFile = INVALID_HANDLE_VALUE;
char timebuf[20] = {0};
DWORD TimeStart;
DWORD TimeEnd;
DWORD TimeUsed; system("pause");
TimeStart = GetTickCount(); hFile = CreateFileA( "./output.txt",
GENERIC_WRITE|GENERIC_READ,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL); if (INVALID_HANDLE_VALUE == hFile)
return FALSE; for (DWORD i=1; i<67108864; i++)
PrintStr(i, hFile);
CloseHandle(hFile); TimeEnd = GetTickCount();
TimeUsed = TimeEnd - TimeStart;
printf("67108863 records, time costs: %ld(ms)\n", TimeUsed);
system("pause"); return 0;
}void PrintStr(DWORD n, HANDLE hFile)
{
/* 26 bits for a ~ z: | 8bits | 8bits | 8bits | 8bits |
|------00|00000000|00000000|00000000|
| zy|xwvutsrq|ponmlkji|hgfedcba| a ~ z: 97 ~ 122 */ static char buf[28*1024*1024] = {0}; //28mb
static int datalen = 0; DWORD temp = 1;
char ch = 'a'; for (int i=0; i<26; i++)
{
if (n & temp)
buf[datalen++] = ch; ch++;
temp = temp << 1;
} buf[datalen++] = ','; if ((datalen > (28*1024*1024 - 28)) || 67108863 == n)
{
DWORD wtlen = 0;
WriteFile(hFile, buf, datalen, &wtlen, 0);
memset(buf, 0, sizeof(buf));
datalen = 0;
}
}
规模为1时,有两种组合:null, a
规模为2时,在原有组合基础上增加b: b, a+b
再加上原有组合,所有排列为(null,a,b,a+b)
规模为3时,在原有组合上增加c: c, a+c, b+c, a+b+c
再加上原有组合,所有排列为 (null,a,b,a+b,c,a+c,b+c,a+b+c)
...
这个问题实际上是一个等比数列,设f(1)=2, f(n)=2*f(n-1),如果不计算空,最后结果减1即可,通项为2^n-1。
按照上述步骤一次性遍历所有结果,无任何多余操作,我就不信还有人能找出比这个更快的算法。
if (n & temp)
buf[datalen++] = ch;
...
//代码在这里用得比较巧妙...
二进制-->逆序-->找出值为1的位对应的字母
1-->1-->A 10-->01-->B 11-->11-->AB
100-->001-->C 101-->101-->AC 110-->011-->BC
111-->111-->ABCJAVA实现:
public class Thr{
public static void main(String[] args) {
System.out.println("总计" + ((1 << 26)-1)+"种组合");
char[] ch = {'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z'};
int n = (1<<ch.length)-1;
int i = 0;
StringBuffer sb = new StringBuffer();
while(i++ < n){
String revBinStr = sb.append(Integer.toBinaryString(i))
.reverse().toString();//逆序二进制字符串
create(ch,revBinStr);
sb.delete(0,revBinStr.length());
System.out.println();//换行
}
}
//找出值为1的位的下标,输出ch中对应该下标的
public static void create(char[] ch,String revBinStr ){
int currentIndex = 0;
for(int x = 0; x < ch.length; ){
currentIndex = revBinStr.indexOf("1",x);
if(currentIndex != -1 ){
System.out.print(ch[currentIndex]);
x = currentIndex + 1;
}else{
break;
}
}
}
}