注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

秋雨冬雪NO1

互联网资源收集

 
 
 

日志

 
 

经典c++编程代码实例  

2012-04-25 09:08:11|  分类: 代码大全 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

一.冒泡法:
这是最原始,也是众所周知的最慢的算法了。他的名字的由来因为它的工作看来象是冒泡:
#include <iostream.h>

void BubbleSort(int* pData,int Count)
{
    int iTemp;
    for(int i=1;i<Count;i++)
    {
        for(int j=Count-1;j>=i;j--)
        {
            if(pData[j]<pData[j-1])
            {
                iTemp = pData[j-1];
                pData[j-1] = pData[j];
                pData[j] = iTemp;
            }
        }
    }
}

void main()
{
    int data[] = {10,9,8,7,6,5,4};
    BubbleSort(data,7);
    for (int i=0;i<7;i++)
        cout<<data[i]<<" ";
    cout<<"\n";
}
图示: before_compare|one_turn|two_turn|three_turn|four_turn|five_turn|six_turn         10        10        10        10        10          10    4                      9         9         9         9         9           4    10          8         8         8         8         4           9    9          7         7         7         4         8           8    8          6         6         4         7         7           7    7          5         4         6         6         6           6    6          4         5         5         5         5           5    5通过上图可以看出,冒泡法形象的描述来,4这个元素就像一个气泡逐渐冒到上面来了。 我们排序的有7个元素,最坏的情况全部倒序,4这个元素要冒上来需要6次。因此,n个元素,最坏的情况,需要移动:1+2+3+ ...+(n-1)=1/2*n(n-1)次。倒序(最糟情况)
第一轮:10,9,8,7->10,9,7,8->10,7,9,8->7,10,9,8(交换3次)
第二轮:7,10,9,8->7,10,8,9->7,8,10,9(交换2次)
第一轮:7,8,10,9->7,8,9,10(交换1次)
循环次数:6次
交换次数:6次

其他:
第一轮:8,10,7,9->8,10,7,9->8,7,10,9->7,8,10,9(交换2次)
第二轮:7,8,10,9->7,8,10,9->7,8,10,9(交换0次)
第一轮:7,8,10,9->7,8,9,10(交换1次)
循环次数:6次
交换次数:3次

上面我们给出了程序段,现在我们分析它:这里,影响我们算法性能的主要部分是循环和交换,显然,次数越多,性能就越差。从上面的程序我们可以看出循环的次数是固定的,为1+2+...+n-1。写成公式就是1/2*(n-1)*n。现在注意,我们给出O方法的定义:

    若存在一常量K和起点n0,使当n>=n0时,有f(n)<=K*g(n),则f(n) = O(g(n))。(呵呵,不要说没学好数学呀,对于编程数学是非常重要的!!!)

现在我们来看1/2*(n-1)*n,当K=1/2,n0=1,g(n)=n*n时,1/2*(n-1)*n<=1/2*n*n=K*g(n)。所以f(n)=O(g(n))=O(n*n)。所以我们程序循环的复杂度为O(n*n)。
    再看交换。从程序后面所跟的表可以看到,两种情况的循环相同,交换不同。其实交换本身同数据源的有序程度有极大的关系,当数据处于倒序的情况时,交换次数同循环一样(每次循环判断都会交换),复杂度为O(n*n)。当数据为正序,将不会有交换。复杂度为O(0)。乱序时处于中间状态。正是由于这样的原因,我们通常都是通过循环次数来对比算法。2.交换法:
交换法的程序最清晰简单,每次用当前的元素一一的同其后的元素比较并交换。
#include <iostream.h>
void ExchangeSort(int* pData,int Count)
{
    int iTemp;
    for(int i=0;i<Count-1;i++)
    {
        for(int j=i+1;j<Count;j++)
        {
            if(pData[j]<pData[i])
            {
                iTemp = pData[i];
                pData[i] = pData[j];
                pData[j] = iTemp;
            }
        }
    }
}

void main()
{
    int data[] = {10,9,8,7,6,5,4};
    ExchangeSort(data,7);
    for (int i=0;i<7;i++)
        cout<<data[i]<<" ";
    cout<<"\n";
} before_compare|one_turn|two_turn|three_turn|four_turn|five_turn|six_turn         10         9         8         7         6           5     4                      9        10        10         10       10           10    10          8         8         9         9         9           9     9          7         7         7         8         8           8     8          6         6         6         6         7           7     7          5         5         5         5      5        6   6          4         4         4         4         4           4     5 从上面的算法来看,基本和冒泡法的效率一样。
倒序(最糟情况)
第一轮:10,9,8,7->9,10,8,7->8,10,9,7->7,10,9,8(交换3次)
第二轮:7,10,9,8->7,9,10,8->7,8,10,9(交换2次)
第一轮:7,8,10,9->7,8,9,10(交换1次)
循环次数:6次
交换次数:6次

