华为2011上机笔试题1+参考程序
1. 数组比较(20分)
比较两个数组,要求从数组最后一个元素开始逐个元素向前比较,如果2个数组长度不等,则只比较较短长度数组个数元素。请编程实现上述比较,并返回比较中发现的不相等元素的个数
比如:
数组{1,3,5}和数组{77,21,1,3,5}按题述要求比较,不相等元素个数为0
数组{1,3,5}和数组{77,21,1,3,5,7}按题述要求比较,不相等元素个数为3
要求实现函数:
int array_compare(int len1, int array1[], int len2, int array2[])
【输入】 int len1:输入被比较数组1的元素个数;
int array1[]:输入被比较数组1;
int len2:输入被比较数组2的元素个数;
int array2[]:输入被比较数组2;
【输出】 无
【返回】 不相等元素的个数,类型为int
示例:
1) 输入:int array1[] = {1,3,5},int len1 = 3,int array2[] = {77,21,1,3,5},int len2 = 5
函数返回:0
2) 输入:int array1[] = {1,3,5},int len1 = 3,int array2[] = {77,21,1,3,5,7},int len2 = 6
函数返回:3
2. 约瑟夫问题
输入一个由随机数组成的数列(数列中每个数均是大于0的整数,长度已知),和初始计数值m。从数列首位置开始计数,计数到m后,将数列该位置数值替换计数值m,并将数列该位置数值出列,然后从下一位置从新开始计数,直到数列所有数值出列为止。如果计数到达数列尾段,则返回数列首位置继续计数。请编程实现上述计数过程,同时输出数值出列的顺序
比如:输入的随机数列为:3,1,2,4,初始计数值m=7,从数列首位置开始计数(数值3所在位置)
第一轮计数出列数字为2,计数值更新m=2,出列后数列为3,1,4,从数值4所在位置从新开始计数
第二轮计数出列数字为3,计数值更新m=3,出列后数列为1,4,从数值1所在位置开始计数
第三轮计数出列数字为1,计数值更新m=1,出列后数列为4,从数值4所在位置开始计数
最后一轮计数出列数字为4,计数过程完成。
输出数值出列顺序为:2,3,1,4。
要求实现函数:
void array_iterate(int len, int input_array[], int m, int output_array[])
【输入】 int len:输入数列的长度;
int intput_array[]:输入的初始数列
int m:初始计数值
【输出】 int output_array[]:输出的数值出列顺序
【返回】 无
示例:
输入:int input_array[] = {3,1,2,4},int len = 4, m=7
输出:output_array[] = {2,3,1,4}
3. 简单四则运算
问题描述:
输入一个只包含个位数字的简单四则运算表达式字符串,计算该表达式的值
注:
3.1、表达式只含 +, -, *, / 四则运算符,不含括号
3.2、表达式数值只包含个位整数(0-9),且不会出现0作为除数的情况
3.3、要考虑加减乘除按通常四则运算规定的计算优先级
3.4、除法用整数除法,即仅保留除法运算结果的整数部分。比如8/3=2。输入表达式保证无0作为除数情况发生
3.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
参考程序(欢迎讨论) 转载请注明来源http://www.cnblogs.com/jerry19880126/
三道题写在一个CPP文件里了,如下:
1 #include <iostream> 2 using namespace std; 3 4 // 第一题 5 //从后往前比较数组中相应元素,返回不同元素的个数 6 int array_compare(int len1, int array1[], int len2, int array2[]) 7 { 8 int count = 0; // 计数器 9 int loopTimes = len1 < len2 ? len1:len2;//求出循环次数 10 int index1 = len1 - 1; 11 int index2 = len2 - 1; 12 for(int i = 0; i < loopTimes; ++i) 13 { 14 if(array1[index1] != array2[index2]) 15 { 16 ++ count; 17 } 18 --index1; 19 --index2; 20 } 21 return count; 22 } 23 24 // 第二题 25 // 约瑟夫环问题,根据计数值不断移走元素,并以移走的元素值作为计数值 26 void array_iterate(int len, int input_array[], int m, int output_array[]) 27 { 28 int startIndex = 0; // 下一次开始计数的下标 29 int chooseIndex = 0; // 选中的下标 30 int outputIndex = 0; // 输出数组的下标 31 while(len > 0) 32 { 33 startIndex = chooseIndex; 34 chooseIndex = (startIndex + (m - 1) % len) % len; 35 m = input_array[chooseIndex]; 36 output_array[outputIndex++] = m; 37 // 数组左移 38 for(int i = chooseIndex; i <= len - 2; ++i) 39 { 40 input_array[i] = input_array[i + 1]; 41 } 42 -- len; 43 } 44 } 45 46 //第三题 47 //四则运算表达式,用两个栈实现,一个是操作数栈,一个是操作符栈 48 int calculate(int len, char *expStr) 49 { 50 //用两个数组来模拟栈 51 int *operNumber = new int[len]; 52 int operNumberSize = 0; 53 char *operSymbol = new char[len]; 54 int operSymbolSize = 0; 55 bool popFlag = false; //需要进行弹出操作 56 for(int i = 0; i < len; ++i) 57 { 58 char c = expStr[i]; 59 if(c >= '0' && c <= '9') 60 { 61 //是操作数 62 operNumber[operNumberSize++] = (int)(c -'0'); 63 continue; 64 } 65 66 // 是操作符 67 else if(c == '*' || c == '/') 68 { 69 //是高优先级操作符 70 //判断是否满足弹出条件 71 if(operSymbolSize > 0 && 72 (operSymbol[operSymbolSize - 1] == '*' || operSymbol[operSymbolSize - 1] == '/') 73 ) 74 { 75 //弹出 76 popFlag = true; 77 } 78 else 79 { 80 // 不弹出 81 popFlag = false; 82 } 83 } 84 else if(c == '+' || c == '-') 85 { 86 // 是低优先级操作符 87 // 判断是否满足弹出条件 88 if(operSymbolSize == 0) 89 { 90 // 不弹出 91 popFlag = false; 92 } 93 else 94 { 95 // 弹出 96 popFlag = true; 97 } 98 } 99 100 // 弹出操作 101 if(popFlag == true) 102 { 103 int b = operNumber[--operNumberSize]; 104 int a = operNumber[--operNumberSize]; 105 char op = operSymbol[--operSymbolSize]; 106 if(op == '+') 107 { 108 operNumber[operNumberSize++] = a + b; 109 } 110 else if(op == '-') 111 { 112 operNumber[operNumberSize++] = a - b; 113 } 114 else if(op == '*') 115 { 116 operNumber[operNumberSize++] = a * b; 117 } 118 else 119 { 120 operNumber[operNumberSize++] = a / b; 121 } 122 } 123 124 // 现有操作符入栈 125 operSymbol[operSymbolSize++] = c; 126 } 127 128 // 清空操作符栈 129 while(operSymbolSize > 0) 130 { 131 int b = operNumber[--operNumberSize]; 132 int a = operNumber[--operNumberSize]; 133 char op = operSymbol[--operSymbolSize]; 134 if(op == '+') 135 { 136 operNumber[operNumberSize++] = a + b; 137 } 138 else if(op == '-') 139 { 140 operNumber[operNumberSize++] = a - b; 141 } 142 else if(op == '*') 143 { 144 operNumber[operNumberSize++] = a * b; 145 } 146 else 147 { 148 operNumber[operNumberSize++] = a / b; 149 } 150 } 151 152 int temp = operNumber[0]; 153 delete [] operNumber; 154 delete [] operSymbol; 155 156 return temp; 157 } 158 159 160 //输出 161 void output(const int *a, const int len) 162 { 163 for(int i = 0; i < len; ++i) 164 { 165 cout << a[i] << " "; 166 } 167 cout << endl; 168 } 169 170 int main() 171 { 172 // 第一题测试 173 int array1[] = {1,3,5}; 174 int len1 = 3; 175 int array2[] = {77,21,1,3,5}; 176 int len2 = 5; 177 cout << "第一题测试结果:"; 178 cout << array_compare(len1, array1, len2, array2) << " "; 179 int array11[] = {1,3,5}; 180 int len11 = 3; 181 int array21[] = {77,21,1,3,5,7}; 182 int len21 = 6; 183 cout << array_compare(len11, array11, len21, array21) << endl; 184 185 186 // 第二题测试 187 cout << endl << "第二题测试结果:"; 188 int input_array[] = {3,1,2,4}; 189 int output_array[4]; 190 int len = 4, m=7; 191 array_iterate(len, input_array, m, output_array); 192 output(output_array, len); 193 194 // 第三题测试 195 cout << endl << "第三题测试结果:"; 196 char *expStr1 = "1+4*5-8/3"; 197 cout << calculate(strlen(expStr1), expStr1) << " "; 198 char *expStr2 = "8/3*3"; 199 cout << calculate(strlen(expStr2), expStr2) << endl; 200 201 return 0; 202 }
有同学指正第三题的实现(每次至多弹出一个操作符)与结构书(可以连续弹出多个操作符)上的不同,另外,空间可以更优化,数组空间可以静态,且有上界,现完善代码如下(针对第三题):
1 // 返回优先级 2 int getPriority(const char c) 3 { 4 if(c == '+' || c == '-') 5 { 6 return 1; 7 } 8 else 9 { 10 return 0; 11 } 12 } 13 //第三题 14 //四则运算表达式,用两个栈实现,一个是操作数栈,一个是操作符栈 15 int calculate(int len, char *expStr) 16 { 17 18 //用两个数组来模拟栈 19 int operNumber[3]; // 就题而言,操作数个数最多为3 20 int operNumberSize = 0; 21 char operSymbol[2]; // 就题而言,操作符的个数最多为2 22 int operSymbolSize = 0; 23 for(int i = 0; i < len; ++i) 24 { 25 char c = expStr[i]; 26 int priority; 27 if(c >= '0' && c <= '9') 28 { 29 // 是操作数 30 operNumber[operNumberSize++] = (int)(c -'0'); 31 continue; 32 } 33 34 // 是操作符 35 else 36 { 37 priority = getPriority(c); // 获得优先级,这里定义加减的优先级是大数,乘除的优先级是小数 38 while(operSymbolSize > 0 && getPriority(operSymbol[operSymbolSize - 1]) <= priority) 39 { 40 int b = operNumber[--operNumberSize]; 41 int a = operNumber[--operNumberSize]; 42 char op = operSymbol[--operSymbolSize]; 43 switch(op) 44 { 45 case '+': 46 operNumber[operNumberSize++] = a + b; 47 break; 48 49 case '-': 50 operNumber[operNumberSize++] = a - b; 51 break; 52 53 case '*': 54 operNumber[operNumberSize++] = a * b; 55 break; 56 57 case '/': 58 operNumber[operNumberSize++] = a / b; 59 break; 60 } 61 } 62 // 现有操作符入栈 63 operSymbol[operSymbolSize++] = c; 64 } 65 } 66 67 // 清空操作符栈 68 while(operSymbolSize > 0) 69 { 70 int b = operNumber[--operNumberSize]; 71 int a = operNumber[--operNumberSize]; 72 char op = operSymbol[--operSymbolSize]; 73 switch(op) 74 { 75 case '+': 76 operNumber[operNumberSize++] = a + b; 77 break; 78 79 case '-': 80 operNumber[operNumberSize++] = a - b; 81 break; 82 83 case '*': 84 operNumber[operNumberSize++] = a * b; 85 break; 86 87 case '/': 88 operNumber[operNumberSize++] = a / b; 89 break; 90 } 91 } 92 93 int temp = operNumber[0]; 94 return temp; 95 }