[笔试]常考算法
#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"); }