致我们终将忘记的算法(千变万化字符串)

来源:互联网 发布:如何注册公司网站域名 编辑:程序博客网 时间:2024/06/09 23:43

1->判断一个字符串是不是回文字符串,不考虑字符串的大小写和标点符号。例如:“A man,a plan,a canal:Panama”是一个回文串。而“race a car”则不是一个回文串

解题方法:没有什么特别的技巧,左右逐个比较久OK了,就是在代码的书写过程注意细节问题。

bool isPalindrome(string s){

    tranform(s.begin(),s.end(),s.begin(),::tolower);                           //将字符串转为小写的

    String::iterator left=s.begin(),right=s.end()--;

    while(left<right){

        if(!::isnalnum(*left))   left++;

        else if(!::isnalnum(*right))  right--;

        else if(*right!=*left)  return false;

    }

    return true;

}

 

2->字符串匹配算法

解题方法1:暴力匹配:时间复杂度O(M*N)  空间复杂度O(1)

char *strStr(char *haystack,char *needle){

    int len_h=strlen(haystack);

    int len_n=strlen(needle);

    if(len_h<len_n)   return NULL;

    else if(len_h==len_n){

        if(strcmp(haystack,needle))   return NULL;

        else return haystack;

    }

    for(int i=0;i<len_h-len_n;i++){

        bool flag=true;

        for(int j=0;j<len_n;j++){

               if(haystack[i+j]!=needle[j]){flag=false; break;}

        }

        if(flag) return haystack+i;

    }

    return NULL;

}

解题方法2:KMP算法:时间复杂度O(m+n),空间复杂度O(M)

void compute_prefix(const char *pattern,int next[]){

    const int m=strlen(pattern);

    int j=0;    next[1]=0;

    while(i<m){

        if(j==0 || pattern[i]==pattern[j]){++i;++j;next[i]=j;}

        else j=next[j];

    }

}

int Kmp(const char *text,const char *pattern){

    const int n=strlen(text);

    const int m=strlen(pattern);

    if(n==0&&m==0) return 0;

    if(m==0) return 0;

    int *next=(int *)malloc(sizeof(int)*m);

    comptue_prefix(pattern,next);

    int i=1,j=1;

    while(i<=m && j<=n){

        if(j==0||text[i]==pattern[j]){++i,++j}

        else j=next[j];

    }

    if(j>m) return i-m;

    else return 0;

}

 

3->将字符串转化为对应的整数,即实现atoi库函数的功能

解题方法:该题没有什么特别的技巧,要注意代码实现的细节,例如前导空格,+和-号问题,还有就是字符串中出现的非数字字符问题,要细致处理。

int atoi(const char *str){

    int num=0;

    int sign=1;

    const int n=strlen(str);

    int i=0;

    while(str[i]==' '&&i<n) i++;    //去掉前导空格

    if(str[i]='+') i++;

    else if(str[i]=='-'){ sign=-1;i++;}   //设置符号为减号

    for(;i<n;i++){

        if(str[i]<'0' || str[i]>'9') break;     //处理非数字符号问题

        if(num>INT_MAX/10 ||(num==INT_MAX/10  &&(str[i]-'0')>INT_MAX%10)){return sign==-1 ?INT_MIN:INT_MAX;}  //处理越界问题

        num=num*10+str[i]-'0';

    }

    return num*sign;

}

 

4->两个字符串表示的二进制数相加

String addBinary(string a,string b){

    string result;

    const int n=a.size()>b.size()?a.size():b.size();

    reverse(a.begin(),a.end());

    reverse(b.begin(),b.end());

    int carry=0;

    for(int i=0;i<n;i++){

         const int ai=i<a.size()?a[i]-'0':0;

         const int bi=i<b.size()?b[i]-'0':0;

         const int val=(ai+bi+carry)%2;

         carry=(ai+bi+carry)/2;

         result.insert(result.begin(),val+'0');

    }

    if(carry==1)  result.insert(result.begin(),'1');

    return result;

}


5->最长回文子串

