}
else
{
cout<<'-'; //小于就输出负号
for(i=1;i<=b[0];i++) //做按位减,大的减小的
{b[i]-=a[i];
if(b[i]<0){b[i+1]--;b[i]+=10;}
}
b[0]++;
while((b[b[0]]==0)&&(b[0]>1))b[0]--;
for(i=b[0];i>=1;i--)
cout<
cout< }
return0;
}
intcompare(strings1,strings2) //比较字符串(两个数)数字的大小,大于等于返回0,小于返回1。
{
if(s1.length()>s2.length())return0; //先比较长度,哪个字符串长,对应的那个数就大
if(s1.length() for(inti=0;i<=s1.length();i++) //长度相同时,就一位一位比较。
{
if(s1[i]>s2[i])return0;
if(s1[i] }
return0; //如果长度相同,每一位也一样,就返回0,说明相等
}
做减法时,首先要判断两个字符串的大小,决定是否输出负号,然后就是按位减法,注意处理借位。
八、高精度乘法
#include
#include
usingnamespacestd;
intmain()
{
stringstr1,str2;
inta[250],b[250],c[500],len; //250位以内的两个数相乘
inti,j;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
cin>>str1>>str2;
a[0]=str1.length();
for(i=1;i<=a[0];i++)
a[i]=str1[a[0]-i]-'0';
b[0]=str2.length();
for(i=1;i<=b[0];i++)
b[i]=str2[b[0]-i]-'0';
memset(c,0,sizeof(c));
for(i=1;i<=a[0];i++) //做按位乘法同时处理进位,注意循环内语句的写法。
for(j=1;j<=b[0];j++)
{
c[i+j-1]+=a[i]*b[j];
c[i+j]+=c[i+j-1]/10;
c[i+j-1]%=10;
}
len=a[0]+b[0]+1; //去掉最高位的0,然后输出
while((c[len]==0)&&(len>1))len--; //为什么此处要len>1?
?
for(i=len;i>=1;i--)
cout< return0;
}
注意:
两个数相乘,结果的位数应该是这两个数的位数和减1。
优化:
万进制
#include
#include
usingnamespacestd;
voidnum1(ints[],stringst1);
inta[2501],b[2501],c[5002];//此处可以进行2500位万进制乘法,即10000位十进制乘法。
Intmain()
{
stringstr1,str2;
intlen;
cin>>str1>>str2;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
num1(a,str1);//把str1从最低位开始,每4位存放在数组a中
num1(b,str2);//把str2从最低位开始,每4位存放在数组b中
for(inti=1;i<=a[0];i++)//作按位乘法并处理进位,此处是万进制进位
for(intj=1;j<=b[0];j++)
{
c[i+j-1]+=a[i]*b[j];
c[i+j]+=c[i+j-1]/10000;
c[i+j-1]%=10000;
}
len=a[0]+b[0];//a[0]和b[0]存放的是每个数按4位处理的位数
while((c[len]==0)&&(len>1))len--;//去掉高位的0,并输出最高位
cout< for(inti=len-1;i>=1;i--)//把剩下来的每一位还原成4位输出
{
if(c[i]<1000)cout<<’0’;
if(c[i]<100)cout<<’0’;
if(c[i]<10)cout<<’0’;
cout< }
cout< return0;
}
voidnum1(ints[],stringst1)//此函数的作用就是把字符串st1,按4位一组存放在数组s中
{ intk=1,count=1;
s[0]=st1.length();//存放st1的长度,省去一长度变量
for(inti=s[0]-1;i>=0;i--)//从最低位开始,处理每一位
{if(count%4==0){s[k]+=(st1[i]-‘0’)*1000;if(i!
=0)k++;}
if(count%4==1)s[k]=(st1[i]-‘0’);
if(count%4==2)s[k]+=(st1[i]-‘0’)*10;
if(count%4==3)s[k]+=(st1[i]-‘0’)*100;
count++;
}
s[0]=k;//存放数组的位数,就是按4位处理后的万进制数的位数。
Return;
}
九、高精度除法(没讲)
十、筛选法建立素数表
voidmaketable(intx)//建立X以内的素数表prim,prim[i]为0,表示i为素数,为1表示不是质数
{
memset(prim,0,sizeof(prim));//初始化质数表
prim[0]=1;prim[1]=1;prim[2]=0;//用筛选法求X以内的质数表
for(inti=2;i<=x;i++)
if(prim[i]==0)
{intj=2*i;
while(j<=x)
{prim[j]=1;j=j+i;}
}
}
对于那些算法中,经常要判断素数的问题,建立一个素数表,可以达到一劳永逸的目的。
十一、深度优先搜索
voiddfs(intx) \\以图的深度优先遍历为例。
{
cout< visited[x]=1;\\作已访问的标记
for(intk=1;k<=n;k++)\\对与顶点x相邻而又没访问过的结点k进行深度优先搜索。
if((a[x][k]==1)&&(visited[k]==0))
dfs(k);
}
十二、广度优先搜索
void bfs(void)//按广度优先非递归遍历图G,n个顶点,编号为1..n。
注:
图不一定是连通的
{//使用辅助队列Q和访问标记数组visited。
for(v=1;v<=n;v++) visited[v]=0;//标记数组初始化
for(v=1;v<=n;v++)
if(visited[v]==0){ //v尚未访问
inth=1,r=1; //置空的辅助队列q
visited[v]=1;//顶点v,作访问标记
cout< q[r]=v; //v入队列
while(h<=r)//当队列非空时循环
{
inttmp=q[h]; //队头元素出队,并赋值给tmp
for(intj=1;j<=n;j++)
if((visited[j]==0)&&(a[tmp][j]==1))
{//j为tmp的尚未访问的邻接顶点
visited[j]=1; 对j作访问标记
cout< r++;//队尾指针加1
q[r]=j;//j入队
} //end-if
h++;
}//end-while
}
十三、二叉树的前序、中序和后序遍历
voidpreorder(intx)//二叉树的先序遍历
{
if(x==0)return;
cout< preorder(a[x].ld);//再先序遍历根的左子树
preorder(a[x].rd);//最后先序遍历根的右子树
}
voidinorder(intx)//二叉树的中序遍历
{
if(x==0)return;
preorder(a[x].ld);//先中序遍历根的左子树
cout< preorder(a[x].rd);//最后中序遍历根的右子树
}
voidreorder(intx)//二叉树的后序遍历
{
if(x==0)return;
preorder(a[x].ld);//先后序遍历根的左子树
preorder(a[x].rd);//再后序遍历根的右子树
cout<}
十四、树转换为二叉树算法
十五、二叉排序树
十六、哈夫曼树
voidhaff(void)//构建哈夫曼树
{
for(inti=n+1;i<=2*n-1;i++)//依次生成n-1个结点
{intl=fmin(i-1);//查找权值最小的结点的编号l
a[i].lchild=l;//把l作为结点i的左孩子
a[l].father=i;//把l的父结点修改为i
intr=fmin(i-1);//查找次小权值的编号r
a[i].rchild=r;//把l作为结点i的右孩子
a[r].father=i;//把r的父结点修改为i
a[i].da=a[l].da+a[r].da;//合并l,j结点,生成新结点i
}
}
intfmin(intk)//在1到K中寻找最小的权值的编号
{
intmins=0;
for(ints=1;s<=k;s++)
if((a[mins].da>a[s].da)&&(a[s].father==0))//a[s].father=0,说明这个结点还不是别个结点
mins=s; //的孩子,不等于0说明这个结点已经用过。
returnmins;
}
voidinorder(intx)//递归生成哈夫曼编码
{
if(a[x].father==0){a[x].code=”“;}//根结点
if(a[a[x].father].lchild==x) a[x].code=a[a[x].father].code+'0';
if(a[a[x].father].rchild==x) a[x].code=a[a[x].father].code+'1';
if(a[x].lchild!
=0)inorder(a[x].lchild);//递归生成左子树
if((a[x].lchild==0)&&(a[x].rchild==0))//输出叶子结点
cout<'< if(a[x].rchild!
=0)inorder(a[x].rchild);//递归生成右子树
}
十七、并查集
intgetfather(intx)//非递归求X结点的根结点的编号
{while(x!
=father[x])
x=father[x];
returnx;
}
intgetfather(intx)//递归求X结点的根结点的编号
{if(x==father[x])returnx;
el