[笔试]常考算法

#include<iostream>

using namespace std;

#include<cmath>

#include<iomanip>



//虚函数

/*class ClassA

{

public:

    ClassA()

    {

        cout<<"A类构造函数被调用"<<endl;

    

    }

    ~ClassA()

    {

        cout<<"A类析构函数被调用"<<endl;

    

    }

    virtual void getnum()=0;

    //{

    //    cout<<"A类虚函数被调用"<<endl;



        

    //}

        

private:

        int num;

        char *str;

        double dnum;

};





class ClassB:public ClassA

{

public:

    ClassB()

    {

        cout<<"B类构造函数被调用"<<endl;

    

    }

    ~ClassB()

    {

        cout<<"B类析构函数被调用"<<endl;

    

    }

    virtual void getnum()

    {

        cout<<"B类虚函数被调用"<<endl;

        

    

    }

private:

    char Bstr[10];





};



void  main()

{

    ClassA *pc;

    ClassB B;

    pc=&B;

    pc->getnum();

    getchar();



}*/



/*

上一程序的缩略版

class ClassA

{

public:

    virtual void getnum()

    {

        cout<<"A类虚函数被调用"<<endl;

    }    

};

class ClassB:public ClassA

{

public:

    virtual void getnum()

    {

        cout<<"B类虚函数被调用"<<endl;

    }

};

void  main()

{   ClassA *pc;

    ClassB B;

    pc=&B;

    pc->getnum();

    getchar();

}*/







/*

通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串过滤程序,若字符串中出现多个相同的字符,

将非首次出现的字符过滤掉。

比如字符串“abacacde”过滤结果为“abcde”。

*/



void stringFilter(const char *pInputStr, long lInputLen, char *pOutputStr)

{

    //const char *TempStr=pInputStr;

    int count1=0;

    int count2=0;

    int i=0;

    while(count1<=lInputLen)

    {

        for(i=0;i<=count2;)

        {

            if(*(pInputStr+count1)!=*(pOutputStr+i))//判断是否有重复字符

                 i++;

            else 

                break;

        }

        if(i>count2)

        {

            *(pOutputStr+count2)=*(pInputStr+count1);

            count2++;

        }

           

        count1++;

    

    }





}









/*通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,

并输出压缩后的字符串。

压缩规则:

1. 仅压缩连续重复出现的字符。比如字符串"abcbc"由于无连续重复字符,压缩后的字符串还是"abcbc".

2. 压缩字段的格式为"字符重复的次数+字符"。例如:字符串"xxxyyyyyyz"压缩后就成为"3x6yz"*/



void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr)

{

    int i=0;

    int j=0;

    int k=0;

        for(i=0;i<lInputLen;i=j)

        {

            for(j=i+1;j<lInputLen;j++)

                if(*(pInputStr+j)!=*(pInputStr+i))

                    break;

            if(j!=i+1)

                *(pOutputStr+k++)=char(j-i+'0');

            

           *(pOutputStr+k++)=*(pInputStr+i);

        }

      









}

/* 

题目描述(50分): 

通过键盘输入100以内正整数的加、减运算式,请编写一个程序输出运算结果字符串。 

输入字符串的格式为:“操作数1 运算符 操作数2”,“操作数”与“运算符”之间以一个空格隔开。 

 

补充说明: 

1. 操作数为正整数,不需要考虑计算结果溢出的情况。 

2. 若输入算式格式错误,输出结果为“0”。 

 

要求实现函数: 

void arithmetic(const char *pInputStr, long lInputLen, char *pOutputStr); 

 

【输入】 pInputStr:  输入字符串 

         lInputLen:  输入字符串长度 

【输出】 pOutputStr: 输出字符串,空间已经开辟好,与输入字符串等长; 

 

【注意】只需要完成该函数功能算法,中间不需要有任何IO的输入输出 

 

示例 

输入:“4 + 7”  输出:“11” 

输入:“4 - 7”  输出:“-3” 

输入:“9 ++ 7”  输出:“0” 注:格式错误 

*/  

bool Isnumber(char c)

{

    if(c<='9'&&c>='0'){  

        return true;  

    }else{  

        return false;  

    }  



}

void arithmetic(const char *pInputStr, long lInputLen, char *pOutputStr)

