永川做网站的公司,wordpress升级php版本,网站建设公司推荐时代创信,南宁智慧园区网站建设目录
1.交换两个变量#xff08;不创建临时变量#xff09;
2.统计二进制中1的个数
3.打印整数二进制的奇数位和偶数位
4.求两个数二进制中不同位的个数
5.【一维数组】有序序列合并
6.获得月份天数
7.变种水仙花数
8.选择题总结tips 这篇博文主要分享操作符算…目录
1.交换两个变量不创建临时变量
2.统计二进制中1的个数
3.打印整数二进制的奇数位和偶数位
4.求两个数二进制中不同位的个数
5.【一维数组】有序序列合并
6.获得月份天数
7.变种水仙花数
8.选择题总结tips 这篇博文主要分享操作符算数转换的题目。
1.交换两个变量不创建临时变量
2.统计二进制中1的个数
3.打印整数二进制的奇数位和偶数位
4.求两个数二进制中不同位的个数
5.【一维数组】有序序列合并
6.获得月份天数
7.变种水仙花数 OJ题目一般有两类 IO型输入和输出都是自己写。接口型只需要完成接口函数就行剩余的main函数接口的调用都搞定了。 1.交换两个变量不创建临时变量
//题目1
//交换两个变量不能创建临时变量
//将数组A中的内容和数组B中的内容进行交换。数组一样大
//方法1
#includestdio.h
int main()
{int a 0;int b 0;scanf(%d %d, a, b);a a b;//aabb a - b;//ab-ba把a的值赋给了ba a - b;//ab-ab把b的值赋给aprintf(a%d b%d, a, b);return 0;
}
//方法2
#includestdio.h
int main()
{int a 0;int b 0;scanf(%d %d, a, b);a a ^ b;b a ^ b;//a^b^baa a ^ b;//a^b^abprintf(a%d b%d, a, b);return 0;
} 2.统计二进制中1的个数
//题目2
//统计二进制中1的个数
//输入一个整数 n 输出该数32位二进制表示中1的个数。其中负数用补码表示。//写一个函数返回参数二进制中 1 的个数。
//比如 15 0000 1111 4 个 1//输入10
//返回值2
//说明十进制中10的32位二进制表示为0000 0000 0000 0000 0000 0000 0000 1010其中有两个1。 //输入-1
//返回值32
//说明负数使用补码表示 -1的32位二进制表示为1111 1111 1111 1111 1111 1111 1111 1111其中32个1
//方法1
// 1234%104
// 1234/10123
// 123%103
// 123/1012
//
// 15%21 00000000 00000000 00000000 00001111 1√
// 15/27 00000000 00000000 00000000 00000110 7
// 7%21 00000000 00000000 00000000 00000110 1√
// 7/23 00000000 00000000 00000000 00000011 3
// 3%21 00000000 00000000 00000000 00000011 1√
// 3/21 00000000 00000000 00000000 00000001 1
// 1%21 00000000 00000000 00000000 00000001 1√
// 1/20结束循环
#includestdio.h
//int is_count_1(int n)//但是如果是负数就是错误的❌
int is_count_1(unsigned int n)//搞成无符号的整数就可以输入负数{int count 0;while (n)//0{if (n % 2 1)count;n n / 2;}return count;
}
int main()
{int n 0;scanf(%d, n);int retis_count_1(n);printf(%d, ret);return 0;
}
//-1
//10000000 00000000 00000000 00000001_原码
//11111111 11111111 11111111 11111110_反码
//11111111 11111111 11111111 11111111_补码
//无符号
//11111111 11111111 11111111 11111111_原码反码补码均是这个
//方法2
// 有0则为0.同时为1才为1
//((n1)1)得到的是最小位1则有 0则为0
#includestdio.h
int is_count_1(int n)
{int count 0;int i 0;for(i0;i32;i){if (((n i) 1) 1)count;}return count;
}
int main()
{int n 0;scanf(%d, n);int ret is_count_1(n);printf(%d, ret);return 0;
}//int is_count_1(int n)
//{
// int count 0;
// while(n)
// {
// if (((n 1) 1) 1)//死循环不会到达0
// count;
// }
// return count;
//}
当然还有效率更高的方法 //方法3
//nn(n-1)
//15 00000000 00000000 00000000 00001111
//15-114 00000000 00000000 00000000 00001110
//1514 00000000 00000000 00000000 00001110 消除1
//
//1514 00000000 00000000 00000000 00001110
//1514-1 00000000 00000000 00000000 00001101
// 00000000 00000000 00000000 00001100 消除1// 00000000 00000000 00000000 00001100
//-1 00000000 00000000 00000000 00001011
// 00000000 00000000 00000000 00001000 消除1// 00000000 00000000 00000000 00001000
//-1 00000000 00000000 00000000 00001011
// 00000000 00000000 00000000 00001000 消除1
//计算1的个数等于消除了几个1的个数
//18 00000000 00000000 00000000 00010010
//18-1 00000000 00000000 00000000 00010001
// 00000000 00000000 00000000 00010000// 00000000 00000000 00000000 00010000
//-1 00000000 00000000 00000000 00001111#includestdio.h
int is_count_1(int n)
{int count 0;while (n)//n!0的时候进入当n0时消除1结束循环结束{n n (n - 1);//每消除一次1计算一次 /会进位就一定会消除1count;}return count;
}
int main()
{int n 0;scanf(%d, n);int retis_count_1(n);printf(%d, ret);return 0;
}
总结
/*
方法一
思路
循环进行以下操作直到n被缩减为01. 用该数据模2检测其是否能够被2整除2. 可以则该数据对应二进制比特位的最低位一定是0否则是1如果是1给计数加13. 如果n不等于0时继续1
*/
int NumberOf1(int n)
{int count 0;while(n){if(n%21)count;n n/2;}return count;
}/*
上述方法缺陷进行了大量的取模以及除法运算取模和除法运算的效率本来就比较低。
方法二思路
一个int类型的数据对应的二进制一共有32个比特位可以采用位运算的方式一位一位的检测具体如下
*/
int NumberOf1(unsigned int n)
{int count 0;int i 0;for(i0; i32; i){if(((ni)1) 1)count;}return count;
}/*
方法二优点用位操作代替取模和除法运算效率稍微比较高缺陷不论是什么数据循环都要执行32次方法三
思路采用相邻的两个数据进行按位与运算
举例
999910 0111 0000 1111
第一次循环n9999 nn(n-1)99999998 9998
第二次循环n9998 nn(n-1)99989997 9996
第三次循环n9996 nn(n-1)99969995 9992
第四次循环n9992 nn(n-1)99929991 9984
第五次循环n9984 nn(n-1)99849983 9728
第六次循环n9728 nn(n-1)97289727 9216
第七次循环n9216 nn(n-1)92169215 8192
第八次循环n8192 nn(n-1)81928191 0可以观察下此种方式数据的二进制比特位中有几个1循环就循环几次而且中间采用了位运算处理起来比较高效
*/
int NumberOf1(int n)
{int count 0;while(n){n n(n-1);count;}return count;
} 3.打印整数二进制的奇数位和偶数位
//题目3
//打印整数二进制的奇数位和偶数位
//获取一个整数二进制序列中所有的偶数位和奇数位分别打印出二进制序列//很重要的一个点就是我们可以通过一个方法将二进制所有位
#includestdio.h
int main()
{int n 0;scanf(%d, n);int i 0;for (i 0; i 32; i){if ((n i) 1 1)printf(移动i为时此位的数字1\n);if ((n i) 1 0)printf(移动i为时此位的数字0\n);}return 0;
}//特别注意奇数位和偶数位的是从几开始循环的
//打印二进制序列的奇数位和偶数位
//拿到二进制所有位
//00000000 00000000 00000000 0000000 0
// 偶奇
//32是符号位/*
思路
1. 提取所有的奇数位如果该位是1输出1是0则输出0
2. 以同样的方式提取偶数位置检测n中某一位是0还是1的方式1. 将n向右移动i位2. 将移完位之后的结果与1按位与如果结果是0则第i个比特位是0结果是非0则第i个比特位是1
*/ #includestdio.h
int main()
{int n 0;scanf(%d, n);int i 0;printf(偶数位);for (i 1; i 32; i2)//偶数位//for(i31;i1;i-2)//偶数位{int t ((n i) 1);printf(%d , t);}printf(\n);printf(奇数位);for (i 0; i 31; i 2)//奇数位//for(i30;i0;i-2)//奇数位{int r ((n i) 1);printf(%d , r);}return 0;
} 4.求两个数二进制中不同位的个数
//题目4
//求两个数二进制中不同位的个数//描述输入两个整数求两个整数二进制格式有多少个位不同
//输入描述两个整数
//输出描述二进制不同位的个数
//输入22 33
//输出5//编程实现两个int32位整数m和n的二进制表达中有多少个位(bit)不同
//1999 2299
//输出例子:7//方法1还是使用拿到二进制数的所有位来达到题目要求//方法2
/*
思路
1. 先将m和n进行按位异或此时m和n相同的二进制比特位清零不同的二进制比特位为1
2. 统计异或完成后结果的二进制比特位中有多少个1即可
*/
//方法1
#includestdio.h
int main()
{int m 0;int n 0;scanf(%d %d, m, n);//输入两个数int i 0;int count 0;for (i 0; i 32; i){if (((m i) 1) ! ((n i) 1))count;}printf(%d, count);return 0;
}
//方法2
#includestdio.h
int main()
{int m 0;int n 0;scanf(%d %d, m, n);int r m ^ n;//因为异或操作符对应的二进制位相同为0相异为1//m和n的不同的二进制位异或后一定是1//那我们数一下r的二进制1的个数就是m和n中不同位的个数int count 0;while (r){//找到r中的1的个数//这里就可以使用第二题中的三种方法中的任何一种r r (r - 1);count;}printf(%d, count);return 0;
} 5.【一维数组】有序序列合并
//题目5
//【一维数组】有序序列合并
//描述输入两个升序排列的序列将两个序列合并为一个有序序列并输出。
输入描述输入包含三行
第一行包含两个正整数n, m用空格分隔。n表示第二行第一个升序序列中数字的个数m表示第三行第二个升序序列中数字的个数。第二行包含n个整数用空格分隔。第三行包含m个整数用空格分隔。//输出描述
输出为一行输出长度为nm的升序序列即长度为n的升序序列和长度为m的升序序列中的元素重新进行升序序列排列合并//示例
//示例1
输入 5 61 3 7 9 222 8 10 17 33 44
输出 1 2 3 7 8 9 10 17 22 33 44 方法1输入两个数组创建第三个数组把前两个数组元素全部放入进去接着再次排序方法2输入两个数组创建第三个数组可以不用创建一边比较大小放入元素一边排序一边比较大小一边打印。 //方法1
#includestdio.h
int main(){//放数据到数组里int m 0;int n 0;int i 0;scanf(%d %d, m, n);int arr1[m];int arr2[n];int arr3[mn];for (i 0; i m; i)//数组下标从0开始{scanf(%d, arr1[i]);}for (i 0; i n; i) {scanf(%d, arr2[i]);}//数据全部放到第三个数组里for(i0;imn;i){if(im)arr3[i]arr1[i];else//imarr3[i]arr2[i-m];}//冒泡排序//mn是arr3里放置的1元素多少sizeof计算的是arr3全部的大小for (i 0; i mn; i) {int j 0;for (j 0; j mn- i - 1; j){if (arr3[j] arr3[j 1]) {int tmp 0;tmp arr3[j];arr3[j] arr3[j 1];arr3[j 1] tmp;}}}for (i 0; i mn; i) {printf(%d , arr3[i]);}return 0;
}
这个方法会产生栈溢出的问题效率低下所以使用下面的方法。 关于这种思想和方法在我们的数据结构中链表中我们也会使用。 经典题目合并2条有序的链表。 //方法2
//需要变长数组
#includestdio.h
int main()
{int n;int m;scanf(%d %d, n, m);int arr1[n];int arr2[m];int arr3[mn];//放数据到数组里int i 0;for (i 0; i n; i)//数组下标从0开始{scanf(%d, arr1[i]);}for (i 0; i m; i){scanf(%d, arr2[i]);}//一边放元素一边调整顺序/* for (i 0; i m n; i){if (arr1[i] arr2[i])arr3[i] arr1[i];elsearr3[i] arr2[i];}*///for循环是一对一对的比较而我们需要的是一个数一个数比较小的放到arr3大的留下继续比较需要两个变量i0;//i调整arr1
//像for if这样i进入运算之后数值都会发生变化所以必须重新初始化。int j 0;//调整arr2int k 0;//调整arr3while(i n j m)//一直循环直到把arr1或者arr2里面的元素放置完毕{if (arr1[i] arr2[j]){arr3[k] arr1[i];//放i的元素到arr3里面i;//arr1元素需要移动一位k;//arr3元素需要移动一位}else//{arr3[k] arr2[j];j;k;}}//如果剩余arr1if (j m)//arr2用完{while(in)//条件限制arr3[k] arr1[i];}else//(i n){while(jm)//条件限制arr3[k] arr2[j];}for (i 0; i mn; i){printf(%d , arr3[i]);}return 0;
}//不用变长数组
int arr1[1000]
int arr2[1000]
int arr3[1000]//题目并没有要求创建数组arr3
//不创建arr3while(i n j m)//一直循环直到把arr1或者arr2里面的元素放置完毕{if (arr1[i] arr2[j]){printf(%d ,arr1[i]);}else//{printf(%d ,arr2[j]);}}//如果剩余arr1if (j m)//arr2用完{while(in)//条件限制printf(%d ,arr1[i]);}else//(i n){while(jm)//条件限制printf(%d ,arr2[j]);}//简化
#include stdio.h
int main()
{int n 0;int m 0;int arr1[1000] {0};int arr2[1000] {0};//输入scanf(%d %d, n, m);int i 0;for(i0; in; i){scanf(%d, arr1[i]);}for(i0; im; i){scanf(%d, arr2[i]);}//处理int j 0;i 0;while(in jm){if(arr1[i] arr2[j]){printf(%d , arr1[i]);i;}else{printf(%d , arr2[j]); j;}}if(i n){for(; jm; j){printf(%d , arr2[j]);}}else{for(; in; i){printf(%d , arr1[i]);}}return 0;
} 6.获得月份天数
//题目6
//获得月份天数
//描述 KiKi想获得某年某月有多少天请帮他编程实现。输入年份和月份计算这一年这个月有多少天。
//输入描述多组输入一行有两个整数分别表示年份和月份用空格分隔。
//输出描述针对每组输入输出为一行一个整数表示这一年这个月有多少天。
//示例1
//输入2008 2
//输出29//记住12个月的天数int m[12] { 31,28,31,30,31,30,31,31,30,31,30,31 };//平年int n[12] { 31,29,31,30,31,30,31,31,30,31,30,31 };//闰年
//数组的下标从0开始但是我们输入的月数从1开始所以放入0进去int m[12] { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//平年int n[12] { 0,31,29,31,30,31,30,31,31,30,31,30,31 };//闰年
//表示闰年的方法有两种
//数组直接表示
//平年2月→闰年
//方法1
#includestdio.h
int is_leap_year(int y)//判断闰年
{if ((y % 4 0 y % 100 ! 0) || (y % 400 0))return 1;//闰年elsereturn 0;//平年
}
int main()
{int y 0;int mouth 0;int m[12] { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//平年int n[12] { 0,31,29,31,30,31,30,31,31,30,31,30,31 };//闰年int ret is_leap_year(y);while (scanf(%d %d, y, mouth) ! EOF){if (ret 1){int k m[mouth];printf(%d, k);}else{int d n[mouth];printf(%d, d);}}return 0;}
//方法2
#includestdio.h
int is_leap_year(int y)//判断闰年
{if ((y % 4 0 y % 100 ! 0) || (y % 400 0))return 1;//闰年elsereturn 0;//平年
}
int main()
{int y 0;int mouth 0;int m[12] { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//平年//int ret is_leap_year(y);while (scanf(%d %d, y, mouth) ! EOF){int day m[mouth];//if (ret 1 mouth 2)if(is_leap_year(y)mouth 2){day;}//打印闰年的数组printf(%d, day);}return 0;}
当然这里还有一种很特别的思路如下所示
//方法3
#includestdio.h
int is_leap_year(int y)//判断闰年
{if ((y % 4 0 y % 100 ! 0) || (y % 400 0))return 1;//闰年elsereturn 0;//平年
}
int main()
{int year 0;int mouth 0;int m[12] { 31,28,31,30,31,30,31,31,30,31,30,31 };//平年//int ret is_leap_year(y);while (scanf(%d %d, year, mouth) ! EOF){int day 0;//if (ret 1 mouth 2)if (is_leap_year(year) mouth 2){day;}//打印闰年的数组switch (mouth){case 1:case 3:case 5:case 7:case 8:case 10:case 12:day 31;break;case 4:case 6:case 9:case 11:day 30;break;case 2:day 28;}printf(%d, day);}return 0;} 7.变种水仙花数
//题目7
//变种水仙花数
//描述
变种水仙花数 - Lily Number把任意的数字从中间拆分成两个数字
比如1461 可以拆分成1和461,14和61,146和1),如果所有拆分后的乘积之和等于自身
则是一个Lily Number。//例如655 6 * 55 65 * 5
1461 1*461 14*61 146*1
求出 5位数中的所有 Lily Number。//输入描述无
//输出描述一行5位数中的所有 Lily Number每两个数之间间隔一个空格。//水仙花
//12345
//12345/101234 12345%105 1234和5
//12345/100123 12345%10045 123和45
//12345/100012 12345%1000345 12和345
//12345/100001 12345%100002345 1和2345
//关于/和%
#includestdio.h
#includemath.h
int main()
{int i 0;for (i 10000; i 99999; i)//10000~99999{//判断i是否是Lily numberint j 0;int ret 0;for (j 1;j4;j)//次方{ret ret (i /(int) pow (10, j)) * (i %(int) pow(10, j));//整数_数据类型的转化_不能出现小数}if (ret i){printf(%d , i);}}
}8.选择题总结tips
位操作符是二进制位的操作符关于操作符的优先级记忆
#include stdio.h
int main()
{int a, b, c;a 5;c a;b c, c, a, a;b a c;printf(a %d b %d c %d\n:, a, b, c);return 0;
} 赋值类的优先级很低逗号表达式的优先级更低运算符优先级较高
#include stdio.h
int main()
{int a, b, c;a 5;c a;
// a加给a1结果为6用加完之后的结果给c赋值因此a 6 c 6b c, c, a, a;// 逗号表达式的优先级最低这里先算bc, b得到的是c后的结果b是7// bc 和后边的构成逗号表达式依次从左向右计算的。// 表达式结束时c和a,a会给a2给c加1此时c8a8b:7b a c;
// a先和c加结果为16在加上b的值7比的结果为23最后给a加1a的值为9printf(a %d b %d c %d\n:, a, b, c);
// a:9, b:23, c:8return 0;
}
关于转化的经典题_程序错误
#include stdio.h
int main()
{int i 1;int ret (i)(i)(i);printf(ret %d\n, ret);return 0;
}
表达式(i)(i)(i)只有操作符的优先级和结合性没法确定唯一计算路径
所以这个表达式可能因为计算顺序的差异导致结果是不一致的所以表达式是错误的表达式
可以在VS和Linux gcc测试结果可能有差异。
算数转化_数据类型的转化_下面代码的结果是
#include stdio.h
int i;//0
int main()
{i--;//-1if (i sizeof(i)){printf(\n);}else//-14{printf(\n);}return 0;
}
//一个全局变量如果不初始化的话默认初始值为0相信很多人都会算成 ,但是我们特别注意比较大小的时候数据的类型是否统一
i-1是int类型的
sizeof是size_t类型的
需要将i强制转化成size_t类型的(size_t的返回值类型是无符号整型)
也就是-1被当作无符号整数
-1被当作无符号整数的时候会成为一个非常大的数字isieof(i)
输出大于
表达式求值先看是否存在整型提升或算术转换再进行计算表达式真正计算的时候先看相邻操作符的优先级再决定先算谁相邻操作符的优先级相同的情况下看操作符的结合性决定计算顺序当然有了优先级和结合性表达式也可能有不同的计算路径导致计算结果的差异a^a^bb二进制中%2 和/2 可以得到想要的位得到二进制中的每一位((ni)1)是1则1,是0则0nn(n-1)思想数组的下标是从0开始,有符号整型的二进制位的32位是符号位,影响for循环的边界条件^操作符的使用变长数组数组怎样去输入元素循环条件的限制闰年和平年%10 %100 %1000——次方
关于以上练习题大家可以动手写一写。
新学期祝各位得偿所愿。不要忘记敲代码哦
✔✔✔✔最后感谢大家的阅读若有错误和不足欢迎指正
代码----------→【giteehttps://gitee.com/TSQXG】
联系----------→【邮箱2784139418qq.com】