2012 华为编程比赛 解决方案
[前言]
华为初赛虽不是很难,但也能考量一个人编程基础,本人是菜鸟,所以得从巩固基础开始,高手勿喷!!!
[比赛题目]
1.就餐抽查
2.输入联想
3. 词法分析
[具体分析]
1.就餐抽查
• 问题描述: 某公司由于人多,午餐分为多批次就餐,严格要求每批次就餐时间。并定期抽查就餐情况。请编写程序实现就餐抽查情况。
• 要求实现函数: void check_lunch(int num, int time,int input[], int output[])
【输入】 int num,就餐总人数 int time,就餐分批数 char input[],就餐情况
【输出】 char output[], 违规就餐情况
【返回】 无 注:对就餐分3批的情况,12人就餐,正确的就餐情况应如下分布[1,2,3,1,2,3,1,2,3,1,2,3],不符合该分布的即是违规,输出时对相应位置0。
• 示例
1) 输入:num = 12,time = 3,input =[1,2,3,3,1,3,1,1,1,1,2,3] 输出:output = [1,2,3,0,0,3,1,0,0,1,2,3]
2) 输入:num = 11,time = 4,intput = [1,2,3,4,2,3,3,4,1,2,3] 输出:output = [1,2,3,4,0,0,3,4,1,2,3]
• 算法思路:
比较简单,对数组中的元素进行取余运算判断与输入的关系
•算法代码:
void check_lunch(int num,int time,int input[],int output[]) { int i=0,j=0; for(i=0;i<num;++i) { if(input[i]==(i+1)%time || ((i+1)%time==0 && input[i]=time)) output[i]=input[i]; else output[i]=0; } }
2.输入联想
• 问题描述: 输入联想功能是非常实用的一个功能,请编程实现类似功能。
• 要求实现函数: void auto_complete(char *str, char *tmp,char *output)
【输入】 char *str,候选字符串 char *tmp,输入字符串
【输出】 int *output,联想匹配的字符串
【返回】 无 注:候选字符串以空格隔开,输入字符串仅从字符串开始处匹配。将匹配的子字符串输出,同样以空格隔开。如无匹配成功的子字符串,则输出空字符串。
• 示例
1) 输入:str = chengdu chongqing,tmp = c 输出:output = chengdu Chongqing
2) 输入:str = chengdu chongqing,tmp = che 输出:end = Chengdu
3)输入:str = beijing nanjing,tmp = jing 输出:end =
•算法思路:字符串匹配,充分利用容器string的优势,给出两种代码:一种利用string,一种利用字符串数组。
•算法代码:
算法1:
View Code
#include <iostream> #include <string.h> #include <sstream> using namespace std; const int N=10005; void auto_complete(char *str,char *tmp, char *output) { char word[N]; memset(word,0,sizeof(word)); int i=0,k=0,j=0,cnt=0; int len=strlen(str); if(!strlen(tmp)) return; while(*str) { if(*str != ' ') { word[i++]=*str++; } else { k=0;j=0; while(k<i && tmp[j] != '\0') { if(word[k]==tmp[j]) { k++; j++; } else { break; } } if(tmp[j] == '\0') { for(k=0;k<i;++k) output[cnt++]=word[k]; output[cnt++]=' '; } memset(word,0,i); i=0; *str++; } } k=0;j=0; while(k<i && tmp[j] != '\0') { if(word[k]==tmp[j]) { k++; j++; } else { break; } } if(tmp[j] == '\0') { for(k=0;k<i;++k) output[cnt++]=word[k]; } output[cnt]='\0'; }
算法2:
void auto_complete(char *str,char *tmp, char *output) { istringstream istream((string)(str)); string word; int i=0,j=0,k=0; while(istream>>word) { int pos=word.find((string)(tmp)); cout<<pos<<endl; if(pos == 0) { for(;pos!=word.size();++pos) output[k++]=word[pos]; output[k++]=' '; } } output[--k]='\0'; }
3. 词法分析
• 问题描述: 编译器通过语法分析来检测程序的一些语法问题。要求实现一个简单的语法分析程序,判断输入的字符串是否有符合要求的语法组合。 需要判断的语法组合有: if then if ( ) then switch case end switch ( ) case end switch ( ) case default end do while
• 要求实现函数: void analysis(char *str,int *num)
【输入】 char *str,待分析字符串
【输出】 int num,匹配的组合个数
【返回】 无 注:输入字符串中关键字以空格隔开,"if"、"("、")"、"case"等均表示关键字,从左向右,找到匹配的组合即可,组合一定是相互分离,不会嵌套,不会有交叉情况出现。
• 示例
1) 输入:str = if then, 输出:num = 1
2) 输入:str = switch case aaa , 输出:num = 0
3) 输入:str = if ( aaa ) then do bbb while switch cas , 输出:num = 2
•算法思路:也是利用string,预先把所有可能的情况定义成数组形式,在编历输入字符串过程中判断其是否属于预定义的关键字或匹配模式
•算法代码:
string mstr[6]={"if then","if ( ) then","switch case end","switch ( ) case end","switch ( ) case default end","do while"}; string keystr[10]={"if","then","(",")","switch","case","end","default","do","while"}; bool iskey(string &str) { for(int i=0;i<10;++i) if(str == keystr[i]) return true; return false; } bool ismatch(string &str) { for(int i=0;i<6;++i) if(str == mstr[i]) return true; return false; } void analysis(char *str,int *num) { istringstream stream((string)(str)); string word; string smatch(""); vector<string> vstr; int i=0; while(stream>>word) { if(iskey(word)) { if(smatch.empty()) smatch.append(word); else { smatch.append(" "); smatch.append(word); } } if(ismatch(smatch)) { (*num)++; smatch.erase(); } } }
作者:ballwql
本文为作者原创,版权所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。