{



    int ops1=0;

    int ops2=0;

    int num=0;

    char Coptr;

    int i=0;

    int j=0;

    int isvailed=0;

    while(Isnumber(pInputStr[i]))

    {

        ops1=ops1*10+(int)(pInputStr[i]-'0');

        i++;

    }

    //cout<<ops1<<endl;

    if(i==0)

        isvailed=1;

    while(pInputStr[i++]==' ');

    //cout<<i<<endl;

    j=i-1;

    Coptr=pInputStr[j];//获取操作符

    //cout<<Coptr<<endl;

    while(pInputStr[j++]==' ');

    j=i+1;

    while(Isnumber(pInputStr[j]))

    {

        ops2=ops2*10+(int)(pInputStr[j]-'0');

        j++;

    }



    if(j==(i+1))

        isvailed=1;

    

    

    

    if(isvailed==1)

        *pOutputStr='0';

    else

    {

        switch(Coptr)

       {

        case '+':

           num=ops1+ops2;

           break;

        case '-':

           num=ops1-ops2;

           break;

         case '*':

           num=ops1*ops2;

           break;

        case '/':

            num=ops1/ops2;

            break;

        default:

            *pOutputStr='0';

            break;

        }

     }

    if(num==0)

        *pOutputStr='0';

    

    int scale=100;

    if(num<0)

    {

        *pOutputStr++='-';

        num=-num;

    }

    

    for(int k=0;k<3;k++)

    {

        if(num/scale)

        {

            *pOutputStr++=char(num/scale+'0');

            

        }

        num=num%scale;

        if(num==0)

        {

            *pOutputStr++=char('0');

            break;

        }

        scale/=10;

    

    }

    



}

/*1 字串转换

问题描述:

将输入的字符串(字符串仅包含小写字母‘a’到‘z’),按照如下规则,循环转换后输出:a->b,b->c,…,y->z,z->a;

若输入的字符串连续出现两个字母相同时,后一个字母需要连续转换2次。例如:aa 转换为 bc,zz 转换为 ab;

当连续相同字母超过两个时,第三个出现的字母按第一次出现算。

要求实现函数:

void convert(char *input,char* output)

【输入】  char *input , 输入的字符串

【输出】  char *output ,输出的字符串

【返回】 无

示例

输入:char*input="abcd" 

输出:char*output="bcde"

输入:char*input="abbbcd" 

输出:char*output="bcdcde"   3*/

void convert(char *input,char* output)

{

    int i=0;

    int j=0;

    int k=0;

    int temp=1;

    while(input[j++]!='\0')

    {        

        

        if(input[i-1]!=input[i])

            output[k++]=input[i++]+1;

        else

        {

            temp++;

            if(temp==3)

                output[k++]=input[i++]+1;

            else

                output[k++]=input[i++]+2;    

            

                

        }

    }

}  

/*2 字符串处理转换

问题描述:    

在给定字符串中找出单词( “单词”由大写字母和小写字母字符构成,其他非字母字符视为单词的间隔,

如空格、问号、数字等等;另外单个字母不算单词);找到单词后,按照长度进行降序排序,

(排序时如果长度相同,则按出现的顺序进行排列),然后输出到一个新的字符串中;

如果某个单词重复出现多次,则只输出一次;如果整个输入的字符串中没有找到单词,请输出空串。

输出的单词之间使用一个“空格”隔开,最后一个单词后不加空格。

要求实现函数:

void my_word(charinput[], char output[])

【输入】  char input[], 输入的字符串

【输出】  char output[],输出的字符串

【返回】 无

示例

输入:charinput[]="some local buses, some1234123drivers" ,

输出:charoutput[]="drivers local buses some"

输入:charinput[]="%A^123 t 3453i*()" ,

输出:charoutput[]=""*/



void my_word(char input[], char output[])

{

    int i=0;

    int j=0;

    int len=0;

    int k=0;

    int s=0;

    int m=0;

    while(input[len++]!='\0');

    cout<<len<<endl;

    char *tstr=new char[len];

    while(input[j]!='\0')

    {

        s=0;

        for(i=j;i<len-1;)

        {

            if((input[i]>='a'&&input[i]<='z')||(input[i]>='A'&&input[i]<='Z'))    

            {

                tstr[s++]=input[i++];

            }

            else

            {

                i++;

                break;

            }

        }

         if (s>1)

            {

              for(k=0;k<s;k++)

                  output[m++]=tstr[k];

              output[m++]=' ';

             }

            j=i;

    }





    //cout<<j<<endl;

    delete [] tstr;





}





