约瑟夫环问题,假设有10个人围成一圈,从1,开始报数,数到3的人退出,下一个人继续从1开始数,问,最后剩余的是哪一个人?
思路,1.剩余的人是第几个,返回值是整型,将这10个人放到一个数组中,数到3的人退出,直到最后只剩下一个人,数组要循环遍历。2.参数设定,用left 变量来表示剩余人数,count变量表示报数器,num表示指定退出的数,while(left > 1),剩余人数大于1,就一直进入循环,再循环内部,先判断这个人报的数是不是3,如果不是,count++;,同时,i++,数组向后遍历。如果这个人报的数是3,那么count得变成0,同时剩余人数left得--,i++;3.第一遍数组完全遍历后,也就是第十个人报数1的时候,怎么再次循环遍历剩余的数据?在循环里面进行条件判断时,我们会发现,不管报的数是不是指定退出的数3,i 都得自增,让数组向后遍历,每次i自增后,都让i对10取余,这样无论i自增到多少,对10取余后,都是个位数,从而实现数组的循环遍历。这里对第二个条件进行补充,怎么判断这个人报的数是不是三,我如果第i 个人报数为3,就让arr[i] = -1;这样条件判断时,if(arr[i] !=-1){count++;},count 是计数器,如果他等于3 ,那么就把-1赋值给arr[i]; if(count=num){arr[i] = -1;……},同时也不影响第三步循环遍历数组。
最后一步,返回值是数组中的某一个数arr[i];
for(int i = 0; i < len; i++){
if(arr[i] != -1){ return arr[i];}
所以封装的函数为一个返回值为整型,形式参数为数组名,数组长度,指定退出的数num
代码如下
int ysf_cycle(int* arr, int len, int num) {
int left = 10;//剩余人数
int i = 0,count = 0;
while (left > 1) {
if (arr[i] != -1) {
count++;
}
if (count == num) {
arr[i] = -1;
count = 0;
left--;
}
i++;
i = i % len;
}
for (int i = 0; i < len; i++) {
if (arr[i] != -1) {
return arr[i];
}
}
//return -1;
}
int main() {
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int len = sizeof(arr) / sizeof(arr[0]);
printf("%d \n", ysf_cycle(arr, len, 3));
return 0;
2.最简单的字符串转整型就是把字符串常量“123”,转变成十进制的123。
思路:先用遍历这个字符串数组,得到每一个字符。2.要获取字符串中字符的个数bit,3.用数学公式,1*10^(bit - 1) + 2*10(bit-2)+3*10(bit - 3) . 怎么获取字符串中字符的个数,在头文件<ctype.h>中,有一个isdight函数,用于判断这个字符是不是数字字符,用法如下,字符串的结尾标记'\0',
int getbit(const char* arr) {
int count = 0;
while (*arr != '\0') {
if (isdigit(*arr)) {
count++;
}
arr++;
}
return count;
}
3.获取位数后,用数学公式计算
int my_atoi(const char*arr) {
int result = 0;
int bit = getbit("123");
while (*arr != '\0') {
result+=(*arr - '0')* pow(10, bit - 1);
bit--;
arr++;
}
return result;
}
int main() {
printf("%d\n", my_atoi("123"));
return 0;
}
3.一个数组中有n个数据,怎么样把后面m 个数据移到前边,前面n - m 个数据移到后面,比如
123456,给它换成56,1234。思路:第一步,用一个逆转函数,将123456变为654321,第二步,将6和5用逆转函数转变成56,第三步,用逆转函数将4321转变成1234。
具体实现: 逆转函数,在数组123456中,将1和6交换,2和5交换,3和4交换。6个数交换3次,所以,数组长度len可以控制循环次数,用len/2来控制。第二个问题,数组1到6交换后,654321,第二次交换6和5的左右下标,所以,逆转函数中要有的参数有左右下标,还有数组名
代码如下
void reverse(int* arr, int left,int right,int len) {
for (int i =0; i<len / 2; i++) {
int temp = arr[i+left];//i+加left可以保证第三次交换的左下标从2号下标开始,
arr[i+left] = arr[right-i];
arr[right-i] = temp;
}
}
void adjust_array(int*arr,int len,int m) {
reverse(arr, 0, len-1,len);
reverse(arr, 0, m-1,m);
reverse(arr, m, 5, len -= m);
}
int main() {
int arr[] = { 1,2,3,4,5,6 };
int len = sizeof(arr) / sizeof(arr[0]);
adjust_array(arr,6,2);
//reverse(arr, 0, 5,6);
for (int i = 0; i < len; i++) {
printf("%3d", arr[i]);
}
return 0;
}