其他:
第一轮:8,10,7,9->8,10,7,9->7,10,8,9->7,10,8,9(交换1次)
第二轮:7,10,8,9->7,8,10,9->7,8,10,9(交换1次)
第一轮:7,8,10,9->7,8,9,10(交换1次)
循环次数:6次
交换次数:3次

从运行的表格来看,交换几乎和冒泡一样糟。事实确实如此。循环次数和冒泡一样也是1/2*(n-1)*n,所以算法的复杂度仍然是O(n*n)。由于我们无法给出所有的情况,所以只能直接告诉大家他们在交换上面也是一样的糟糕(在某些情况下稍好,在某些情况下稍差)。3.选择法:
现在我们终于可以看到一点希望:选择法,这种方法提高了一点性能(某些情况下)这种方法类似我们人为的排序习惯:从数据中选择最小的同第一个值交换,在从省下的部分中选择最小的与第二个交换,这样往复下去。
#include <iostream.h>
void SelectSort(int* pData,int Count)
{
    int iTemp;
    int iPos;
    for(int i=0;i<Count-1;i++)
    {
        iTemp = pData[i];
        iPos = i;
        for(int j=i+1;j<Count;j++)
        {
            if(pData[j]<iTemp)
            {
                iTemp = pData[j];
                iPos = j;
            }
        }
        pData[iPos] = pData[i];
        pData[i] = iTemp;
    }
}

void main()
{
    int data[] = {10,9,8,7,6,5,4};
    SelectSort(data,7);
    for (int i=0;i<7;i++)
        cout<<data[i]<<" ";
    cout<<"\n";
}该排序法的图示如下;   i=0时:  iTemp = pData[0]=10;iPos = i=0;
         j=1 ;
            pData[j]<iTemp ---> pData[1]=9<10;
            iTemp=pData[1]=9;
            ipos=j=1;
            j++=2
         j=2;
            pData[j]<iTemp----> pData[2]=8<9;
            iTemp=pData[2]=8;
            ipos=j=2;
            j++=3
         . . .
         j=6;
            pData[j]<iTemp----> pData[6]=4<5;
            iTemp=pData[6]=4;
            ipos=j=6;
            j++=7;
        pData[6]=Pdata[0];
        pData[0]=4;   
       
before_compare one turn two turn three turn
10  4  4  4
9  9  5  5
8  8  8  6
7  7  7  7
6  6  6  8
5  5  9  9
4  10  10  10由上面可以看到选择排序法并没有在一开始就交换数据,而是用第一个数据去和所有的数据比较,如果第一个数据小于第二个数据,那么,先把第二个数据放到一个临时变量里面,同时记录这个较小的数据在待排序的集合中的位置。再用该集合中的下一个数据和我们之前放在临时变量中的数据比较。也就是我们目前认为最小的数据比较,如果比我们之前选出来的数据小,那么再替换该变量。如果比这个数据大,则继续用下一个数据来比较。知道所有的数据都比较完为止。到这时,临时变量里面访的就是最小的数据了。我们把这个数据和第一个数据做对换。此时,最小的元素排到了第一位。倒序(最糟情况)
第一轮:10,9,8,7->(iTemp=9)10,9,8,7->(iTemp=8)10,9,8,7->(iTemp=7)7,9,8,10(交换1次)
第二轮:7,9,8,10->7,9,8,10(iTemp=8)->(iTemp=8)7,8,9,10(交换1次)
第一轮:7,8,9,10->(iTemp=9)7,8,9,10(交换0次)
循环次数:6次
交换次数:2次

其他:
第一轮:8,10,7,9->(iTemp=8)8,10,7,9->(iTemp=7)8,10,7,9->(iTemp=7)7,10,8,9(交换1次)
第二轮:7,10,8,9->(iTemp=8)7,10,8,9->(iTemp=8)7,8,10,9(交换1次)
第一轮:7,8,10,9->(iTemp=9)7,8,9,10(交换1次)
循环次数:6次
交换次数:3次
遗憾的是算法需要的循环次数依然是1/2*(n-1)*n。所以算法复杂度为O(n*n)。
我们来看他的交换。由于每次外层循环只产生一次交换(只有一个最小值)。所以f(n)<=n
所以我们有f(n)=O(n)。所以,在数据较乱的时候,可以减少一定的交换次数。4.插入法:
插入法较为复杂,它的基本工作原理是抽出牌,在前面的牌中寻找相应的位置插入,然后继续下一张
#include <iostream.h>
void InsertSort(int* pData,int Count)
{
    int iTemp;
    int iPos;
    for(int i=1;i<Count;i++)
    {
        iTemp = pData[i];
        iPos = i-1;
        while((iPos>=0) && (iTemp<pData[iPos]))
        {
            pData[iPos+1] = pData[iPos];
            iPos--;
        }
        pData[iPos+1] = iTemp;
    }
}