/*【功能】:判断给定的一个数iNumber是否是一个素数

【输入】:一个整型数 iNumber

【输出】:0:不是素数

                   1:是素数

*/

int isPrimNumber(int iNumber)

{

         if(iNumber == 1)

               return 0;

         if(iNumber == 2)

               return 1;

         for(int i = 2; i <= sqrt((double)iNumber); ++ i)



         {

                 if(iNumber % i == 0)

                          return 0;

          }

          return 1;

   }



/* 

【功能】:找出一个数组iArray[]中大于等于平均值的元素个数

【输入】:数组iArray, 数组的元素个数nSize

【输出】:大于等于平均值的元素个数cnt

*/

int func(int iArray[],int nSize)

{

    int i=0;

    int num=0;

    double Array=0;

    int cnt=0;

    for(i=0;i<nSize;i++)

        num+=iArray[i];

     Array=num*1.0/nSize;

     for(i=0;i<nSize;i++)

         if(iArray[i]>=Array)

             cnt++;

     return cnt;

}



/* 

【功能】:判断一个数是否回文数,如果1221,232, 3;

【输入】:一个整型数iNumber

【输出】:0: iNumber不是回文数

          1:iNumber是回文数

*/

int isPlalindromeNumber(int iNumber)

{

    int src = iNumber;

         int des = 0;



         while(src)

         {

                des = des * 10 + src % 10;

                src /= 10;

          }



         if(des != iNumber)

                 return 0;

          return 1;







}







 /* 

【功能】:求解出特定数iNumber之内的所有素数,将这些素数存入一个数组primNumber[]中

【输入】:特定的数iNumber

*/

 void getPrim(int iNumber) 

 {

     int primNumber[100]={2,3,5};

     int trial=5;

     int count=3;

    

    do

    {

        int found=0;

        trial+=2;

        for(int i=0;i<count;i++)

        {

            found=(trial%(primNumber[i]))==0;

            if(found)

                break;



        }

        if(!found)

        primNumber[count++]=trial;

    

    

    }while(trial<iNumber);

    int n=0;

    for(int i=0;i<count;i++)

    {

        cout<<setw(10)<<*(primNumber+i);

        n++;

        if(n==5)

        {

            n=0;

            cout<<endl;

        

        }

        

    

    

    }

 

 

 }

 int func(int x) 

{ 

int countx =0; 

while(x) 

{ 

countx ++; 

x = x&(x-1); 

} 

return countx; 

}



 /***********************************三种简单排序方法**************************************************

 直接插入排序   稳定

 冒泡排序       稳定

 直接选择排序   不稳定

 时间复杂度均为O(n方) 空间复杂度O(1)

 稳定算法:两个相等的关键字若排序前后位置不变则稳定







 

 直接插入排序,也是分成两个序列,待排序列和已排好序列,每次从待排序列里去一个数,将其插入到已排好序列中

 显然,只要最后的一个数每排好,所有已排好序列数的位置都有可能会变动。

 先把当前待拍元素保存起来,用j来循环已排好序列,找到插入位置,这个寻找过程就是不断移动元素的过程

 input[j + 1] = input[j]; 

 input[j] = temp;







 直接插入排序适合原始数据基本有序且长度较小的情况下

 */

 void InsertionSort(int input[],int len) 

{

     int i,j,temp;

     for (i = 1; i < len; i++) 

     {

          temp = input[i];  /* 操作当前元素,先保存在其它变量中 */

          for (j = i - 1;j>-1&&input[j] > temp ; j--) /* 从当前元素的上一个元素开始查找合适的位置 */

          {

               input[j + 1] = input[j]; /* 一边找一边移动元素 */

               input[j] = temp;

          }

     }

}







/*直接选择算法的思想是将数列分成两部分,一部分是待排序列,一部分是已经拍好的序列

显然,一开始已经排好的序列只有第一个元素,每次从待排序列里选一个最小的跟已经排好的序列最大的交换

对于已排好序列是不会发生改变的除了最后一个元素。

直接选择算法时间复杂度为O(n方),空间复杂度O(1)。他是一个不稳定的算法

*/

void SelectSort(int input[],int len)