解题方法:以源字符串的每个字符为中心,向左右扩展,求回文字符串的长度,(注意以字符为扩展中心,有两种情况,第一回文串的长度为偶数,和回文字符串的长度为奇数两种不同的情况。)

int Palindromic(const string& str,int i,int j){                                      //判断一个子字符串是否为回文字符串

    int n=str.size()  , curlen=0;

    while(i>=0  && j<n  &&str[i]==str[j]){

        i--;  j++;

    }

     curlen=(j-1)+(i+1)+1;

     return curlen;

}

string longestPalindrome(string s){

    int n=s.length();

    int startPos=0 ,maxlen=1;

    for(int i=0;i<n;i++){

        int oddlen=0, evenlen=0;

        int curlen=0;

        oddlen=Palindromic(s,i,i);

        if(i+1<n)    evenlen=Palindromic(s,i,i+1);

        if(curlrn>max){ 

            max=len;

            if(max &0x1)  startPos=i-max/2;

            else startPos=i-(max-1)/2; 

        }

    }

    return s.substr(startPos,max);

}


6->正则表达式字符串匹配问题,其中‘.’代表任意一个字符串,‘*’代表任意多个或者0个字符

解题方法:采用递归的方式,主要以当前字符的下一个字符是否为‘*’展开判断。

bool isMatch(const char *s,const char *p){

    if(*p=='\0') return s=='\0';

    if(*(p+1)!='*'){

        if(*p==*s || (*p=='.' && *s!='\0'))    return isMarch(s+1,p+1);

        else  return false;

    }else{

        while(*s==*p ||(*p=='.'  && *s!='\0')){

            if(isMatch(s,p+2))    return true;

            s++;

        }

        return isMatch(s,p+2);

    }

}


7->通配符字符串匹配(其中‘?’代表任意一个字符,‘*’代表任意多个或者0个序列)要求两个字符串要完全匹配

解题方法:递归版:

bool isMatch(const char *s,const char *p){

    if(s==NULL || p==NULL)    return false;

    if(*p=='\0')  return *s=='\0';

    if(*p=='*'){

        while(*p=='*') ++p;

        while(*s!='\0'){ if(isMatch(s,p))    return true;   s++;}

        return isMatch(s,p);

    }else{

         if((*s!='\0' && *p=='?') || *s==*p)  return isMatch(s+1,p+1);

    }

    return false;

}


8->求所有字符串的最长公共前缀

解题方法:

string longestCommonPrefix(vector<string> &strs){

    if(strs.empty())   return "";

    for(int idx=0;idx<str[0].size();idx++){

         for(int i=1;i<strs.size();i++){

               if(strs[i][idx]!=strs[0][idx]) return strs[0].substr(0,idx);

          }

    }

    return strs[0];

}


9->判断一个字符串是否可以转化为正确的浮点数

解题方法:调用标准库函数中的strtod来实现

bool isNumber(char const *s){

    char *endptr;

    strtod(s,&endptr);

    for(endptr==s)    return false;

    for(;*endptr;++endptr)

        if(!isspace(*endptr))    return false;

    return true;

}


10->将阿拉伯数字转化为罗马数字

string intToRoman(int num){

    const int radix[]={1000,900,500,400,90,50,40,10,9,5,4,1};

    const string symbol[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};

    string roman;

    for(size_t i=0;num>0;i++){

        int count=num/radix[i];

        num%=radix[i];

        for(;count>0;--count) roman+=symbol[i];

    }

    return roman;

}


11->将罗马数字转化为阿拉伯数字

inline int map(const char c){

    switch(c){

        case 'I':return 1;

        case 'V':return 5;

        case 'X':return 10;

         case 'L':return 50;

         case ‘C’:return 100;

         case ‘D’:return 500;

         case ‘M’:return 1000;

         default:  return 0;

   }

    int romanToInt(string s){

         int result=0;

         for(int i=0;i<s.size();i++){

                if(i>0 &&map(s[i])>map(s[i-1])){

                     result+=(map(s[i])-2*map(s[i-1]));

                }else{

                    result+=map(s[i]);

                 }

         }

    }

      return result;

}


