Chinaunix

标题: 一道百度笔试题 [打印本页]

作者: kewenliang    时间: 2008-09-16 15:33
标题: 一道百度笔试题
编程实现把中英文混合字符串(汉字用两个字节表示,特点是第一个字节的最高位为1)中的大写字母转化为小写字母。
作者: emacsnw    时间: 2008-09-16 15:42
直接用tolower或者isupper之后+32不行吗?
作者: cugb_cat    时间: 2008-09-16 15:45
isupper判断成立后加32?
作者: lemonniu    时间: 2008-09-16 15:47
怎么百度天天有面试体??
RT!
作者: cugb_cat    时间: 2008-09-16 15:52
原帖由 lemonniu 于 2008-9-16 15:47 发表
怎么百度天天有面试体??
RT!

天天有人去面百度呗,呵呵。。
作者: blizzard213    时间: 2008-09-16 15:55
原帖由 lemonniu 于 2008-9-16 15:47 发表
怎么百度天天有面试体??
RT!


百度这次好像只招几十个吧 中奖率不如回头去重读高中考清华北大
作者: kewenliang    时间: 2008-09-16 16:13
原帖由 cugb_cat 于 2008-9-16 15:45 发表
isupper判断成立后加32?

遇到汉字怎么处理啊?
作者: cugb_cat    时间: 2008-09-16 16:14
原帖由 kewenliang 于 2008-9-16 16:13 发表

遇到汉字怎么处理啊?

汉字的两个字节都是大于127的。。
isupper返回假。。
作者: 5毛党党员    时间: 2008-09-16 16:18
原帖由 blizzard213 于 2008-9-16 15:55 发表


百度这次好像只招几十个吧 中奖率不如回头去重读高中考清华北大

我怎么听说这次要200多,不过可能不都是技术
作者: kewenliang    时间: 2008-09-16 16:48
原帖由 cugb_cat 于 2008-9-16 16:14 发表

汉字的两个字节都是大于127的。。
isupper返回假。。

大佬能否给写一下啊?
作者: Godbach    时间: 2008-09-16 16:49
百度的试题天天都有啊,不知道做了这些题是否可以去百度了
作者: wilbur512    时间: 2008-09-16 16:53
一个字节一个字节的判断

char a;


如果首位是1  if(a&0x80),跳1个字节 a++;

如果首位不是1 说明是英文字符

   int d='a'-'A';
if(a>='A'&&a<='Z')
     a+=d;
作者: aliking    时间: 2008-09-16 17:36
标题: 回复 #1 kewenliang 的帖子
不知道有什么要求。
用什么编程语言?输入字符串和输出字符串是不是同一个?

下面是用C实现的,输入和输出字符串用同一个。
  1. void lower(char *s)
  2. {
  3.         while(*s != '\0')
  4.         {
  5.                 if (*s & 0x80)  /* chinese character */
  6.                         s++;
  7.                 else if ((*s >= 'A') && (*s <= 'Z'))
  8.                         *s |= 0x20;   /* to lower case */
  9.                 s++;
  10.         }
  11.         return;
  12. }
复制代码

[ 本帖最后由 aliking 于 2008-9-16 17:39 编辑 ]
作者: emacsnw    时间: 2008-09-16 17:40
原帖由 aliking 于 2008-9-16 01:36 发表
不知道有什么要求。
用什么编程语言?输入字符串和输出字符串是不是同一个?