{

    int i=0;//第一层循环,i永远表示已排好序列的最后一个元素

    int j=0;//第二层循环,j永远表示待排序列的第一个元素

    int temp=0;//中间变量

    for(i=0;i<len;i++)

        for(j=i+1;j<len;j++)

            if(input[i]>input[j])

            {

                temp=input[j];

                input[j]=input[i];

                input[i]=temp;

            }

}



/*

冒泡排序

每轮沉淀一个最大的数到最后,在最好的情况下冒泡排序和直接插入排序是最快的。







*/

void BubleSort(int input[],int len)

{



    int i=0;//第一层循环

    int j=0;//第二层循环

    int temp=0;//中间变量

    for(int i=0;i<len;i++)

    {    for(int j=0;j<len-i-1;j++)

        {

            if(input[j]>input[j+1])

            {

                temp=input[j];

                input[j]=input[j+1];

                input[j+1]=temp;

            }

        }

    }

}







/*快速排序

快速排序适合原始数据杂乱无章,n较大且对稳定性没有要求的情况,平均情况下,快速排序最快,时间复杂度

O(nlogn),空间复杂度为O(logn)



*/

int partition(int input[],int low,int high)

{

    

    int pivotey=input[low];

    low=low+1;

    while(low<high)

    {

        while(low<high&&input[high>=pivotey])--high;

            input[low]=input[high];

        while(low<high&&input[low]<=pivotey)++low;

            input[high]=input[low];

    }

    input[low]=pivotey;

    return low;

}

void Qsort(int input[],int low,int high)

{

    int pivoloc=0;

    if(low<high)

    {

        pivoloc=partition(input,low,high);

        Qsort(input,low,pivoloc-1);

        Qsort(input,pivoloc+1,high);

    

    }







}















//编程实现字符串到整数的转换函数

int parseInt(char *str,int radix)

{

    int i=0;

    int j=0;



    //首先判断他是不是一个合法的整数

    int len=strlen(str);

    while(i<len)

      if((*(str+i)>=48)&&(*(str+i)<=57)||(*(str+i)>=65)&&(*(str+i)<=90)||(*(str+i)>=97)&&(*(str+i)<=122))

          i++;

      else

           break;

    try

    {

         if(i<len||len==0)

         throw "整数不合法";

    

    }

    catch(const char aMessage())

    {

        cout<<endl<<aMessage<<endl;

        



    }

    //字符转换

    int temp=0;

    int num=0;

    j=len;

    int k=0;

    cout<<str<<endl;

    while(j>=0)

    {

        if((*(str+k)>=65)&&(*(str+k)<=90))

            temp=*(str+k)-54;

        if((*(str+k)>=97)&&(*(str+k)<=122))

            temp=*(str+k)-86;

        if((*(str+k)>=48)&&(*(str+k)<=57))

            temp=*(str+k)-48;



        num+=(int)temp*pow((double)radix,(int)j-1);

        j--;

        k++;

    }

    try

    {

         if(!(num>=-32768||num<=32767))

         throw "整数越界";

    

    }

    catch(const char aMessage())

    {

        cout<<endl<<aMessage<<endl;



    }             









   return num;





}





//笼子里有鸡和兔子,共100条腿,问鸡有多少,兔子有多少,有多少可能性

int lag(int num)

{

    int chken=0;

    int rubb=0;

    int k=0;

    int snum=0;

    while(chken<=(num/2))

    {



        k=(num-chken*2)%4;

        rubb=(num-chken*2)/4;

        if(k==0)

        {

            cout<<"鸡的数目为"<<chken<<" "<<" 鸭的数目为"<<rubb<<endl;

            snum++;

        }

            

            chken++;

    }

    cout<<"总可能性为"<<snum<<endl;

    return 1;



}









//********单链表的的问题***********************



//定义一个链表节点

//单向链表节点

struct node

{

    int data;

    node *next;



}Node;

//双向链表节点

struct dnode

{

    int data;

    dnode *left;

    dnode *right;



}Dnode;

//创建并初始化单链表

struct node * Initlist(int n)

{

    node *head;

    head=(node*)malloc(sizeof(node));

    head->next=NULL;

    head->data=0;

    node *p=head;

    int data=0;

    int i=0;

    while(i<n)

    {

       node *L;

       L=(node*)malloc(sizeof(node));

       cin>>data;

       p->next=L;

       L->data=data;

       p=L;

       i++;

    }

    p->next=NULL;

    return head;





}