void main()
{
    int data[] = {10,9,8,7,6,5,4};
    InsertSort(data,7);
    for (int i=0;i<7;i++)
        cout<<data[i]<<" ";
    cout<<"\n";
}
i=1时:
   iTemp=pData[1]=9
   ipos=1-1=0;
   ipos=0>=0 && iTemp=9<pData[0]=10;
   pData[1]=pData[0]=10;
   ipos--=0-1=-1;
   pData[0]=9;   9-10-8-7-6-5-4
i=2时:
   iTemp=pData[2]=8
   ipos=2-1=1;
   ipos=1>=0 && iTemp=8<pData[1]=10;
   pData[2]=pData[1]=10;
   ipos--=1-1=0; 9-10-10-7-6-5-4
   
   ipos=0>=0 && iTemp=8<pData[0]=9;
   pData[1]=pData[0]=9;
   ipos--=0-1=-1;
   pData[0]=8;  8-9-10-7-6-5-4
i=3时:
   iTemp=pData[3]=7
   ipos=3-1=2;
   ipos=2>=0 && iTemp=7<pData[2]=10;
   pData[3]=pData[2]=10;
   ipos--=2-1=1;  8-9-10-10-6-5-4

   ipos=1>=0 && iTemp=8<pData[1]=9;
   pData[2]=pData[1]=9;
   ipos--=1-1=0;  8-9-9-10-6-5-4

   ipos=0>=0 && iTemp=7<pData[0]=8;
   pData[1]=pData[0]=8;
   ipos--=0-1=-1; 
   pData[0]=7;  7-8-9-10-6-5-4i=4时:
   iTemp=pData[4]=6;
   ipos=4-1=3;
   ipos=3>=0 && iTemp=6<pData[3]=10;
   pData[4]=pData[3]=10;
   ipos--=3-1=2; 7-8-9-10-10-5-4
   
   ipos=2>=0 && iTemp=7<pData[2]=9;
   pData[3]=pData[2]=9;
   ipos--=2-1=1;  7-8-9-9-10-5-4
 
   ipos=1>=0 && iTemp=7<pData[1]=8;
   pData[2]=pData[1]=8;
   ipos--=1-1=0;  7-8-8-9-10-5-4  
   
   ipos=0>=0 && iTemp=7<pData[0]=7;
   pData[1]=pData[0]=7;
   ipos--=1-1=0; 
   pDate[0]=6;    6-7-8-9-10-5-4 
由上述可知:插入排序是先把集合中的下一个元素抽取出来
放到一个临时变量里面和第一个元素比较。并记录该元素在集合中的位置
如果第二个元素比第一个小,那么第一个元素和第二个元素对调。下一次
再用第三个元素先和变化后的第二个元素比较,如果变化后的第二个元素
小于第三个元素,用第二个元素的值覆盖第三个元素。在从临时变量里面
取出该元素放到第二个元素中去。
倒序(最糟情况)
第一轮:10,9,8,7->9,10,8,7(交换1次)(循环1次)
第二轮:9,10,8,7->8,9,10,7(交换1次)(循环2次)
第一轮:8,9,10,7->7,8,9,10(交换1次)(循环3次)
循环次数:6次
交换次数:3次

其他:
第一轮:8,10,7,9->8,10,7,9(交换0次)(循环1次)
第二轮:8,10,7,9->7,8,10,9(交换1次)(循环2次)
第一轮:7,8,10,9->7,8,9,10(交换1次)(循环1次)
循环次数:4次
交换次数:2次

上面结尾的行为分析事实上造成了一种假象,让我们认为这种算法是简单算法中最好的,其实不是,因为其循环次数虽然并不固定,我们仍可以使用O方法。从上面的结果可以看出,循环的次数f(n)<=1/2*n*(n-1)<=1/2*n*n。所以其复杂度仍为O(n*n)(这里说明一下,其实如果不是为了展示这些简单排序的不同,交换次数仍然可以这样推导)。现在看交换,从外观上看,交换次数是O(n)(推导类似选择法),但我们每次要进行与内层循环相同次数的‘=’操作。正常的一次交换我们需要三次‘=’而这里显然多了一些,所以我们浪费了时间。

最终,我个人认为,在简单排序算法中,选择法是最好的。插入排序
#include <iostream>
using namespace std;

void coutstream(int a[],int n){
    for(int i=0;i!=n;i++)
        cout<<a[i]<<" ";
}

