[笔试]常考算法

#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");

}

 

posted @ 2013-10-16 16:01  明珠交到我手上  阅读(341)  评论(0编辑  收藏  举报