//单链表输出

void puts(struct node *head)

{

    node * p=NULL;

    for(p=head->next;p!=NULL;p=p->next)

        cout<<p->data<<" ";

    cout<<endl;



}



//单链表就地逆置

//思路很简单就是 用三个变量,P用来循环节点,r用来控制最后一个节点被连接上,q是最重要的中间节点。

void Reverselist(struct node *head)

{

    node *p=head->next;

    node *q=NULL;

    node *r=NULL;

    while(p)

    {

        r=q;

        q=p;

        p=p->next;

        q->next=r;

    

    

    }

    head->next=q;

}





//带尾指针的循环单链表,有很多好处,其中之一就是找最后一个元素的时候不需要遍历整个链表,但凡涉及到不需要遍历的

//尽量考虑尾指针单链表的情况。



//两个链表A,B有序,合并成一个依然有序的单链表C,注意不要增加空间复杂度



int mubble(node *ListA,node *ListB)

{

    node *p=NULL;

    p=ListA->next;

    node *q=NULL;

    q=ListB->next;

    node *c=NULL;



    while(p->next!=NULL&&q!=NULL)

    {

        while(p->data<=q->data&p!=NULL)

        {

            c=p;

            if(p->next!=NULL)

              p=p->next;

        }

        c->next=q;    

        while(q->data<=p->data&&q!=NULL)

        {

            c=q;

            if(q->next!=NULL)

            q=q->next;

        }

        c->next=p;

    }

    c->next=q;

    return 1;

}





//编写string类的构造函数、析构函数、赋值

class String

{

public:

    String(const char *str=NULL);

    String(const String &other);

    ~String();

    String & operator =( const String &other);

    

private:

    char *data;



};



String::String(const String &other)

{

    int len=strlen(other.data);

    data=new char(len+1);

    strcpy(data,other.data);

}



String::~String()

{

    delete [] data;



}



String & String::operator =( const String &other)

{

     if(this == &other)

        return *this;

    delete [] data;

    int length = strlen(other.data);  

    data = new char[length+1];

    strcpy(data, other.data);

    return *this;

}





void main()

{

//    char instr[]="ppddsdpp";

//    char neinstr[]="5 - 15";

//    int n=sizeof(instr);

    //char outstr[100]={ };

    //char aa[]="hello";

    //char cstr[]="a3c3hello212my221dd22www";

    //stringFilter(instr,n,outstr);

    //stringZip(instr,n,outstr);

    //arithmetic(neinstr,n,outstr);

    //cout<<aa<<endl;

    //cout<<outstr<<endl;

    //cout<<noutstr<<endl;

    //convert(cstr,outstr);

    //my_word(cstr,outstr);

    //cout<<outstr<<endl;

    /*int a=121;

    bool f=isPrimNumber(a);

    if(f)

        cout<<"这是一个素数"<<endl;

    else

        cout<<"这不是一个素数"<<endl;*/



    

    

    /*int ary[6]={4,4,21,1,2,23};

    int k=func(ary,6);

    cout<<k;*/



    /*int i=12344221;

    bool f=isPlalindromeNumber(i);

    if(f)

        cout<<"这是一个回文"<<endl;

    else

        cout<<"这不是一个回文"<<endl;

    getPrim(100); */



    //int a=230;

    //cout<<func(a)<<endl;

    //int a[10]={2,34,5,22,212,32,43,12,9,12};

    //InsertionSort(a,10);

    //SelectSort(a,10);

    //BubleSort(a,10);

    //Qsort(a,0,9);

    //for(int i=0;i<10;i++)

    //    cout<<a[i]<<" ";

    /*int b=5;

    int  * const p=&b;

    int a=12;

    int  * const r=&b;

    const int * p=&a;

    int k=6;

    //p=&k;

    b=k;

    cout<<b<<endl;*/

    //char *ss="hello";

    //int p=sizeof(ss);

    //int q=strlen(ss);

    //cout<<p<<q;

    //int a=0;

    //char b='a';

    





    //char str[]="1000";

    //int k=parseInt(str,2);

    //cout<<k;

    

    //lag(100);

    struct node * L1=Initlist(5);

    struct node * L2=Initlist(7);

    puts(L1);

    puts(L2);

    mubble(L1,L2);

    //Reverselist(L1);

    puts(L1);

    system("pause");



}

 

你可能感兴趣的:(算法)