您的位置:首页 > 其它

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。

就是一个配置文件的解析程序,下面给出源代码,

下面是自己定义的两个结构体,分别表示规则和规则里面的子项:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: