您的位置:首页 > 其它

机试——华为

2015-08-28 21:00 225 查看

需要识记的点

1、qsort

void qsort(void * base, int num_elem, int size_elem, int (fcmp)(const void ,const void *));

参数:

1 待排序数组首地址

2 数组中待排序元素数量

3 各元素的占用空间大小

4 指向函数的指针,用于确定排序的顺序 int comp(const void , const void)

int comp(const void *a,const void *b)
{
return *(int*)a - *(int*)b;  //由小到大排序
}


2、sort排序

#include <algorithm>
bool vector_int_cmp(int a, int b)
{
return (b<a);   //升序
}
sort(v.begin(), v.end(),vector_int_cmp);


3、C++

string::iterator it;
getline(cin,s);
int *arry = new int
;
vector<int> v(ch_array, ch_array+WORD_CNT);   //数组array赋值到vector中

str2 = str.substr(3,5);


4、C

char str[128];
fgets(str,128,stdin);
puts(str);

char*p;
p=strtok(input,",");
p=strtok(NULL,",");

//比较字符串大小 从小到大
int cmp_string(const void *a,const void *b)
{
return strcmp((char *)a,(char *)b);
}


一、过滤字符(60分):

通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉。

比如字符串“abacacde”过滤结果为“abcde”。

要求实现函数:void stringFilter(const char *pInputStr, long lInputLen, char *pOutputStr);

【思路】

用一个hash表,bool hash[26] = {0};对应26个字母是否在pInputStr出现与否,这样就不要再增加一个FOR循环,在pOutputStr从头遍历一遍pInputStr是否在pOutputStr中出现过了。

bool hash[26] = {0}; 表示首先都没有出现过,随着往pOutputStr加数据,将对应的hash表中的对应字母置1。

二、四则运算匹配

输入一个只包含个位数字的简单四则运算表达式字符串,计算该表达式的值

注: 1、表达式只含 +, -, *, /, (, ), 四则运算符

2、表达式数值只包含个位整数(0-9),且不会出现0作为除数的情况

3、要考虑加减乘除按通常四则运算规定的计算优先级

4、除法用整数除法,即仅保留除法运算结果的整数部分。比如8/3=2。输入表达式保证无0作为除数情况发生

5、输入字符串一定是符合题意合法的表达式,其中只包括数字字符和四则运算符字符,除此之外不含其它任何字符,不会出现计算溢出情况

• 要求实现函数:

int calculate(int len,char *expStr)

【输入】 int len: 字符串长度;

char *expStr: 表达式字符串;

【输出】 无

【返回】 计算结果

• 示例

1) 输入:char *expStr = “1+4*5-8/3”

函数返回:19

2) 输入:char *expStr = “8/3*3”

函数返回:6

——————————————————————————————————————————————————

① 将中缀表达式解析成后缀表达式

中缀表达式翻译成后缀表达式的方法如下:

(1)从右向左依次取得数据ch,需要一个运算符栈op_stack,输出的后缀表达式缓存suffix。

(2)如果ch是操作数,直接输出给suffix。

(3)如果ch是运算符(含左右括号),则:

