15、奇偶数分离
有一个整型偶数n(2<= n <=10000),你要做的是:先把1到n中的所有奇数从小到大输出,再把所有的偶数从小到大输出。
- 输入: 第一行有一个整数i(2<=i<30)表示有 i 组测试数据;每组有一个整型偶数n。
- 输出: 第一行输出所有的奇数。第二行输出所有的偶数
思路
方法一:利用两个for循环分别打印奇数和偶数。
方法二:用辅助字符串的方式(空间上字符串是优于数组的)。
- 通过一个for循环判断奇偶数的同时,打印奇数并把偶数累加到辅助字符串中。
- for循环结束,奇数已经打印完毕,接着直接打印字符串(即偶数打印完毕),这样就实现了隔行打印的效果,并且也无需数组存储。
具体实现-方法一
//法一:用两个for循环打印奇偶
#include<stdio.h>
int main()
{
int n,even;//n表示有几组测试数据,even表示整型偶数
printf("输入需要测试的行数和整型偶数:");
scanf_s("%d", &n);
while (n--) {//n为真且even数为偶数
scanf_s("%d", &even);
if (even % 2 != 0)
return 0;
int arr[500] = {0};
printf("奇数:");
for (int i = 1; i <= even; i++) {//遍历1到n的所有数
if (i & 1) {//变量i位于1是否等于1,是就是奇数,否则是偶数
printf("%d ", i);//打印奇数
}
}
printf("\n");
printf("偶数:");
for (int j = 1; j <= even; j++) {//打印偶数
if (j % 2 == 0) {
printf("%d ", j);//打印偶数
}
}
printf("\n");
}
return 0;
}
运行结果
复杂度
- 时间复杂度 O(n^2)--- 不考虑输入测试循环多少次的数据,需要两个个for循环分别要执行n次,其中n为整型偶数,所以为n*n。
- 空间复杂度 O(1)--- 没有用到存储的
具体实现-方法一
#include <iostream>
#include<string>
using namespace std;
int main() {
int i=0,num = 0; //i表示几组测试数据,num表示每组的整型偶数
cin >> i; //scanf_s("&d", &i);c语言运行有警告:传递给 "scanf_s" 的额外参数。
while (i-- && cin>>num) {
if (num % 2 != 0) return 0;//当num不是整型偶数 就推出
string str = ""; //辅助字符串
for (int j = 1; j <= num; j++) {//循环判断1到n之间的数
if (j & 1) cout << j << ' ';// printf("%d ", num);//打印奇数
else str += to_string(j) + ' ';//获取偶数
}
cout << endl << str; //printf("%d ", str);//打印偶数 有警告
}
return 0;
}
复杂度
- 时间复杂度 O(n)--- 不考虑输入数据所占用的时间,仅需要一个for循环需要执行n次,其中n为整型偶数
- 空间复杂度 O(n)--- 使用辅助字符串大小为n/2,其中n为整型偶数
小结
判断奇数偶数方式:
方法一:
利用取模:变量%2==0为偶数,变量%2!=0为奇数;
方法二:
&位于运算符,变量1&变量2,
进行计算时,将会把类型提升为int。
运算法则是在二进制数下,相同位的两个数字都为1,则为1;
若有一个不为1,则为0。
- &运算通常用于二进制取位操作,
- n为偶数时,相应的最低位为0,n&1的结果就是0,
- n为奇数时,对应的二进制数最低位一定为1,n&1的结果就是1