2012年奇虎360校园招聘实习生笔试编程题
1. 自己实现库函数 int atoi(const char* str);
注意两点:(1). 字符串中,符号位的处理。
(2).字符串中,出现非数字字符。
(3). 进制考虑(如八进制只以0开头,十六进制以0x或者0X开头)
实现原理: 霍纳规则(Hornor rule):
下面给出具体实现代码:
#include <stdio.h>
#include <stdlib.h>
int atoi(const char* str);
int main(int argc, char *argv[], char *env[]) {
char * str = "+123dafd435";
printf("%d\n", atoi(str));
return 0;
}
int atoi(const char *str) {
int n;
int sum;
int sign;
const char *p;
p = str;
sum = 0;
sign = 0;
if(NULL==p) exit(1);
if(*p == '-' || *p=='+') {
if(*p=='-') sign = 1;
/*
switch(*p) {
case '-':
sign=1;
break;
case '+':
sign=0;
break;
}
*/
p++;
}
while(*p!='\0') {
if(*p<'0' || *p>'9') {
//abort();
if(p==str || p==str+1) {
//abort();
exit(1);
}else {
return sign ? -sum : sum;
}
}
n = *p -'0';
sum = sum*10 + n;
p++;
}
return sign ? -sum : sum;
}
运行结果:
version 2: 避免了对空串的操作。
#include <stdio.h>
#include <stdlib.h>
int atoi(const char* str);
int main(int argc, char *argv[], char *env[]) {
char * str = "-123dafd435";
printf("%d\n", atoi(str));
return 0;
}
int atoi(const char *str) {
int n;
int sum;
int sign;
const char *p;
p = str;
sum = 0;
sign = 0; // 符号号位为‘+’ 或者无符号位
//避免字符串指针无效以及字符串为空
if(NULL==p || *p=='\0') exit(1);
/* 符号位的处理 **/
if(*p == '-' || *p=='+') {
if(*p=='-') sign = 1; //符号位为‘-’
p++; // 跳过符号位
}
while(*p!='\0') {
//处理字符串中出现的,非数字字符
if(*p<'0' || *p>'9') {
if(p==str || p==str+1) { //无效的非数字串
exit(1);
}else {
break; // 数字串中, 前半部分为有效的数字串,遇见非数字字符
}
}
n = *p -'0';
sum = sum*10 + n; //霍纳规则
p++;
}
return sign ? -sum : sum;
}
#include <stdio.h>
#include <stdlib.h>
int atoi(const char* str);
int main(int argc, char *argv[], char *env[]) {
char * str = " \t \n -123dafd435";
printf("%d\n", atoi(str));
return 0;
}
int atoi(const char *str) {
int n;
int sum;
int sign;
const char *p;
sum = 0;
sign = 0; // 符号号位为‘+’ 或者无符号位
//避免字符串指针无效以及字符串为空
if(NULL==str || *str=='\0') exit(1);
//跳过空白符
while(*str==' ' || *str=='\t' || *str=='\n') str++;
p = str;
/* 符号位的处理 **/
if(*p == '-' || *p=='+') {
if(*p=='-') sign = 1; //符号位为‘-’
p++; // 跳过符号位
}
while(*p!='\0') {
//处理字符串中出现的,非数字字符
if(*p<'0' || *p>'9') {
if(p==str || p==str+1) { //无效的非数字串
exit(1);
}else {
break; // 数字串中, 前半部分为有效的数字串,遇见非数字字符
}
}
n = *p -'0';
sum = sum*10 + n; //霍纳规则
p++;
}
return sign ? -sum : sum;
}
version 4: 对八进制和十六进制的支持数字串的支持
#include <stdio.h>
#include <stdlib.h>
int atoi(const char* str);
int main(int argc, char *argv[], char *env[]) {
/*
char * str = " -123dafd435";
char * octalStr = "0678";
char * hexStr1 = "0xadfb";
char * hexStr2 = "-0Xabad";
*/
char * numStr[] = { " 123dafd435", // decimal number string without sign
" +123dafd435", // decimal number string with plus sign
" -123dafd435", // decimal number string with minus sign
"0678", // octal number string
"+0678", // octal number string with plus sign
"-0678", // octal number string with minus sign
"0xadfb", // hexadecimal number string
"sdfds+0xadgh", // hexadecimal number string with plus sign
"-0xahgfh" // hexadecimal number string with minus sign
};
int i;
int len = sizeof(numStr)/sizeof(numStr[0]);
for(i=0; i<len; i++) {
printf("%s: %d\n", numStr[i], atoi(numStr[i]) );
}
//printf("%d\n", atoi(str));
return 0;
}
int atoi(const char *str) {
int n;
int sum;
int sign;
int base;
const char *p;
char c;
sum = 0;
sign = 0; // 符号号位为‘+’ 或者无符号位
base = 10;
//避免字符串指针无效以及字符串为空
if(NULL==str || *str=='\0') exit(1);
//跳过空白符
while(*str==' ' || *str=='\t') str++;
p = str;
/* 符号位的处理 **/
if(*p=='-' || *p=='+') {
if(*p=='-') sign = 1; //符号位为‘-’
p++; // 跳过符号位
}
//确定字符串的进制
if(*p=='0') {
if(*(p+1)=='x' || *(p+1)=='X') {
base = 16;
p++;
}else {
base = 8;
}
p++;
}
while(*p!='\0') {
c = *p;
if(c>='0'&&c<='9') {
n = c - '0';
}else if(c>='A'&&c<='F'){ //十六进制数字
n = c - 'A' + 10;
}else if(c>='a'&& c<='f'){ //十六进制数字
n = c - 'a' + 10;
}else {
break; //非法字符
}
if(n>=base) break; //进制错误
sum = sum*base + n; //霍纳规则
p++;
}
return sign ? -sum : sum;
}
#include <stdio.h>
#include <stdlib.h>
int atoi(const char* str);
int main(int argc, char *argv[], char *env[]) {
/*
char * str = " -123dafd435";
char * octalStr = "0678";
char * hexStr1 = "0xadfb";
char * hexStr2 = "-0Xabad";
*/
char * numStr[] = { " 123dafd435", // decimal number string without sign
" +123dafd435", // decimal number string with plus sign
" -123dafd435", // decimal number string with minus sign
"06778", // octal number string
"+06778", // octal number string with plus sign
"-06778", // octal number string with minus sign
"0xadfb", // hexadecimal number string
"sdfds+0xadgh", // hexadecimal number string with plus sign
"-0xahgfhgdb" // hexadecimal number string with minus sign
};
int i;
int len = sizeof(numStr)/sizeof(numStr[0]);
for(i=0; i<len; i++) {
printf("%s: %d\n", numStr[i], atoi(numStr[i]) );
}
//printf("%d\n", atoi(str));
return 0;
}
int atoi(const char *str) {
int n;
int sum;
int sign;
int base;
int d;
const char *p;
char c;
sum = 0;
sign = 0; // 符号号位为‘+’ 或者无符号位
base = 10;
//避免字符串指针无效以及字符串为空
if(NULL==str || *str=='\0') exit(1);
//跳过空白符
while(*str==' ' || *str=='\t') str++;
p = str;
/* 符号位的处理 **/
if(*p=='-' || *p=='+') {
if(*p=='-') sign = 1; //符号位为‘-’
p++; // 跳过符号位
}
//确定字符串的进制
if(*p=='0') {
if(*(p+1)=='x' || *(p+1)=='X') {
base = 16;
d = 4;
p++;
}else {
base = 8;
d=3;
}
p++;
}
while(*p!='\0') {
c = *p;
if(c>='0'&&c<='9') {
n = c - '0';
}else if(c>='A'&&c<='F'){ //十六进制数字
n = c - 'A' + 10;
}else if(c>='a'&& c<='f'){ //十六进制数字
n = c - 'a' + 10;
}else {
break; //非法字符
}
if(n>=base) break; //进制错误
if(base==10){
sum = sum*base + n; //霍纳规则
}else {
sum <<= d;
sum |= n;
}
p++;
}
return sign ? -sum : sum;
}
2. 笔试的第二个答题: 是关于互斥锁和共享锁的两个英文句子的翻译。
大致的意思是: 在受保护的临界区上,如果已经加上了互斥锁,其他任何进程都不能再在其上加共享锁或者互斥锁。对没有写权限的文件,加互斥锁操作将失败。
总结: 奇虎360的笔试:前面客观题,要涂卡。客观题分两部分: 1.逻辑推理题。(像考公务员死的)2. 基础的计算机知识。
其他:
#include <iostream>
#include <cstring>
using namespace std;
const char* strNums[10] = { "zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine",
};
int getNumValue(const char * strNum){
for (int i = 0; i < 10; ++i) {
if (strcmp(strNum, strNums[i]) == 0) {
return i;
}
}
return -1;
}
int isSeperator(int c) {
if(c == ' ' || c == '\t' || c == '\n') return 1;
return 0;
}
/*
int isOperator(int c) {
if( c == '+' || c == '-' ||
c == '*' || c == '/' ||
c == '=') return 1;
return 0;
}
*/
int cal1(const char *str) {
char buffer[6];
int len = 0;
int strLen = strlen(str);
int sum = 0;
int first = 0;
while(sscanf(str + len, "%s", buffer) == 1) {
if(buffer[0] != '+' && buffer[0] != '=') {
first = first * 10 + getNumValue(buffer);
}else {
sum += first;
first = 0;
}
if(buffer[0] == '=') break;
len += strlen(buffer);
++len;
}
return sum;
}
int cal(const char *str) {
char buffer[6];
int len = 0;
int strLen = strlen(str);
const char *p = str;
int sum = 0;
int first = 0;
while(isSeperator(*p)) ++p; //跳过空白符
while(sscanf(p, "%s", buffer)==1 ) {
if(buffer[0] != '+' && buffer[0] != '=') {
first = first * 10 + getNumValue(buffer);
}else {
sum += first;
first = 0;
}
if(buffer[0] == '=') break;
len = strlen(buffer);
++len;
p += len;
while(isSeperator(*p)) ++p; //跳过空白符
}
return sum;
}
int main()
{
char str[] = " one two three one + five six =";
cout<< cal(str) << endl;
return 0;
}