⑴ 怎样用C语言实现FFT算法啊
1、二维FFT相当于对行和列分别进行一维FFT运算。具体的实现办法如下:
先对各行逐一进行一维FFT,然后再对变换后的新矩阵的各列逐一进行一维FFT。相应的伪代码如下所示:
for (int i=0; i<M; i++)
FFT_1D(ROW[i],N);
for (int j=0; j<N; j++)
FFT_1D(COL[j],M);
其中,ROW[i]表示矩阵的第i行。注意这只是一个简单的记法,并不能完全照抄。还需要通过一些语句来生成各行的数据。同理,COL[i]是对矩阵的第i列的一种简单表示方法。
所以,关键是一维FFT算法的实现。
2、例程:
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#defineN1000
/*定义复数类型*/
typedefstruct{
doublereal;
doubleimg;
}complex;
complexx[N],*W;/*输入序列,变换核*/
intsize_x=0;/*输入序列的大小,在本程序中仅限2的次幂*/
doublePI;/*圆周率*/
voidfft();/*快速傅里叶变换*/
voidinitW();/*初始化变换核*/
voidchange();/*变址*/
voidadd(complex,complex,complex*);/*复数加法*/
voidmul(complex,complex,complex*);/*复数乘法*/
voidsub(complex,complex,complex*);/*复数减法*/
voidoutput();
intmain(){
inti;/*输出结果*/
system("cls");
PI=atan(1)*4;
printf("Pleaseinputthesizeofx: ");
scanf("%d",&size_x);
printf("Pleaseinputthedatainx[N]: ");
for(i=0;i<size_x;i++)
scanf("%lf%lf",&x[i].real,&x[i].img);
initW();
fft();
output();
return0;
}
/*快速傅里叶变换*/
voidfft(){
inti=0,j=0,k=0,l=0;
complexup,down,proct;
change();
for(i=0;i<log(size_x)/log(2);i++){/*一级蝶形运算*/
l=1<<i;
for(j=0;j<size_x;j+=2*l){/*一组蝶形运算*/
for(k=0;k<l;k++){/*一个蝶形运算*/
mul(x[j+k+l],W[size_x*k/2/l],&proct);
add(x[j+k],proct,&up);
sub(x[j+k],proct,&down);
x[j+k]=up;
x[j+k+l]=down;
}
}
}
}
/*初始化变换核*/
voidinitW(){
inti;
W=(complex*)malloc(sizeof(complex)*size_x);
for(i=0;i<size_x;i++){
W[i].real=cos(2*PI/size_x*i);
W[i].img=-1*sin(2*PI/size_x*i);
}
}
/*变址计算,将x(n)码位倒置*/
voidchange(){
complextemp;
unsignedshorti=0,j=0,k=0;
doublet;
for(i=0;i<size_x;i++){
k=i;j=0;
t=(log(size_x)/log(2));
while((t--)>0){
j=j<<1;
j|=(k&1);
k=k>>1;
}
if(j>i){
temp=x[i];
x[i]=x[j];
x[j]=temp;
}
}
}
/*输出傅里叶变换的结果*/
voidoutput(){
inti;
printf("Theresultareasfollows ");
for(i=0;i<size_x;i++){
printf("%.4f",x[i].real);
if(x[i].img>=0.0001)printf("+%.4fj ",x[i].img);
elseif(fabs(x[i].img)<0.0001)printf(" ");
elseprintf("%.4fj ",x[i].img);
}
}
voidadd(complexa,complexb,complex*c){
c->real=a.real+b.real;
c->img=a.img+b.img;
}
voidmul(complexa,complexb,complex*c){
c->real=a.real*b.real-a.img*b.img;
c->img=a.real*b.img+a.img*b.real;
}
voidsub(complexa,complexb,complex*c){
c->real=a.real-b.real;
c->img=a.img-b.img;
}
⑵ 算法编程:用c语言实现
解决这类问题可以使用 回溯 算法,代码如下:
#include<stdio.h>
#include<stdlib.h>
#defineM6//候选数字个数
#defineN5//组合后数字位数
intcheck(intresult[],inti)
{
for(intj=0;j<N;j++)
if(result[j]==i)
return0;
return1;
}
intlist(intnumbers[],intl,intresult[],intcount)
{
if(l>=N){
//将各位数组合成一个数
intnum=0;
for(inti=0;i<N;i++){
num=num*10+numbers[result[i]];
}
//判断这个数是否能被75整除
if(num%75==0){
printf("%d ",num);
count++;
}
returncount;
}
for(inti=0;i<M;i++){
if(!check(result,i)){
continue;
}
result[l]=i;
count=list(numbers,l+1,result,count);
result[l]=-1;
}
returncount;
}
intmain()
{
intnumbers[M]={1,2,5,7,8,9};
intresult[N]={-1,-1,-1,-1,-1};
intcount=list(numbers,0,result,0);
printf("共有%d个 ",count);
system("pause");
return0;
}
运行结果:
⑶ 用C语言编写一个对称加密算法,对字符串加密
/*本问题的关键是如何交换ASCII的二进制位,下面提供简短算法,并附上VC++6.0环境下的运行结果截图。
*/
#include<stdio.h>
charswapbit(charc){
chari,num=0,ch[8];
for(i=0;i<8;i++){
ch[i]=c&1;
c=(c>>1);
}
for(i=0;i<8;i++){
num=2*num+ch[i];
}
returnnum;
}
intmain(){
charch;
for(ch='A';ch<='Z';ch++){
printf("%c=%X:%X ",ch,ch,0XFF&swapbit(ch));
}
return0;
}
⑷ 用c语言写算法
直接手写
size_t lenT, lenP, lenS;
char *e;
if ( !T || !P || !S ) return;
e = strstr( T, P );
if ( !e ) return;
lenT = strlen( T );
lenP = strlen( P );
lenS = strlen( S );
memmove( e+lenS, e+lenP, lenT+1-(e-T)-lenP );
memcpy( e, s, lenS );
假定三个长度 t、p、s 。
strstr: O(t*p)
strlen*3: O(t+p+s)
memmove: O(t-p)
memcpy:O(s)
最终复杂度 O(t*p+2(t+s)) -> O(n^2)。
可以看出热点在 strstr 函数。
如果将其通过 kmp 或类似的匹配算法优化成 O(n) 的,那么复杂度可以直接降为 O(n) 。