void insertsort(int a[],int n){
int temp;
    for(int i=1;i<n;i++)
{
   int j=i;
   temp=a[i]; //先把a[i]位置的数据存起来
   while(j>0&&temp<a[j-1])
   {
    a[j]=a[j-1];
    j--;
   }
   a[j]=temp;
}
}


int main()
{
    int a[5]={1,6,4,8,4};
    insertsort(a,5);//插入排序
    coutstream(a,5);//
    return 0;
}
二、高级排序算法:
高级排序算法中我们将只介绍这一种,同时也是目前我所知道(我看过的资料中)的最快的。它的工作看起来仍然象一个二叉树。首先我们选择一个中间值middle程序中我们使用数组中间值,然后把比它小的放在左边,大的放在右边(具体的实现是从两边找,找到一对后交换)。然后对两边分别使用这个过程(最容易的方法——递归)。

1.快速排序:
#include <iostream.h>

void run(int* pData,int left,int right)
{
    int i,j;
    int middle,iTemp;
    i = left;
    j = right;
    middle = pData[(left+right)/2];  //求中间值
    do{
        while((pData[i]<middle) && (i<right))//从左扫描大于中值的数
            i++;         
        while((pData[j]>middle) && (j>left))//从右扫描大于中值的数
            j--;
        if(i<=j)//找到了一对值
        {
            //交换
            iTemp = pData[i];
            pData[i] = pData[j];
            pData[j] = iTemp;
            i++;
            j--;
        }
    }while(i<=j);//如果两边扫描的下标交错,就停止(完成一次)

    //当左边部分有值(left<j),递归左半边
    if(left<j)
        run(pData,left,j);
    //当右边部分有值(right>i),递归右半边
    if(right>i)
        run(pData,i,right);
}

void QuickSort(int* pData,int Count)
{
    run(pData,0,Count-1);
}

void main()
{
    int data[] = {10,9,8,7,6,5,4};
    QuickSort(data,7);
    for (int i=0;i<7;i++)
        cout<<data[i]<<" ";
    cout<<"\n";
}

这里我没有给出行为的分析,因为这个很简单,我们直接来分析算法:首先我们考虑最理想的情况
1.数组的大小是2的幂,这样分下去始终可以被2整除。假设为2的k次方,即k=log2(n)。
2.每次我们选择的值刚好是中间值,这样,数组才可以被等分。
第一层递归,循环n次,第二层循环2*(n/2)......
所以共有n+2(n/2)+4(n/4)+...+n*(n/n) = n+n+n+...+n=k*n=log2(n)*n
所以算法复杂度为O(log2(n)*n)
其他的情况只会比这种情况差,最差的情况是每次选择到的middle都是最小值或最大值,那么他将变成交换法(由于使用了递归,情况更糟)。但是你认为这种情况发生的几率有多大??呵呵,你完全不必担心这个问题。实践证明,大多数的情况,快速排序总是最好的。
如果你担心这个问题,你可以使用堆排序,这是一种稳定的O(log2(n)*n)算法,但是通常情况下速度要慢于快速排序(因为要重组堆)。三、其他排序
1.双向冒泡:
通常的冒泡是单向的,而这里是双向的,也就是说还要进行反向的工作。
代码看起来复杂,仔细理一下就明白了,是一个来回震荡的方式。
写这段代码的作者认为这样可以在冒泡的基础上减少一些交换(我不这么认为,也许我错了)。
反正我认为这是一段有趣的代码,值得一看。
#include <iostream.h>
void Bubble2Sort(int* pData,int Count)
{
    int iTemp;
    int left = 1;
    int right =Count -1;
    int t;
    do
    {
        //正向的部分
        for(int i=right;i>=left;i--)
        {
            if(pData[i]<pData[i-1])
            {
                iTemp = pData[i];
                pData[i] = pData[i-1];
                pData[i-1] = iTemp;
                t = i;
            }
        }
        left = t+1;

        //反向的部分
        for(i=left;i<right+1;i++)
        {
            if(pData[i]<pData[i-1])
            {
                iTemp = pData[i];
                pData[i] = pData[i-1];
                pData[i-1] = iTemp;
                t = i;
            }
        }
        right = t-1;
    }while(left<=right);
}