a:如果ch = ‘(‘,压栈。

b:如果ch = ‘)’,依次输出栈中的运算符,直到遇到’(‘为止,并弹出’(‘。

c:如果ch不是’)’或者’(‘,那么就和op_stack栈顶点运算符top做优先级比较。

1:如果ch优先级比top高,那么将ch入栈(来的优先级高,入栈)。

2:如果ch优先级低于或者等于top,那么输出top,然后将ch入栈(来的优先级不高,输出栈顶,将来的ch压栈)。

(4)如果表达式已经读取完成,而op_stack栈中还有运算符时依次由顶端输出

如果我们有表达式(A-B)*C+D-E/F,要翻译成后缀表达式,并且把后缀表达式存储在一个名叫output的字符串中,可以用下面的步骤。

(1)读取’(‘,压入堆栈,output为空

(2)读取A,是运算数,直接输出到output字符串,output = A

(3)读取’-‘,此时栈里面只有一个’(‘,因此将’-‘压入栈,output = A

(4)读取B,是运算数,直接输出到output字符串,output = AB

(5)读取’)’,这时候依次输出栈里面的运算符’-‘,然后就是’(‘,直接弹出,output = AB-

(6)读取’*’,是运算符,由于此时栈为空,因此直接压入栈,output = AB-

(7)读取C,是运算数,直接输出到output字符串,output = AB-C

(8)读取’+’,是运算符,它的优先级比’‘低,那么弹出’‘,压入’+”,output = AB-C*

(9)读取D,是运算数,直接输出到output字符串,output = AB-C*D

(10)读取’-‘,是运算符,和’+’的优先级一样,因此弹出’+’,然后压入’-‘,output = AB-C*D+

(11)读取E,是运算数,直接输出到output字符串,output = AB-C*D+E

(12)读取’/’,是运算符,比’-‘的优先级高,因此压入栈,output = AB-C*D+E

(13)读取F,是运算数,直接输出到output字符串,output = AB-C*D+EF

(14)原始字符串已经读取完毕,将栈里面剩余的运算符依次弹出,output = AB-C*D+EF/-

② 后缀表达式的求值

从左到右扫描后缀表 达式,遇到运算符就把表达式中该运算符前面两个操作数取出并运算,然后把结果带回后缀表达式;继续扫描直到后缀表达式最后一个表达式。

设置一个操作数栈,开始时,栈为空,然后从左到右扫描后缀表达式suffix。

若遇操作数,则进栈;

若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的 放到运算符左边,运算后的结果再进栈,直到后缀表达式扫描完毕。此时,栈中仅有一个元素,即为运算的结果。

int calculate(int len,char *expStr)
{
char *suffix = new char[len];
char *op_stack = new char[len];
int op_top = 0,j=0;

//先将中缀表达式转换为后缀表达式
for(int i=0; i<len; ++i)
{
if(is_digit(expStr[i]))    //如果为操作数直接输出
{
suffix[j++] = expStr[i];
}
else  //操作符
{
if(expStr[i] == '(' || !op_top)
{
op_stack[op_top++] = expStr[i];
}
else if(expStr[i] == ')')
{
//将操作栈栈顶元素~ '('之间的操作符出栈输出
while(op_top && op_stack[op_top-1] != '(')
{
suffix[j++] = op_stack[--op_top];
}
op_top--;  //将( 出栈
}
else if(priority(expStr[i],op_stack[op_top-1]) == 1)  //来的优先级> 栈顶
{
op_stack[op_top++] = expStr[i];
}
else if(priority(expStr[i],op_stack[op_top-1]) != 1)     //来的优先级<= 栈顶
{
suffix[j++] = op_stack[--op_top];
op_stack[op_top++] = expStr[i];
}
}
}
while(op_top)
{
suffix[j++] = op_stack[--op_top];
}

//由后缀表达式求值
int *dig_stack = new int[len];
int dig_top = 0,a,b;

for(int i=0; i<j; ++i)
{
if(is_digit(suffix[i]))
{
dig_stack[dig_top++] = suffix[i] - '0';
}
else
{
a = dig_stack[--dig_top];
b = dig_stack[--dig_top];
dig_stack[dig_top++] = cal(b,a,suffix[i]);
}
}
return dig_stack[--dig_top];
}


三、链表翻转

给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现。

对reverse的解释如下图:



typedef struct _node
{
int data;
struct _node * next;
}node;

//翻转start后一位~end位置的链表
//返回end的指针
node * reverse(node **pre_start, node **end)
{
assert(end || pre_start);
node *start,*after_end;
node *p,*pre,*tmp;

start = (*pre_start)->next;
if(start == *end)  //only one node need not reverse
return;
after_end = (*end)->next;
pre = start;
p = pre->next;
*end = start;

while(p != after_end)
{
//将p插入到pre_start的后面
pre->next = p->next;
p->next = start;
(*pre_start)->next = p;
start = p;
p = pre->next;
}

(*end)->next = after_end;

return *end;
}

//main函数中的处理
p = head;
while(p)
{
//找到需要翻转的尾节点P2
tmpk = k;
p2 = p->next;
while(tmpk>1 && p2)
{
p2 = p2->next;
tmpk --;
}
if(!p2)
{
break;
}

p = reverse(&p,&p2);
}


四、字符串整数相减

输入两行字符串正整数,第一行是被减数,第二行是减数,输出第一行减去第二行的结果。

备注:1、两个整数都是正整数,被减数大于减数

示例:

输入:1000000000000001

1

输出:1000000000000000

解析:a-b

1:保证a>b

若a
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: