2013亚马逊笔试题
2012-10-18 19:01
323 查看
题目的大概意思是就是,亚马逊有一种配置文件,文件的内容按照如下格式:
A={A=1;B=2;C=3;E={A=100;};};
A+={D=4;E={B=10;C=D;};};
规则A如第一行表示,每条规则用一个字符串表示,可以通过若干条规则向规则A中增加子项,若子项有相同则覆盖之前的值。最后可以通过下面的形式来访问规则A的内容,规则名和相应的值只包含A-z,a-z和0-9:
A.E.B
A.A
A.E.A
说明,一个规则中的非嵌套规则用子项表示,如A.A,规则中的嵌套规则用子规则表示如A.E。
就是一个配置文件的解析程序,下面给出源代码,
下面是自己定义的两个结构体,分别表示规则和规则里面的子项:
给出一个字符串,需要判断是规则的开始,子项的开始,子规则的开始等等,从字符串的头开始遍历,如果遇到={则表示规则的开始,如果是=表示子项的开始,如果是};则是规则结束。
有了上面的这些辅助函数,就可以解析上面的规则,整个程序如下,包含测试函数:
A={A=1;B=2;C=3;E={A=100;};};
A+={D=4;E={B=10;C=D;};};
规则A如第一行表示,每条规则用一个字符串表示,可以通过若干条规则向规则A中增加子项,若子项有相同则覆盖之前的值。最后可以通过下面的形式来访问规则A的内容,规则名和相应的值只包含A-z,a-z和0-9:
A.E.B
A.A
A.E.A
说明,一个规则中的非嵌套规则用子项表示,如A.A,规则中的嵌套规则用子规则表示如A.E。
就是一个配置文件的解析程序,下面给出源代码,
下面是自己定义的两个结构体,分别表示规则和规则里面的子项:
struct rule_component{//这个表示子项 char *name; //当子项的名字长度小于NAME_LEN,指向新分配的内存,否则指向_name成员 char *value; //同理,指向新分配的内存或者_value成员,这个是为了提高效率,防止为了短字符串分配内存 char _name[NAME_LEN + 1]; char _value[VALUE_LEN + 1]; struct rule_component *next; //将属于某个规则的所有子项组织在一个单链表中 }; struct rule{ char *name; //当子项的名字长度小于NAME_LEN,指向新分配的内存,否则指向_name成员 char _name[NAME_LEN + 1]; struct rule_component *head; //子项链表的表头 struct rule *nested_head; //属于这个规则的子规则的链表的表头 struct rule *next; //规则的链表 };
给出一个字符串,需要判断是规则的开始,子项的开始,子规则的开始等等,从字符串的头开始遍历,如果遇到={则表示规则的开始,如果是=表示子项的开始,如果是};则是规则结束。
char* is_rule_start(char *ptr) { do{ if(*ptr == '='){ if(*(ptr + 1) == '{') return ptr; else return NULL; } ptr ++; }while(*ptr); return 0; } char* is_rule_append(char *ptr) { do{ if(*ptr == '='){ if(*(ptr - 1) == '+') return ptr - 1; else return NULL; } ptr ++; }while(*ptr); return NULL; } char* is_comp_start(char *ptr) { char *res; do{ if(*ptr == '='){ if(*(ptr + 1) != '{') return ptr; else return NULL; } ptr ++; }while(*ptr); return 0; } int is_rule_end(char *ptr) { if(ptr) return strstr(ptr, RULE_END) == ptr; return 0; }添加一些辅助函数用于管理这两个数据结构:
struct rule* make_rule() //new一个rule对象 { struct rule *res; res = (struct rule*)malloc(sizeof(*res)); if(res) memset(res, 0, sizeof(*res)); res->name = res->_name; return res; } struct rule_component *make_rule_component() //new一个rule_component对象 { struct rule_component *res; res = (struct rule_component*)malloc(sizeof(*res)); if(res) memset(res, 0, sizeof(*res)); res->name = res->_name; res->value = res->_value; return res; } void free_rule(struct rule * r) //释放rule对象 { if(r){ if(strlen(r->name) > NAME_LEN) //当name的长度小于NAME_LEN,则name指向内嵌的_name成员,不用释放 free(r->name); free(r); } } void free_rule_component(struct rule_component * c) //释放rule_component对象 { if(c){ if(strlen(c->name) > NAME_LEN) free(c->name); if(strlen(c->value) > VALUE_LEN) free(c->value); free(c); } } void destroy_rule_recursive(struct rule *rule) //destroy整个rule,包括子规则,子项 { struct rule *nested; struct rule_component *comp; comp = rule->head; while(comp){ struct rule_component *tmp; tmp = comp->next; free_rule_component(comp); comp = tmp; } nested = rule->nested_head; while(nested){ struct rule *tmp; tmp = nested->next; destroy_rule_recursive(nested); nested = tmp; } free_rule(rule); } void destroy_rule_list(struct rule *head) //destroy一个rule的链表 { struct rule *tmp; while(head){ tmp = head->next; destroy_rule_recursive(head); head = tmp; } }
有了上面的这些辅助函数,就可以解析上面的规则,整个程序如下,包含测试函数:
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
/*
2 2
A={A=1;B=2;C=3;E={A=100;};};
A+={D=4;E={B=10;C=D;};};
A.E.B
B.D.E
*/
#define NAME_LEN 10
#define VALUE_LEN 20
#define COMP_STRING ";"
#define RULE_START "={"
#define RULE_END "};"
#define RULE_APP "+={"
#define DELIM "."
static struct rule *rules; //所有顶级规则的链表
char* is_rule_start(char *ptr) { do{ if(*ptr == '='){ if(*(ptr + 1) == '{') return ptr; else return NULL; } ptr ++; }while(*ptr); return 0; } char* is_rule_append(char *ptr) { do{ if(*ptr == '='){ if(*(ptr - 1) == '+') return ptr - 1; else return NULL; } ptr ++; }while(*ptr); return NULL; } char* is_comp_start(char *ptr) { char *res; do{ if(*ptr == '='){ if(*(ptr + 1) != '{') return ptr; else return NULL; } ptr ++; }while(*ptr); return 0; } int is_rule_end(char *ptr) { if(ptr) return strstr(ptr, RULE_END) == ptr; return 0; }
struct rule_component{
char *name;
char *value;
char _name[NAME_LEN + 1];
char _value[VALUE_LEN + 1];
struct rule_component *next;
};
struct rule{
char *name;
char _name[NAME_LEN + 1];
struct rule_component *head;
struct rule *nested_head;
struct rule *next;
};
struct rule* make_rule()
{
struct rule *res;
res = (struct rule*)malloc(sizeof(*res));
if(res)
memset(res, 0, sizeof(*res));
res->name = res->_name;
return res;
}
struct rule_component *make_rule_component()
{
struct rule_component *res;
res = (struct rule_component*)malloc(sizeof(*res));
if(res)
memset(res, 0, sizeof(*res));
res->name = res->_name;
res->value = res->_value;
return res;
}
void free_rule(struct rule * r)
{
if(r){
if(strlen(r->name) > NAME_LEN)
free(r->name);
free(r);
}
}
void free_rule_component(struct rule_component * c)
{
if(c){
if(strlen(c->name) > NAME_LEN)
free(c->name);
if(strlen(c->value) > VALUE_LEN)
free(c->value);
free(c);
}
}
void destroy_rule_recursive(struct rule *rule)
{
struct rule *nested;
struct rule_component *comp;
comp = rule->head;
while(comp){
struct rule_component *tmp;
tmp = comp->next;
free_rule_component(comp);
comp = tmp;
}
nested = rule->nested_head;
while(nested){
struct rule *tmp;
tmp = nested->next;
destroy_rule_recursive(nested);
nested = tmp;
}
free_rule(rule);
}
void destroy_rule_list(struct rule *head)
{
struct rule *tmp;
while(head){
tmp = head->next;
destroy_rule_recursive(head);
head = tmp;
}
}
struct rule* find_nested_rule(struct rule *root, char *name, int nlen)
{
while(root){
if(strlen(root->name) != nlen){
root = root->next;
continue;
}
if(!strncmp(root->name, name, nlen))
return root;
root = root->next;
}
return NULL;
}
struct rule_component* find_nested_component(struct rule *root, char *name, int nlen) //在规则中查找子项
{
struct rule_component *comp = root->head;
while(comp){
if(strlen(comp->name) != nlen){
comp = comp->next;
continue;
}
if(!strncmp(comp->name, name, nlen))
return comp;
comp = comp->next;
}
return NULL;
}
struct rule_component* parse_component(char *ptr, char **next) //解析子项
{
char *start;
struct rule_component *res;
start = is_comp_start(ptr);
if(!start)
return 0;
res = make_rule_component();
if(!res)
return NULL;
if(start - ptr > NAME_LEN)
res->name = (char*)malloc(start - ptr + 1);
strncpy(res->name, ptr, start - ptr);
res->name[start - ptr] = '\0';
ptr = start + 1; //跳过子项开始符 '='
start = strstr(ptr, COMP_STRING); //寻找子项结束符 ';'
if(!start){
free_rule_component(res);
return 0;
}
if(start - ptr > VALUE_LEN)
res->value = (char*)malloc(start - ptr + 1);
res->value[start - ptr] = '\0';
strncpy(res->value, ptr, start - ptr);
*next = start + strlen(COMP_STRING);
return res;
}
void unique_rule_component(struct rule *root, struct rule_component *comp) //当子项加入到rule时,保证子项是唯一的
{
struct rule_component *next, *prev;
int repeat = 0;
prev = NULL;
next = root->head;
while(next){
if(!strcmp(next->name, comp->name)){
repeat = 1;
if(prev){
prev->next = comp;
comp->next = next->next;
}else
root->head = comp;
free_rule_component(next);
break;
}
prev = next;
next = next->next;
}
if(!repeat){
comp->next = root->head;
root->head = comp;
}
}
struct rule* parse_rule(struct rule *parent, char *confs, char** next);
void parse_rule_content(struct rule *root, char *ptr, char **next) //解析规则的"{...};"之间的内容
{
char *ctmp = ptr;
while(1){
ctmp = is_rule_start(ptr);
if(ctmp){
struct rule *nested, *tmp;
nested = parse_rule(root, ptr, &ctmp);
if(!nested)
exit(0);
tmp = find_nested_rule(root->nested_head, nested->name, strlen(nested->name));
if(!tmp){
nested->next = root->nested_head;
root->nested_head = nested;
}
ptr = ctmp;
continue;
}
ctmp = is_comp_start(ptr);
if(ctmp){
struct rule_component *comp = parse_component(ptr, &ctmp);
if(!comp)
exit(0);
unique_rule_component(root, comp);
ptr = ctmp;
continue;
}
if(is_rule_end(ptr)){
ptr += strlen(RULE_END);
*next = ptr;
return;
}
printf("Rule Error : You have got a wrong rule\n");
exit(0);
}
}
struct rule* parse_rule(struct rule *parent, char *confs, char** next)
{
struct rule *root = NULL, *nested;
char *ptr = confs, *ctmp = confs;
ctmp = is_rule_start(ptr);
if(ctmp){
if(parent)
root = find_nested_rule(parent->nested_head, ptr, ctmp - ptr);
if(!root){
root = make_rule();
if(ctmp - ptr > NAME_LEN)
root->name = (char*)malloc(ctmp - ptr + 1);
root->name[ctmp - ptr] = '\0';
strncpy(root->name, ptr, ctmp - ptr);
}
ctmp += strlen(RULE_START);
ptr = ctmp;
parse_rule_content(root, ptr, &ctmp);
if(next)
*next = ctmp;
}
return root;
}
struct rule* parse_append_rule(char *confs, char **nnext) //解析+=的规则
{
char *rule_name, *next;
int rule_name_len;
struct rule *root;
rule_name = is_rule_append(confs);
if(!rule_name)
return NULL;
root = rules;
rule_name_len = rule_name - confs;
do{
if(!strncmp(root->name, confs, rule_name_len))
break;
root = root->next;
}while(root);
if(!root)
return NULL;
rule_name += strlen(RULE_APP);
parse_rule_content(root, rule_name, &next);
*nnext = next;
return root;
}
char* parse_value_string(char *s_value) //字符串求值,在规则中找就可以了
{
struct rule *root;
struct rule_component *comp;
char *part_name, *next_part;
char buf[100];
part_name = strtok(s_value, DELIM);
if(!part_name)
return NULL;
root = rules;
root = find_nested_rule(root, part_name, strlen(part_name));
if(!root){
printf("Can't find the value\n");
return NULL;
}
part_name = NULL;
next_part = strtok(NULL, DELIM);
while(next_part){
part_name = next_part;
strcpy(buf, part_name);
next_part = strtok(NULL, DELIM);
if(!next_part)
break;
root = find_nested_rule(root->nested_head, buf, strlen(buf));
if(!(root)){
printf("Can't find the value\n");
return NULL;
}
}
comp = find_nested_component(root, buf, strlen(buf));
if(!comp){
printf("Can't find the value\n");
return NULL;
}
return comp->value;
}
int main(){
char *conf = "A={A=1;B=2;C=3;E={A=100;};};";
char *app = "A+={D=4;E={B=10;C=D;};};";
char *conf2 = "B={A=adc;C=123;ADC=sldkfdsfsdfjf;E={AD=dddd;};};";
char res1[6] = "A.A";
char res2[6] = "B.D.E";
char res3[6] = "A.E.C";
char res4[8] = "B.ADC";
char *tmp;
struct rule *rule = parse_rule(NULL, conf, &tmp);
if(*tmp){
printf("Rule Error\n");
exit(0);
}
rules = rule;
rule = parse_rule(NULL, conf2, &tmp);
rule->next = rules;
rules = rule;
rule = parse_append_rule(app, &tmp);
if(*tmp){
printf("Rule Error\n");
exit(0);
}
tmp = parse_value_string(res1);
printf("%s\n", tmp);
tmp = parse_value_string(res2);
if(tmp)
printf("%s\n", tmp);
tmp = parse_value_string(res3);
if(tmp)
printf("%s\n", tmp);
tmp = parse_value_string(res4);
if(tmp)
printf("%s\n", tmp);
destroy_rule_list(rules);
return 0;
}
相关文章推荐
- 2013亚马逊在线笔试题目
- 2013亚马逊校园招聘在线笔试题MM-Chess
- 亚马逊2013的一道在线笔试题
- 亚马逊在线技术笔试(Amazon Hiring Campus 2013 - Final 6)
- 【面试题】2013亚马逊校园招聘--在线笔试题
- 腾讯2013笔试题—web前端笔试题 (老题练手)
- 2013微策略笔试题
- 2013 苏州中磊研发中心笔试 总结
- 亚马逊笔试题第二弹
- 微软2013实习生笔试题目
- 2013网易校园招聘笔试题
- 华为2013校园招聘上机笔试题--字串转换
- 百度2013校园招聘笔试题(含自己整理的答案)【转】
- 阿里巴巴2013笔试
- 微软2013暑期实习笔试题目
- 2013阿里巴巴软件测试笔试题
- 微软2013校园招聘笔试试题及详细解答
- 2013腾讯实习笔试
- [转]网易2013校园招聘笔试题集锦
- 微软2013暑假实习生笔试题解析