void main()
{
    int data[] = {10,9,8,7,6,5,4};
    Bubble2Sort(data,7);
    for (int i=0;i<7;i++)
        cout<<data[i]<<" ";
    cout<<"\n";
}快速排序
#include <iostream>
using namespace std;
class QuickSort
{
public:
    void quick_sort(int* x,int low,int high)
    {
        int pivotkey;
        if(low <high)
        {
            pivotkey=partion(x,low,high);
            quick_sort(x,low,pivotkey-1);
            quick_sort(x,pivotkey+1,high);
        }
    }
    int partion(int* x,int low,int high)
    {
        int pivotkey;
        pivotkey=x[low];
        while(low <high)
        {
            while (low <high&&x[high]>=pivotkey)
                --high; //还有while循环只执行这一句
            x[low]=x[high];
            while (low <high&&x[low] <=pivotkey)
                ++low; //还有while循环只执行这一句
            x[high]=x[low];
        }
        x[low]=pivotkey;
        return low;
    }
};
int main()
{
    int x[10]={52,49,80,36,14,58,61,97,23,65};
    QuickSort qs;
    qs.quick_sort(x,0,9);
    cout <<"排好序的数字序列为:" <<endl;
    for (int i=0;i <10;i++)
    {
      printf("%d ",x[i]);
    }
return 0;
}
2.SHELL排序
这个排序非常复杂,看了程序就知道了。
首先需要一个递减的步长,这里我们使用的是9、5、3、1(最后的步长必须是1)。
工作原理是首先对相隔9-1个元素的所有内容排序,然后再使用同样的方法对相隔5-1个元素的排序以次类推。
#include <iostream.h>
void ShellSort(int* pData,int Count)
{
    int step[4];
    step[0] = 9;
    step[1] = 5;
    step[2] = 3;
    step[3] = 1;

    int iTemp;
    int k,s,w;
    for(int i=0;i<4;i++)
    {
        k = step[i];
        s = -k;
        for(int j=k;j<Count;j++)
        {
            iTemp = pData[j];
            w = j-k;//求上step个元素的下标
            if(s ==0)
            {
                s = -k;
                s++;
                pData[s] = iTemp;
            }
            while((iTemp<pData[w]) && (w>=0) && (w<=Count))
            {
                pData[w+k] = pData[w];
                w = w-k;
            }
            pData[w+k] = iTemp;
        }
    }
}

void main()
{
    int data[] = {10,9,8,7,6,5,4,3,2,1,-10,-1};
    ShellSort(data,12);
    for (int i=0;i<12;i++)
        cout<<data[i]<<" ";
    cout<<"\n";
}
呵呵,程序看起来有些头疼。不过也不是很难,把s==0的块去掉就轻松多了,这里是避免使用0步长造成程序异常而写的代码。这个代码我认为很值得一看。这个算法的得名是因为其发明者的名字D.L.SHELL。依照参考资料上的说法:“由于复杂的数学原因避免使用2的幂次步长,它能降低算法效率。”另外算法的复杂度为n的1.2次幂。同样因为非常复杂并“超出本书讨论范围”的原因(我也不知道过程),我们只有结果了

#include <iostream>
using namespace std;
void maopao(int *list,int n)
{
int i=n,j,temp;
bool exchange;//当数据已经排好时,退出循环
for(i=0;i<n;i++)
{
   exchange=false;
   for (j=0;j<n-i-1;j++)
   {
    if (list[j]>list[j+1])
    {
     temp=list[j];
     list[j]=list[j+1];
     list[j+1]=temp;
     exchange=true;
    }

   }
   if (!exchange)
    {
    return;
    }
}
}
int main()
{
int a[7]={32,43,22,52,2,10,30};
maopao(a,7);
for(int i=0;i<7;i++)
   cout<<a[i]<<" ";
return 0;
}

