美文网首页
字符串相关笔试题

字符串相关笔试题

作者: eesly_yuan | 来源:发表于2014-08-07 13:53 被阅读1149次

在进行相关编程之前必须进行一些条件判断
1、有效性判断,给定字符串是否为空,长度是否为1,长度为1表明可能不需要后续的操作了;
2、与整数有关,则需要考虑正负号问题,还必须考虑精度问题。
3、不要急于编写,先做全面的分析


字符串的操作
  • 题1:实现strcpy,原型char * mystrcpy(char * src, char *dest)
  • 分析:先判定是否是NULL指针,再进行相应的操作;返回是char*是为了链式操作;strcpy的目的存储空间一定要大于等于源的存储空间。
char * mystrcpy(char * src, char *dest)
{
     if(src==NULL || dest==NULL)
          return NULL;
     char * rs = dest;
     while((*dest++ ==  *src++)!='\0');
     return rs;
}

  • 题2:将整数转化为字符串
  • 分析:实际是写itoa函数,先判断正负,如果是负的先转为正的,可以先将每个数字提取出来(采用先对10求余,再除10的方法)再加'0'。
void myitoa(int num, char * str)
{
     char temp[20];
     bool sig = true;
     if(num<0)
     {
          *str++ = '-';
          sig = false;
     }
     int i = 0;
     while(num)
     {
          temp[i++]=(sig?num%10:-(num%10))+'0';
          num /= 10;
     }
     while(i--)
          *str++= temp[i];
     *str = '\0';
}

  • 题3:字符串循环左右移问题
  • 分析:若对使用空间没有限制,则利用strcpy即可,如对空间有要求可以考虑使用翻转。
//字符串左移step位
void myreverse(char * str,int p1, int p2)
{
    while(p1<p2)
    {
        *(str+p1) ^= *(str+p2);
        *(str+p2) ^= *(str+p1);
        *(str+p1) ^= *(str+p2);
        p1++;
        p2--;
    }
}
void strleftmove(char * str, int step)
{
    if(str == NULL)
        return;
    int n = strlen(str);
    myreverse(str,0,step-1);
    myreverse(str,step,n-1);
    myreverse(str,0,n-1);
}

  • 题4:去除一个顺序排序的字符串中的重复字符
  • 分析:由于是排序过的,只要比较相邻的两个是否相等,若不相等则把上一个输出即可。
//去除顺序的重复的字符串
void deleteduplicate(char * str)
{
    if(str == NULL)
        return;
    int num = strlen(str);
    cout<<str[0];
    for(int i = 1; i<num; i++)
        if(str[i]!=str[i-1])
            cout<<str[i];
    cout<<endl;
}

  • 题5:寻找一个字符串中存在相同的最长子串
  • 分析:寻找最长子串,因此可以从最长的子串开始查找,存在相同的子串可以采用,从左往右找和从右往左找,如果存在不同的话返回的序号应该不一致
//查找相同的且长度最长的子串
void maxSameSubstr(string str)
{
    int i,j;
    int num = str.length();
    string substr;
    for(i = num - 1; i>0; i--)      //从最大的子串开始
        for(j = 0; j <num -i;j++)
        {
            substr = str.substr(j,i);
            if (str.find(substr) != str.rfind(substr))
            {
                cout<<substr<<" "<<str.find(substr)<<endl;
                return;
            }
        }
}

  • 题6:数字压缩,例如11111222223转换成515213
  • 分析:只需要计算处前后有多少个相同的数即可
void zipNum1(char * str)
{
    if (str == NULL)
        return;
    int len = strlen(str);
    int sublen = 1;
    int i = 1;
    for(i = 1; i<len; i++)
    {
        if (str[i]!=str[i-1])
        {
            cout<<sublen<<str[i-1];
            sublen = 1;
        }           
        else
            sublen++;
    }
    cout<<sublen<<str[i-1];
}

给定一个输入的字符串和一个包含各种单词的字典,用空格将字符串分割成一系列字典中存在的单词。举个例子,如果输入字符串是“applepie”而字典中包含了所有的英文单词,那么我们应该得到返回值“apple pie”。
注意,我故意没有解释或者漏掉了一些细节,从而给候选人一个弄清楚问题的机会。 这里我举一些候选人可能会问的问题,以及我会如何回答
问:如果输入字符串本身是一个单词怎么办?
答:可以把它看作一个特殊情况。
问:我只用考虑分割成两个单词的情况吗?
答:不,但是可以从这种情况开始。
问:如果输入字符串无法被分割成单词怎么办?
答:返回null或者类似的东西。
问:有变位或者拼写错误怎么办?
答:只需要严格分割成字典中有的单词。
问:如果有多种分割可能性怎么办?
答:只需要返回任何一个正确的答案。
问:我在想将字典用前缀树,后缀树,Fibonacci堆实现…
答:你不用实现字典。只需要假设它已经被合理地实现了。
问:字典支持哪些操作?
答:字符串查询——这就是你所需要的全部
问:字典有多大?
答:假设它远远大于输入字符串,但足够装入内存。

  • 根据提示写了一个较为通用的写法,采用递归实现,从深递归回溯到现在可以发现其复杂度为O(2^n)。至于动态规划的实现不是很了解,还有待学习动态规划
string segmentStr(string str,set<string> &disc)
{
    if (disc.find(str)!=disc.end())
        return str;
    for (int i = 1; i<str.length(); i++)
    {
        string substr = str.substr(0,i);
        if (disc.find(str)!=disc.end())
        {
            string reback = segmentStr(str.substr(i,str.length()-i),disc);
            if (!reback.empty())
                return substr+" "+reback;
        }
    }
    string s;
    return s;
}

reference

相关文章

网友评论

      本文标题:字符串相关笔试题

      本文链接:https://www.haomeiwen.com/subject/dkletttx.html