12->求出第n个countAndSay序列。其中countAndSay序列为:1->one 1->11   11->two 1->21

解题方法:安装题意即可完成

string getNext(const string &s){

    stringstream ss;

    for(string::iterator it=s.begin();it!=s.end();){

          auto j=find_if(it,s.end(),bind1st(not_equal_to<char>,*it));

           ss<<distance(it,j)<<*it;

           it=j'

    }

    return ss.str();

}

string countAndSay(int n){

    string s("1");

    while(--n){

         s=getNext(s);

    } 

    return s;   

}


13->返回一组单词中的所有回文构词法的单词

解题方法:回文构词法,只是将单词的顺序调换,所有如果两个单词有同样的一种排序,两个单词就是回文词

vector <string> anagrams(vector<string> &strs){

    map<string,vector<string>>  group;

    for(int i=0;i<strs.size(),i++){

        string key=strs[i];

        sort(key.begin(),key.end());

        group[key].push_back(s);

    }

    vector<string> result;

    for(vector<string>::it=group.begin();it!=group.end();it++){

         if(it->second.szie()>1)

                result.insert(result.end(),it->second.begin(),it->second.end());

         return result;

    }

}


14->求出一串句子的最后一个单词的长度

解题方法:调用string的库函数find_if  和find_if_not 可以确定最后一个单词的开始和结束位置,自然很容易求出最后一个单词的长度

int lengthOfLastWord(const char *s){

    const string str(s);

    auto first=find_if(str.rbegin(),str.rend(),::isalpha);

    auto last=find_if_not(first,str.rend(),::isalpha);

    return distance(first,last);

}


15->将一个复杂的文件路径转化为简单的文件路径(按照Linux文件路径访问方式)

解题方法:栈的方式

string simplifyPath(const string &path){

    vector<string> dirs;

    for(string::iterator it=path.begin();i!=path.end();){

         it++;

          string::iterator j=find(i,path.end(),'/');

          string dir=string(i,j);

          if(!dir.empty() && dir!='.'){

                  if(dir==".."){

                         if(!dirs.empty())  dirs.pop_back();

                  }

                  else  dirs.push_back(dir);

          }

          i=j;

    }

    stringstream out;

    if(dirs.empty()) out<<"/";

    else{

          for(auto dir:dirs) out<<'/'<<dir;

     }

     return out.str();

}

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 去英国留学不会做饭怎么办 小米陶瓷刀钝了怎么办 橱柜的缝擦不到怎么办 悠悠球上油早了怎么办 买了没有esp的车怎么办 饥荒海难狗来了怎么办 饥荒海难拖网掉水里了怎么办 饥荒遇到了猪人怎么办 饥荒龙蝇赖在家不走怎么办 饥荒海难崩档了怎么办 gta5全是rpf文件怎么办 饥荒没有海象人营地怎么办 饥荒海滩猎犬来了怎么办 宝宝换牙门牙上长颗尖牙怎么办 肉卡在牙缝里怎么办 电脑做系统卡死怎么办 苹果6升级太卡怎么办 电脑玩不了联机饥荒怎么办 饥荒渡渡鸟死了一只怎么办 饥荒电脑联机植物生病怎么办 开车蹭到别人车怎么办 立定跳不会收腹怎么办 1岁宝宝有蛔虫怎么办 手机屏幕总是有网页跳出来怎么办 cs游戏屏幕变成正方形怎么办 大王卡被收回了怎么办 模拟人生4小人生病了怎么办 创造与魔法死后怎么办? 脚不小心扭伤了该怎么办 小鸡脚扭伤了该怎么办 跳高比赛最终成绩相等怎么办 热车1200怠速降不下来怎么办 大腿根骨髓水肿越来越疼怎么办 倒库方向打晚了怎么办 签吻芳颜祛斑液脸脱皮怎么办 3d右边工具栏消失了怎么办 3d菜单栏消失了怎么办 觉得自己性无能不敢谈对象怎么办 护士面试时被问到病人坠床怎么办 三次元仪器坏了怎么办 运动同手同脚怎么办