shell排序的思想是根据步长由长到短分组,进行排序,直到步长为1为止,属于插入排序的一种。下面用个例子更好的理解一下 无序数列: 32, 43,56,99,34,8,54,76 1.首先设定gap=n/2=4于是分组 32,34    排序  32,34 43, 8            8, 43 56,54            54,56 99,76            76,99 数列变成 32,8,54,76,34,43,56,99 2.gap=gap/2=2 于是分组 32,54,34,56  排序  32,34,54,56 8,76,43,99            8,43,76,99 于是数列变成 32,8,34,43,54,76,56,99 3.gap=gap/2=1于是分组 32,8,34,43,54,76,56,99 排序 8,32,34,43,54,56,76,99 gap=1结束…… 相应的C语言代码引用K&R C程序设计一书中给出的代码 void shellsort(int v[], int n) { int gap, i, j, temp; for(gap=n/2;gap>0;gap/=2) //设定步长     for(i=gap;i <n;++i) //在元素间移动为止         for(j=i-gap; j>=0&&v[j]>v[j+gap]; j-=gap){ //比较相距gap的元素,逆序互换             temp=v[j];             v[j]=v[j+gap];             v[j+gap]=temp;       } } //帕斯卡恒等式为C(n,k)=C(n-1,k-1)+C(n-1,k)
long fun(long n,long r)
{
   if(r<0||n<0)
   {
      printf("\nError.Exit!");
      exit(1);
   }
   if(r>n)  return 0;
   if(r==1||r==n-1)//根据组合定义,我们有C(n,1)=C(n,n-1)=n
      return n;
   if(r==0||r==n)//根据组合定义,我们有C(n,0)=C(n,n)=1
      return 1;
   return fun(n-1,r)+fun(n-1,r-1);//帕斯卡组合公式
}

//选择法对数组排序的函数模板
template <class T>
void selectsort(T arr[],int size)
{
    T temp;
    int i,j;
    for (i=0;i<size-1;i++)
        for (j=i+1;j<size;j++)
            if (arr[i]>arr[j])
            {
               temp=arr[i];
               arr[i]=arr[j];
               arr[j]=temp;
            }
}

//冒泡法对数组排序的函数模板
template<class T>
void bubblesort(T *d,int n)
{
int i,j;
T t;
for(i=0;i<n-1;i++)
   for(j=0;j<n-i-1;j++)
    if(d[j]>d[j+1])
      {
        t=d[j];
        d[j]=d[j+1];
        d[j+1]=t;
      }
}

//插入法对数组排序的函数模板
template <class T>
void InsertSort(T A[], int n)
{
   int i, j;
   T   temp;
   for (i = 1; i < n; i++)
   {
     temp = A[i];
     for (j=i-1; j>=0&&temp<A[j];j--)
        A[j+1]=A[j];
     A[j+1] = temp;
   }
}

//二分查找法的函数模板
template <class T>
int binary_search(T array[], T value, int size)
{
    int high = size-1, low = 0, mid;
    while (low<=high)
    {
      mid = (high + low) / 2;
      if (value < array[mid])
        high = mid - 1;
      else if(value>array[mid])
        low = mid + 1;
      else return mid;
    }
    return -1;
}


将2~36进制数与10进制数相互转换
 //将2~36进制数转换成10进制数
unsigned int OthToDec(char *oth, int base) //base为已知数的进制
{
    unsigned int i=0, dec=0;
    while (oth[i])
    {
        dec*=base;
        if (oth[i]>='0' && oth[i]<='9')
            dec+=oth[i]&15;//dec+=oth[i]-48;
        else if (oth[i]>='A' && oth[i]<='Z')
            dec+=oth[i]-55;
        else if (oth[i]>='a' && oth[i]<='z')
            dec+=oth[i]-87;
        i++;
    }
    return dec;
}
//将10进制(无符号)转2~36进制数
char *DecToOth(char *oth, unsigned int dec, int base)   //base为要转换的数的进制

{
    char ch, *left=oth, *right=oth,num[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    do
      {
       *right=num[dec%base];
       right++;
      }while (dec/=base);
    *right='\0';
    right--;
    while (left<right)
    {
        ch=*left;
        *left=*right;
        *right=ch;
        left++;right--;
    }
    return oth;
}

//统计substr在str中的个数
int fun(char *str,char *substr)
{
 int n=0;
 char *q;
 q=substr;
 while(*str!='\0')
 {
  if(*str==*substr)
   {
    str++;
    substr++;
    if(*substr=='\0')
     {
      n++;
      substr=q;
     }
   }
   else
   {
    str++;substr=q;
   }
 }
 return n;
}使用数组实现约瑟夫环:
#include <stdio.h>
#include <stdlib.h>
main()
{
      int m,n,i=1,j,k=1,per,o;
    
      printf("请输入总共的人数,记为n \n");
      scanf("%d",&n);
    
      int array[n+1];
      int order[n+1];
      printf("请输入几号出圈,记为m \n");
      scanf("%d",&m);
      printf("\n**************************************\n");
      for(;i <n;i++)//数组链表模拟  
          array[i]=i+1;
      array[n]=1;
      printf("%d  ",array[n]);
      i=1;j=1;per=n;
      while(array[i]!=i){
          if(k==m){
              order[j]=i;
              j++;
              array[per]=array[i];
              k=0;
              for(o=1;o <=j;o++)
              printf("%d* ",order[o]);
          }
          else{printf("%d  ",array[i]);
        
              per=i;
              i=array[i];
              k++;
          }

      }
      order[n]=i;
      printf("\n**************************************\n");
      for(i=1;i <=n;i++)
          printf("%d  ",order[i]);

      system("pause");
      return 0;
} 输入正整数N,然后是N*N个正整数,表示边权邻接矩阵。 
  输出求解过程。 
  
  
  /* 
      Problem   :   Weighted   Bipartite   Matching 
  Algorithm   :   Hungarian   Algorithm 
  Reference   :   Douglas   B.West,Introduction   to   Graph   Theory,125-129 
        Author   :   PC 
            Date   :   2005.2.23 
  */ 
  
  #include   <iostream.h> 
  #include   <iomanip.h> 
  #include   <fstream.h> 
  #include   <memory.h> 
  
  ifstream   fin("input.txt"); 
  #define   cin   fin 
  
  const   int   max=50; 
  bool   T[max],R[max],visited[max]; 
  int   U[max],V[max],gt[max][max],x[max],y[max]; 
  int   N; 
  
  void   output() 
  { 
  int   i,j; 
  for(i=0;i<N;i++) 
  { 
  for(j=0;j<N;j++) 
  { 
  cout<<setw(2)<<gt[i][j]<<'   '; 
  } 
  if(R[i])cout<<setw(2)<<'R'<<'   '; 
  cout<<endl; 
  } 
  for(i=0;i<N;i++) 
  if(T[i])cout<<setw(2)<<'T'<<'   '; 
  else   cout<<setw(2)<<'   '<<'   '; 
  cout<<endl; 
  } 
  
  int   path(int   u) 
  { 
  int   v; 
  for(v=0;v<N;v++) 
  { 
  if(gt[u][v]==0   &&   !visited[v]) 
  { 
  visited[v]=1; 
  if(y[v]<0   ||   path(y[v])) 
  { 
  x[u]=v;y[v]=u; 
  R[u]=1;T[v]=0; 
  return   1; 
  }else{ 
  T[v]=1; 
  R[y[v]]=0; 
  } 
  } 
  } 
  return   0; 
  } 
  
  int   main() 
  { 
  for(;cin>>N;){ 
  int   i,j,ans,sigma,step=0; 
  for(i=0;i<N;i++) 
  { 
  U[i]=V[i]=0; 
  for(j=0;j<N;j++) 
  { 
  cin>>gt[i][j]; 
  if(U[i]<gt[i][j])U[i]=gt[i][j]; 
  } 
  } 
  
  for(i=0;i<N;i++) 
  { 
  for(j=0;j<N;j++) 
  { 
  gt[i][j]=U[i]-gt[i][j]; 
  } 
  } 
  ////////////////////////////////////////////////////////// 
  for(;;) 
  { 
  ans=0; 
  sigma=0; 
  memset(x,-1,sizeof(x)); 
  memset(y,-1,sizeof(y)); 
  memset(R,0,sizeof(R)); 
  memset(T,0,sizeof(T)); 
  for(i=0;i<N;i++) 
  { 
  if(x[i]<0) 
  { 
  memset(visited,0,sizeof(visited)); 
  ans+=path(i); 
  } 
  
  for(j=0;j<N;j++) 
  { 
  if(sigma<1   ||   sigma>gt[i][j]   &&   gt[i][j]>0) 
  sigma=gt[i][j];   
  } 
  } 
  cout<<"step   "<<++step<<":\n"; 
  output(); 
  
  if(ans>=N) 
  break; 
  
  for(i=0;i<N;i++) 
  { 
  if(!R[i]) 
  U[i]-=sigma; 
  if(T[i]) 
  V[i]+=sigma; 
  for(j=0;j<N;j++) 
  { 
  if(T[j]) 
  gt[i][j]+=sigma; 
  if(!R[i]) 
  gt[i][j]-=sigma; 
  } 
  } 
  } 
  ////////////////////////////////////////////////////////// 
  ans=0; 
  cout<<"Result:"<<endl; 
  for(i=0;i<N;i++) 
  { 
  ans+=U[i]+V[i]; 
  for(j=0;j<N;j++) 
  { 
  if(x[i]==j   &&   y[j]==i)cout<<setw(2)<<U[i]+V[j]<<'   '; 
  else   cout<<setw(2)<<0<<'   '; 
  } 
  cout<<endl; 
  } 
  cout<<"Maximum   :   "<<ans<<endl; 
  } 
  return   0; 
  } 
  
  
  input.txt: 
  
  5 
  4   1   6   2   3 
  5   0   3   7   6 
  2   3   4   5   8 
  3   4   6   3   4 
  4   6   5   8   6 
  
  5 
  4   4   4   3   6 
  1   1   4   3   4 
  1   4   5   3   5 
  5   6   4   7   9 
  5   3   6   8   3 
  
  5 
  7   8   9   8   7 
  8   7   6   7   6 
  9   6   5   4   6 
  8   5   7   6   4 
  7   6   5   5   5 
  
  5 
  1   2   3   4   5 
  6   7   8   7   2 
  1   3   4   4   5 
  3   6   2   8   7 
  4   1   3   5   4 
  /* 
      Problem   :   Weighted   Bipartite   Matching 
  Algorithm   :   Hungarian   Algorithm 
  Reference   :   Douglas   B.West,Introduction   to   Graph   Theory,125-129 
        Author   :   PC 
            Date   :   2005.2.23 
  */ 
  #include   <iostream.h> 
  #include   <iomanip.h> 
  #include   <fstream.h> 
  #include   <memory.h> 
  
  ifstream   fin("input.txt"); 
  #define   cin   fin 
  
  const   int   max=50; 
  bool   T[max],R[max],visited[max]; 
  int   U[max],V[max],gt[max][max],x[max],y[max]; 
  int   N; 
  
  void   output() 
  { 
        int   i,j; 
        for(i=0;i<N;i++) 
        { 
              for(j=0;j<N;j++) 
              { 
                    cout<<setw(2)<<gt[i][j]<<'   '; 
              } 
              if(R[i])cout<<setw(2)<<'R'<<'   '; 
                    cout<<endl; 
        } 
        for(i=0;i<N;i++) 
              if(T[i])cout<<setw(2)<<'T'<<'   '; 
        else   cout<<setw(2)<<'   '<<'   '; 
        cout<<endl; 
  } 
  
  int   path(int   u) 
  { 
        int   v; 
        for(v=0;v<N;v++) 
        { 
              if(U[u]+V[v]-gt[u][v]==0   &&   !visited[v]) 
              { 
                    visited[v]=1; 
                    if(y[v]<0   ||   path(y[v])) 
                    { 
                          x[u]=v;y[v]=u; 
                          R[u]=1;T[v]=0; 
                          return   1; 
                    }else{ 
                          T[v]=1; 
                          R[y[v]]=0; 
                    } 
              } 
        } 
        return   0; 
  } 
  
  int   main() 
  { 
        int   i,j,ans,sigma,step=0; 
        for(;cin>>N;){ 
              for(i=0;i<N;i++) 
              { 
                    U[i]=V[i]=0; 
                    for(j=0;j<N;j++) 
                    { 
                          cin>>gt[i][j]; 
                          if(U[i]<gt[i][j])U[i]=gt[i][j]; 
                    } 
              } 
              ////////////////////////////////////////////////////////// 
              for(;;) 
              { 
                      ans=0; 
                      sigma=0; 
                      memset(x,-1,sizeof(x)); 
                      memset(y,-1,sizeof(y)); 
                      memset(R,0,sizeof(R)); 
                      memset(T,0,sizeof(T)); 
                      for(i=0;i<N;i++) 
                      { 
                            if(x[i]<0) 
                            { 
                                    memset(visited,0,sizeof(visited)); 
                                    ans+=path(i); 
                            } 
                      } 
                      for(i=0;i<N;i++) 
                      { 
                            if(!R[i]) 
                                  for(j=0;j<N;j++) 
                                  { 
                                  if(!T[j]   &&   (sigma<1   ||   sigma>U[i]+V[j]-gt[i][j]   &&   U[i]+V[j]-gt[i][j]>0)) 
                                          sigma=U[i]+V[j]-gt[i][j];   
                                  } 
                      } 
                      cout<<"step   "<<++step<<":\n"; 
                      output(); 
  
                      if(ans>=N) 
                            break; 
  
                      for(i=0;i<N;i++) 
                      { 
                            if(!R[i]) 
                                  U[i]-=sigma; 
                            if(T[i]) 
                                  V[i]+=sigma; 
                      } 
              } 
              ///////////////////////////////////////////////////////// 
              ans=0; 
              cout<<"Result:"<<endl; 
              for(i=0;i<N;i++) 
              { 
                      ans+=U[i]+V[x[i]]; 
                      for(j=0;j<N;j++) 
                      { 
                              if(x[i]==j   &&   y[j]==i)cout<<setw(2)<<U[i]+V[j]<<'   '; 
                              else   cout<<setw(2)<<0<<'   '; 
                      } 
                      cout<<endl; 
              } 
              cout<<"Maximum   :   "<<ans<<endl; 
        } 
        return   0; 
  } 
   写函数完成内存的拷贝 void* memcpy( void *dst, const void *src, unsigned int len ) {     register char *d;     register char *s;     if (len == 0)         return dst;     if ( dst > src )  //考虑覆盖情况     {         d = (char *)dst + len - 1;         s = (char *)src + len - 1;         while ( len >= 4 )  //循环展开,提高执行效率         {             *d-- = *s--;             *d-- = *s--;             *d-- = *s--;             *d-- = *s--;             len -= 4;         }         while ( len-- )         {             *d-- = *s--;         }     }     else if ( dst < src )     {         d = (char *)dst;         s = (char *)src;         while ( len >= 4 )         {             *d++ = *s++;             *d++ = *s++;             *d++ = *s++;             *d++ = *s++;             len -= 4;         }         while ( len-- )         {             *d++ = *s++;         }     }     return dst; } 出现次数相当频繁

  评论这张
 
阅读(4101)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017