| 218.25.35.* |
1楼 |
|
|
- 共有22篇贴子
| 219.134.101.* |
2楼 编了一个很菜的程序: 首先建立"原文.txt" "加密.txt"两个文件,在"原文.txt" 中输入要加密的字符300以内 从主函数注明的接口处可以再随意加入自己的加密函数, 全局变量abc[300]中存放这些字符,tt是这些字符的个数。 */ #include <stdio.h> int tt=0; //这一行字符个数 char abc[300]; //存放这行字符 #define password 1234 //密码 /*******************************/ void txt_r_and_w(int ii) //对文件读写 {char ff; int i=0; if(ii==1) { FILE *ffile=fopen("原文.txt","r"); aa: ff=fgetc(ffile); if(ff!='\n'&&ff!=EOF&&i!=300&&ff!='\0') {abc[i++]=ff; goto aa; } tt=i; fclose(ffile); } if(ii==0) { FILE *ffile=fopen("加密.txt","r"); aab: ff=fgetc(ffile); if(ff!='\n'&&ff!=EOF&&i!=300&&ff!='\0') {abc[i++]=ff; goto aab; } tt=i; fclose(ffile); } if(ii==3) { FILE *ffile=fopen("加密.txt","w"); for(i=0;i<tt;i++) fprintf(ffile,"%c",abc[i]); fclose(ffile); } if(ii==2) { FILE *ffile=fopen("解密.txt","w"); for(i=0;i<tt;i++) fprintf(ffile,"%c",abc[i]); fclose(ffile); } } /*******************************/ void to_a(int i) {int j=0,k=0;char n; if(i==1) { ta1: j=k*3; //逢3位全部前移到最前面 if(j<tt) {n=abc[j];abc[j]=abc[k];abc[k]=n;k++;goto ta1;} } //解密 if(i==0) {k=tt/3; ta0: j=k*3; if(k>0) {n=abc[j];abc[j]=abc[k];abc[k]=n;k--;goto ta0;} } } /*******************************/ void to_b(int i) {int j=1,k=1;char n; if(i==1) { tb1: if(j%2!=0&&j<tt) //所有奇数位ASCII加13 {abc[j]+=13;j+=2; goto tb1; } if(j%2==0&&j<tt) {j+=2; goto tb1;} } if(i==0) //解密 { tb0: if(j%2!=0&&j<tt) {abc[j]-=13; j+=2; goto tb0; } if(j%2==0&&j<tt) {j+=2; goto tb0;} } } /*******************************/ //用一个数列的值对数组进行交叉换位 void to_c(int i) {int j=0,jj=0,k=0,sun[100],m=0;char n; if(i==1) {j=1; tc1: sun[0]=1;sun[1]=2; //定义一个数列sun[i]=sun[i-1]+i;,以增加破解的难度。 for(jj=2;jj<101;jj++) sun[jj]=sun[jj-1]+jj; if(sun[j]<=tt&&sun[j-1]<=tt&&j<100) {n=abc[sun[j]];abc[sun[j]]=abc[sun[j-1]]; abc[sun[j-1]]=n; j++; goto tc1; } else if(sun[j]>tt&&sun[j-1]>tt&&j<100) {sun[j]%=tt;sun[j-1]%=tt; n=abc[sun[j]]; abc[sun[j]]=abc[sun[j-1]];abc[sun[j-1]]=n;j++;goto tc1; } else if(sun[j]>tt&&sun[j-1]<tt&&j<100||sun[j]<tt&&sun[j-1]>tt&&j<100) {j++;goto tc1; } } if(i==0) //解密 {j=99; tc0: sun[0]=1;sun[1]=2; for(jj=2;jj<101;jj++) sun[jj]=sun[jj-1]+jj; if(sun[j]<=tt&&sun[j-1]<=tt&&j>0) {n=abc[sun[j]];abc[sun[j]]=abc[sun[j-1]]; abc[sun[j-1]]=n;j--;goto tc0; } else if(sun[j]>tt&&sun[j-1]>tt&&j>0) {sun[j]%=tt;sun[j-1]%=tt; n=abc[sun[j]]; abc[sun[j]]=abc[sun[j-1]];abc[sun[j-1]]=n;j--;goto tc0; } else if(sun[j]>tt&&sun[j-1]<tt&&j>0||sun[j]<tt&&sun[j-1]>tt&&j>0) {j--; goto tc0; } } } /*******************************/ int main() { int i=0,kk=0,k; abcd: printf("请输入密码:\n"); scanf("%d",&k); if(k==password) { bb: printf("加密请按1,解密请按0,并回车\n"); scanf("%d",&k); if(k==1) //加密接口 { txt_r_and_w(k); to_a(k); to_b(k); to_c(k); txt_r_and_w(3); printf("加密已完成\n"); } else if(k==0) //解密接口 dd:{ txt_r_and_w(k); to_c(k); to_b(k); to_a(k); txt_r_and_w(2); printf("解密已完成\n"); kk=1; }else goto bb; if(k==1&&kk==0) { printf("\n\n\n\n如要解密请按0,退出请按1,并回车\n"); scanf("%d",&kk); if(kk==0) goto dd; } }else goto abcd; return 0; } |
|
|
| 219.134.101.* |
4楼 另求助高手一个问题: 有一个“*.txt”文件中存放500万组数,每组由14个int型数据组成,找出其相同的组并统计其出现的次数,要求在尽可能短的时间内能算完,我头都大了,救救我吧,能在15分钟内算出结果就算成功了 |
|
|
| 219.134.101.* |
5楼 |
|
|
|
6楼 比较大量的操作,最好用链表并先排序,并且在排序的同时进行统计,若相同就不执行插入操作而仅仅计数加1;否则再插入,这样如果数据重复多的话应该可以避免很多次比较 排序的方法,感觉就用折半查找就行,再想快的话,可以多分几组。 具体试验一下看看再说 |
|
|
|
| 219.134.101.* |
7楼 1.第2个函数改成: /*******************************/ void to_a(int i) {int j=0,k=0;char n; if(i==1) { ta1: j=k*3; //逢3位全部前移到最前面 if(j<tt) {n=abc[j];abc[j]=abc[k];abc[k]=n;k++;goto ta1;} } //解密 if(i==0) {k=tt/3; ta0: j=k*3; if(k>0&&j<tt) {n=abc[j];abc[j]=abc[k];abc[k]=n;k--;goto ta0;} if(k>0&&j>=tt) {k--;goto ta0;}//********加上这一行 } } /*******************************/ 2.第4个函数第二行改成: /********************/ //用一个数列的值对数组进行交叉换位 void to_c(int i) {int j=0,jj=0,k=0,sun[110],m=0;char n; //改成sun[110] 3.主函数的倒数第6、5行的kk改成k: scanf("%d",&k); if(k==0) goto dd; |
|
|
| 219.134.101.* |
8楼 |
|
|
| 219.134.101.* |
9楼 |
|
|
|
10楼 http://post.baidu.com/f?kz=4201196 如果是500万组数,每组14个整数,那就应该是 5M*14*4=280M字节 很可观了,呵呵, |
|
|
|
|
11楼 VC99已经算出需要的内存数了。280M。这个数字在32位系统里,是很小的。物理内存+虚拟内存,使得基本上每一个系统都能申请到这么多的内存(C用MALLOC,C++用NEW)。 既然系统支持这么多内存,那我们当然要用空间换取速度,来尽快完成这个问题。 由于每组是14个INT型(4字节),没办法直接进行数学运算(14×4=56字节,现在32位机子上的编译器,绝大部分都只能支持到8字节64位)。我们应该用另外的方法来实现。 1、我第一反应,就是用二叉树。不过仔细想了想,好像没办法完成。 换思路。用HASH。不过C语言没有系统可用的HASH函数。得自己去找或者自己写一个。我基本上没研究过HASH函数,对这个了解不是很多,不知道有哪些开源库可用。VC99对这个有过研究,可以提供一些吗?8PM对开源库很熟悉,也许也能提供一些帮助。 如果用C++,那就方便了。因为C++提供了HASH函数。在这里用std::map最方便。构造一个:std::map< int, std::map< int, std::map< ...(共14级)>>>>>>>>>>>>>>(我不知道能不能构造成功。呵呵,从来没试过,刚才试了一下,3级的时候,是没问题的) 用HASH,速度就会很有保障。伪代码如下: (1)、构造14个HASH表(暂时为空) (2)、读取一组数 (3)、把每一个数放入HASH函数中,在当前HASH表中查询,如果出现过,则按分支继续比较下一个数 (4)、如果没出现过,则在当前HASH表中添加一个新的分枝,并把该组中剩下的数逐个添加到这个分枝中。 (5)、比较完14组,如果都出现过,则对应的HASH值+1。 2、用链表 这个实现起来比较简单,唯一的缺点是,每次比较的速度会慢一些。伪代码如下: (1)、构造一个链表,共14级(暂时为空)。链表的结构大致如下: struct link{ int num; int times;//计算次数。但是只有最后一级的数字才需要。实际可以构造两种不同的链表。 struct * link same_level;//用于链接当前级别下所有出现的链表。每一个不同的数出现,都要构造一个新链表,并链接上。 struct * link next_level;//用于链接下一级别,这个总共有14级,表示14个数,共一组 }; (2)、读取一组数 (3)、比较每一级数,如果有了,继续比下一级(比起HASH,速度就慢在这里) (4)、如果没有,则在当前链表下创建一个新的分枝,并把该组下的所有数都放进去。 (5)、比较完14级的数,如果都出现过,则最后一个数的times+1。表示出现过一次了。 3、用数组 每出现一组不同的数,就malloc一个新的int [14]数组,用来保存这个数。 这些所有的int [14]数组,要用一个链表来链接。链表结构如下: struct link{ int num[14]; int times; struct link* next; } 这个方法比前一种还要慢一些,因为每次都要比较很多很多次数。但更容易实现。好像它需要的内存要比前两个少得多。 4、用大数运算库。 把这14个数看成一个56字节的数,用大数运算库进行比较(或者可以结合HASH,速度会提高一点)。 特点:最容易实现,哈哈,基本上不需要什么脑筋。 但速度……估计…… |
|
|
|
|
12楼 再用hash函数。 如果可能,也许它反而会是最好的选择:最容易实现,速度也不会慢。 |
|
|
|
| 219.145.154.* |
16楼 |
|
|
|
17楼 |
|
|
|
|
18楼 |
|
|
|
| 59.62.10.* |
20楼 |
|
|
|
21楼 |
|
|
|
| 125.71.28.* |
22楼 file fgetc.c line 41 expression stream!=NULL 什么意思哦 晓得的说下。谢谢 |
|
|
| 58.45.191.* |
23楼 |
|
|