下面是用C实现的,输入和输出字符串用同一个。
void lower(char *s)
{
        while(*s != '\0')
        {
             ...


这个 if 分支是多余的吧。呵呵。
作者: aliking    时间: 2008-09-16 17:47
原帖由 emacsnw 于 2008-9-16 17:40 发表


这个 if 分支是多余的吧。呵呵。


当然不是多余的,因为汉字的第二个字节也有可能为'A'~'Z'间对应的ASCII码。
比如"燗"这个字,16进制编码为0xA041,而0x41是字符'A'对应的ASCII编码。
作者: tyc611    时间: 2008-09-16 17:58
百度面试题有这么简单么?
作者: cugb_cat    时间: 2008-09-16 18:00
原帖由 tyc611 于 2008-9-16 17:58 发表
百度面试题有这么简单么?

我也感觉不对劲,呵呵。。
作者: weiqiboy    时间: 2008-09-16 19:16
int lower(char * str)
{
    char *p = str;
    char *q = str + strlen(str);
    while(P < q){
        if(*p & 0x80)
        {   P+=2;
            if(p > q)
               return 0;
        }      
        else if (*p >= 'A' && *p <= 'Z')
        {    (*p) |= 0x20;
             p++;
        }
        else
            p++;
    }
    return 1;
}

作者: GodPig    时间: 2008-09-16 20:56
汉字的最高字节位为1
byte *ptr = string;
while (*ptr)
{
   if (*ptr & 0x80)
      continue;
   //此处再对大写字母进行处理
}
作者: openq    时间: 2008-09-17 10:54
原帖由 aliking 于 2008-9-16 17:36 发表
不知道有什么要求。
用什么编程语言?输入字符串和输出字符串是不是同一个?

下面是用C实现的,输入和输出字符串用同一个。
void lower(char *s)
{
        while(*s != '\0')
        {
             ...

第二个 else 中的if是多余的
不管大小写 &0x20 就行
作者: weiqiboy    时间: 2008-09-17 11:20
我觉得有的答案没有考虑到字符串出错的情况,如果在串的最后一个字节符合汉字字符最高位的要求,即高位为1,这显然是错误的
作者: aliking    时间: 2008-09-17 18:05
原帖由 weiqiboy 于 2008-9-17 11:20 发表
我觉得有的答案没有考虑到字符串出错的情况,如果在串的最后一个字节符合汉字字符最高位的要求,即高位为1,这显然是错误的


你说的情况确实存在,谢谢!
我当时虽然也考虑到了这一点,但草率的认为这种输入合法性是应该留给调用者处理的。
看了你的回复,我经过仔细考虑,认为这种情况还是应该由被调用者处理的。

修改后的代码如下:

  1. void lower(char *s)
  2. {
  3.         while (*s)
  4.         {
  5.                 if  (*s & 0x80)          /* chinese character */
  6.                 {
  7.                         if  (!(*++s))      /* the string is terminated here */
  8.                                 return;
  9.                 }
  10.                 else if  (*s >= 'A' && *s <= 'Z')
  11.                         *s |= 0x20;      /* to lower case */
  12.                 s++;
  13.         }
  14.         return;
  15. }
复制代码

[ 本帖最后由 aliking 于 2008-9-17 20:15 编辑 ]
作者: aliking    时间: 2008-09-17 18:09
原帖由 openq 于 2008-9-17 10:54 发表

第二个 else 中的if是多余的
不管大小写 &0x20 就行

如果其中有会车换行等字符怎么办?不要告诉我你处理文本时从来不会遇到这种情况。
而且,这里为什么要用“&”而不用“|”呢?
作者: 雨过白鹭洲    时间: 2008-09-17 21:10
谁说汉字是两个字节。。。
作者: aliking    时间: 2008-09-17 23:52
原帖由 雨过白鹭洲 于 2008-9-17 21:10 发表
谁说汉字是两个字节。。。

参见1楼帖子原题描述。
作者: guohua219    时间: 2008-09-18 09:02
学习一下
作者: babyyellow    时间: 2008-09-18 13:41
既然是字符串,

那么就要判断标点符号,这些都要考虑进去
作者: ytl    时间: 2008-09-18 13:49
面试不会出这种题的,考察不出能力
作者: cjaizss    时间: 2008-09-18 14:11

  1. sed 's/[A-Z+]/\L&/g'
复制代码

[ 本帖最后由 cjaizss 于 2008-9-18 14:34 编辑 ]
作者: kewenliang    时间: 2008-09-18 17:08
昨晚参加百度的笔试,今天下午去面试时被鄙视了,提出了问题基本都不会,人家直接说:不好意思。。。。。。。。。
作者: bel5f5    时间: 2008-09-18 20:38
char *tolower(char *p) {
    char *src = p;
    int diff = 'a' - 'A';
   
    for (; src != NULL && *src; ++src) {
        if (*src&0x80) {
            if ((++src == NULL) || !*src)
                break;
        } else if (*src >= 'A' && *src <= 'Z') {
            *src += diff;
        }                        
    }  
    return p;  
}
作者: jronald    时间: 2008-09-19 08:37
这个也考?
百度一下不就可以了?
作者: lenky0401    时间: 2008-09-19 08:44
原帖由 kewenliang 于 2008-9-18 17:08 发表
昨晚参加百度的笔试,今天下午去面试时被鄙视了,提出了问题基本都不会,人家直接说:不好意思。。。。。。。。。


精灵王都不会?
作者: 焚书煲粥    时间: 2008-09-19 11:18
虽然题目挺简单,不过楼上所有回帖全都不对。。。
正解显然是打表
作者: merlyncaulfield    时间: 2008-09-19 11:46
有必要把面试题搞上来讨论么?
作者: lihao102    时间: 2008-09-19 14:14
汉字的两个字节的高位都是1啊,ASCII值都是负数,知道这个了,就好办了啊。
作者: tlzhu    时间: 2008-09-19 15:01
标题: 试着写了一个,不知道对不对
char tmp[128];
        strcpy(tmp, "helloWorld你好you");
        cout << tmp << endl;
       
        int c;
        int pos = 0;
        int len = strlen(tmp);
        cout << "length: " << len << endl;
       
        do
        {
                c = (int)tmp[pos];
                if (c>127)
                {
                        pos++;
                }
                else
                {
                        tmp[pos] = isupper(tmp[pos]) ? tmp[pos] : toupper(tmp[pos]);
                }       
                pos++;
        }while(pos < len);
        cout << tmp << endl;
作者: heiyeluren    时间: 2008-09-19 16:03
拿php实现一下,原理差不多:

  1. <?php
  2. function tolower(&$s){
  3.         $len = strlen($s);
  4.         for($i=0; $i<$len; $i++){
  5.                 $t = ord($s[$i]);
  6.                 if ($t>128 && $t<255){$i++;continue;}
  7.                 if($t>=65 && $t<=90)$s[$i] = strtolower($s[$i]);
  8.         }
  9.         return $s;
  10. }
  11. //Test code
  12. $s = "这是一段TEST TEXT,里面夹杂了English和Chinese,还有一些数字,比如123456";
  13. echo tolower($s);
  14. //output: 这是一段test text,里面夹杂了english和chinese,还有一些数字,比如123456[~]$
  15. ?>
复制代码

作者: 虑而后能得    时间: 2008-09-19 19:09
原帖由 emacsnw 于 2008-9-16 15:42 发表
直接用tolower或者isupper之后+32不行吗?

支持
作者: zw047    时间: 2008-09-19 20:03
不是baidu的面试题
作者: dingweiqi    时间: 2008-09-19 21:54
提示: 作者被禁止或删除 内容自动屏蔽
作者: wangqi0021    时间: 2008-09-19 21:55
原帖由 kewenliang 于 2008-9-16 16:48 发表

大佬能否给写一下啊?

UTF8是1110**** 10****** 10******
GBK不清楚
作者: ssafa    时间: 2008-09-19 23:10
我的笨办法就是一个字节一个字节的比较,如果大于0x7F就跳过下一个,直接读第三个,然后判断是不是大写字母
作者: pingtunao89    时间: 2008-09-20 06:42
提示: 作者被禁止或删除 内容自动屏蔽
作者: pingtunao89    时间: 2008-09-20 07:07
提示: 作者被禁止或删除 内容自动屏蔽
作者: xishagu39    时间: 2008-09-20 10:31
提示: 作者被禁止或删除 内容自动屏蔽
作者: xishagu39    时间: 2008-09-20 16:08
提示: 作者被禁止或删除 内容自动屏蔽
作者: tanzhuomei71    时间: 2008-09-20 18:12
标题: 回复 #1 kewenliang 的帖子
两个字节表示,特点是第一个字节的最高位为1
作者: tanzhuomei71    时间: 2008-09-20 20:34
标题: 回复 #1 kewenliang 的帖子
实现把中英文混合字符
作者: cxhcjq    时间: 2008-09-21 11:34
谁发一个完整的程序SEE,SEE
作者: pizzx    时间: 2008-09-21 13:05
原帖由 aliking 于 2008-9-17 18:05 发表


你说的情况确实存在,谢谢!
我当时虽然也考虑到了这一点,但草率的认为这种输入合法性是应该留给调用者处理的。
看了你的回复,我经过仔细考虑,认为这种情况还是应该由被调用者处理的。

修改后的代码 ...



我觉得也可以在while中判断,这样同时也对入参s进行了为空判断。
void lower(char *s)
{
        while (s != NULL && *s) //         {
                ....
        }

个人看法。
作者: bingfeng2hzy    时间: 2008-09-22 22:59
今天笔试百度,这一道题一点不会,各位看看:
有一序列Seq=[a,b,...,z,aa,ab,...,az,ba,bb,....,zz,za,zb,....,zzz,....],
现在有一字符串s=[a-z]+(由a-z组成的任意长的字符串),问s是Seq的第几个字符串?
大体意思就这样.
作者: 以泪洗面    时间: 2008-09-23 16:36
原帖由 bingfeng2hzy 于 2008-9-22 22:59 发表
今天笔试百度,这一道题一点不会,各位看看:
有一序列Seq=[a,b,...,z,aa,ab,...,az,ba,bb,....,zz,za,zb,....,zzz,....],
现在有一字符串s=[a-z]+(由a-z组成的任意长的字符串),问s是Seq的第几个字符串?
大体意 ...


每一个字符串都是啊
我没看明白?
作者: bingfeng2hzy    时间: 2008-09-23 19:22
原帖由 以泪洗面 于 2008-9-23 16:36 发表


每一个字符串都是啊
我没看明白?

是啊!我也看不懂.
作者: yixineryi    时间: 2008-09-24 13:00
标题: 百度
百度还挺牛。
作者: jeyochen    时间: 2008-09-24 20:31
这个问题不是加32那么简单。我认为要逐个字节的去判断,首先要判断当前字节的ASCII码是不是在字符的范围内,如果不在字符的范围内则跳过两个字节,如果在字符范围内,再判断是不是在大写的字符范围内,如果是那么就加32,如果不是就进行下一个字节的比较
作者: xwolff    时间: 2008-09-25 10:09
for ( i = 0; i < maxline; i++ )
{
    for ( j = 0; j < strlen( aa ); j++ )
    {
          if ( aa[j] <= 'Z' && aa[j] >= 'A' ) aa[j] += 32;
    }
}


[ 本帖最后由 xwolff 于 2008-9-25 10:11 编辑 ]
作者: aliking    时间: 2008-09-25 11:06
原帖由 bingfeng2hzy 于 2008-9-22 22:59 发表
今天笔试百度,这一道题一点不会,各位看看:
有一序列Seq=[a,b,...,z,aa,ab,...,az,ba,bb,....,zz,za,zb,....,zzz,....],
现在有一字符串s=[a-z]+(由a-z组成的任意长的字符串),问s是Seq的第几个字符串?
大体意 ...


看成26进制数计算就可以了。基本实现如下:

  1. int sequence(char* str)
  2. {
  3.         int i,  ret = 0;
  4.         for (i = 0; i < strlen(str); i++)
  5.         {
  6.                 ret *= 26;
  7.                 ret += str[i] - 'a' + 1;
  8.         }
  9.         return ret;
  10. }
复制代码

严谨点可以判断一下字符串的长度、整数溢出等。

[ 本帖最后由 aliking 于 2008-9-25 11:16 编辑 ]
作者: xwolff    时间: 2008-09-25 11:08
void convert( char *s )
{        int i = 0;
          while ( s )      
         {               
         // 只要是大写字符,最高位肯定不是1               
        if ( s <= 'Z' && s >= 'A' ) s += 32;   
        }
}


[ 本帖最后由 xwolff 于 2008-9-25 11:12 编辑 ]
作者: zuii    时间: 2008-09-25 19:57
这题在百度之星出过的~处理汉字编码问题
作者: pingtunao89    时间: 2008-09-26 08:15
提示: 作者被禁止或删除 内容自动屏蔽
作者: pingtunao89    时间: 2008-09-26 08:48
提示: 作者被禁止或删除 内容自动屏蔽
作者: pingtunao89    时间: 2008-09-26 10:10
提示: 作者被禁止或删除 内容自动屏蔽
作者: pingtunao89    时间: 2008-09-26 10:12
提示: 作者被禁止或删除 内容自动屏蔽
作者: aliking    时间: 2008-09-26 10:29
原帖由 pingtunao89 于 2008-9-26 08:48 发表
大写字母转化为小写字母

是写了一个机器人程序赚积分吗?怎么总是重复发无意义的回复,浪费大家时间。
作者: xishagu39    时间: 2008-09-26 18:21
提示: 作者被禁止或删除 内容自动屏蔽
作者: zhonghan    时间: 2008-09-26 22:32
提示: 作者被禁止或删除 内容自动屏蔽
作者: youxiaohe    时间: 2008-09-27 11:19
百度去年招人太多了,今年不回要多少的
作者: 312-pirl0    时间: 2008-10-21 18:14
Baidu又怎么吗,why我们就不能去。
作者: samon_fu    时间: 2008-10-21 18:35
标题: 回复 #1 kewenliang 的帖子
印象中有些C语言的书中提到过。

a、b、c……, A,B,C……是对应到具体的ASCI字符集中有对应的编号的。通过编号来判断。

只是你读入字符的时候可能会碰到问题,因为你不知道下一个字符是中文的字符还是英文的字符。这个需要具体去试了。
作者: 不如意的时候    时间: 2008-10-30 20:02
我是来学习的
作者: lengbingyu1016    时间: 2008-11-01 01:04
哪位大哥能把标准答案弄出来么
作者: wxr9999    时间: 2008-11-03 18:37
提示: 作者被禁止或删除 内容自动屏蔽
作者: north423    时间: 2008-11-11 10:36
标题: 我的方法
首先大致介绍下汉字编码:
      GB2312规定"对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示",习惯上称第一个字节为"高字节",第二个字节为"低字节"。GB2312的编码范围为2121H-777EH,与ASCII有重叠,通行方法是将GB码两个字节的最高位置1以示区别。GB2312的两个字节的最高位都是1。但符合这个条件的码位只有128*128=16384个。

      GBK是GB2312-80的扩展,是向上兼容的。它包含了20902个汉字,因为GBK和GB18030的低字节最高位都可能不是1,其编码范围是0x8140-0xfefe,剔除高位0x80的字位。其所有字符都可以一对一映射到Unicode2.0。

      我觉得本题主要是为了防止将汉字编码的第二个字节当做字母将其小写(+32),否则直接逐个字节的tolower()就可以了,下面是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void m_lower(char *str)
{
        while(*str!='\0')
        {
                if(*str & 0x80)
                        str += 2;
                else
                {
                        *str = tolower(*str);
                        str++;
                }
        }
}
int main()
{
    char test[]="aB测试cD";
        m_lower(test);
        printf("string is %s\n",test);
        return 0;
}
/*
*run result:
*            string is ab测试cd
*/
作者: north423    时间: 2008-11-11 10:50
标题: 接上一个帖子
GB 2312-80其编码范围是高位0xa1-0xfe,低位也是0xa1-0xfe;
比如 朱镕基的“镕”字在GB 2312-80里并没有收录,也就是说这个字的第二个字节不在0xa1-0xfe范围,有可能被当做字母。我们将判断
汉字的部分注释,直接tolower(),就会出现错误。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void m_lower(char *str)
{
        while(*str!='\0')
        {
//                if(*str & 0x80)
//                        str += 2;
//                else
//                {
                        *str = tolower(*str);
                        str++;
//                }
        }
}
int main()
{
    char test[]="aB测试镕cD";
        m_lower(test);
        printf("string is %s\n",test);
        return 0;
}
/*
*run result:
*            string is ab测试閒cd
*/
作者: spiritX    时间: 2008-11-11 10:53
static int strfunc(char *str, int mode, int c1, int c2)
{

  int ret;
  char *pt;
  int cnt;
  int from, to;

        if(str == NULL){
                return(-1);
        }
        if(strlen(str) == 0){
                return(0);
        }

        for(pt = str, cnt = 0 ; *pt != '\0' ; ){
                ret = mbtowc((wchar_t *)0, pt, MB_CUR_MAX);
                if(ret < 0){
                        break;
                }
                if(ret == 1){
                        from = (int)*pt;
                        if(mode == 1){
                                to = toupper(from);
                        }else if(mode == 2){
                                to = tolower(from);
                        }else if(mode == 3){
                                if(from == c1){
                                        to = c2;
                                }else{
                                        to = from;
                                }
                        }else{
                                to = from;
                        }
                        if(from != to){
                                cnt ++;
                                *pt = (char)to;
                        }
                }
                pt += ret;
        }

        if(*pt != '\0'){
                return(-1);
        }else{
                return(cnt);
        }

}        /*        strfunc()        */


mode:
1:小写变大写
2:大写变小写
3:c2变c1

给分,谢谢!
作者: north423    时间: 2008-11-11 11:10
Hi spiritX ~~

我测试了下你的函数,“镕”字没有被正确的处理,希望你能把你的思想讲一下,只有代码比较抽象。呵呵,谢谢

best wishes
作者: spiritX    时间: 2008-11-11 12:45
原帖由 north423 于 2008-11-11 11:10 发表
Hi spiritX ~~

我测试了下你的函数,“镕”字没有被正确的处理,希望你能把你的思想讲一下,只有代码比较抽象。呵呵,谢谢

best wishes


调用这个函数之前先setlocale(LC_ALL, "");一下 --中文系统
需要#include <locale.h>
作者: vincentdpan    时间: 2008-12-24 21:05
原帖由 aliking 于 2008-9-16 17:36 发表
不知道有什么要求。
用什么编程语言?输入字符串和输出字符串是不是同一个?

下面是用C实现的,输入和输出字符串用同一个。
void lower(char *s)
{
        while(*s != '\0')
        {
             ...


这个应该能行!
作者: 剑魂箫心    时间: 2014-08-10 14:11
直接上汇编!
作者: cobras    时间: 2014-08-10 14:27
显然前面的代码乎略了汉字中的英文字母的转换。
作者: Hugo801122    时间: 2014-08-11 03:50
说实话,我用c比较多,瞬间有点没头绪。
作者: cobras    时间: 2014-08-11 11:49
给个通用的函数,并附例子。

  1. /* nstrcovt.c */

  2. #include <string.h>

  3. int nstr_get_nchar(const char *s, int off, int lmt)
  4. {
  5.         if (off < lmt) {
  6.                 if (s[off] < 0 && off + 1 < lmt) {
  7.                         return 2;
  8.                 }
  9.                 return 1;
  10.         }
  11.         return 0;
  12. }

  13. int nchar_match(const char *c, int c_len, const char *list, int list_len)
  14. {
  15.         int i;
  16.         int len;

  17.         for (i = 0; i + c_len <= list_len; i += len) {
  18.                 len = nstr_get_nchar(list, i, list_len);
  19.                 if (len == c_len && strncmp(c, list + i, len) == 0) {
  20.                         return i;
  21.                 }
  22.         }
  23.         return -1;
  24. }

  25. int nstr_convert(char *s, int off, int lmt, const char *src, const char *tar)
  26. {
  27.         int c_len;
  28.         int i;
  29.         int src_len;

  30.         src_len = strlen(src);
  31.         for (; off < lmt; off += c_len) {
  32.                 c_len = nstr_get_nchar(s, off, lmt);
  33.                 i = nchar_match(s + off, c_len, src, src_len);
  34.                 if (i != -1) {
  35.                         strncpy(s + off, tar + i, c_len);
  36.                 }
  37.         }
  38.         return 0;
  39. }

  40. /* test */

  41. #if 1

  42. #include <stdio.h>

  43. int main(void)
  44. {
  45.         char str[] = "abcdefghijklmnopqrstuvwxyzавс";
  46.         char rep[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZАВС";
  47.         char buf[] = "I LIKE АВС";

  48.         nstr_convert(buf, 0, strlen(buf), rep, str);
  49.         puts(buf);
  50.         return 0;
  51. }

  52. #endif
复制代码





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2