C++课堂笔记三

C++课堂笔记三

for循环

1
2
3
for(表达式1;表达式2;表达式3) {
语句组
}

1
2
3
4
5
6
7
例如:
int i;
for(i=0;i<26;i++) { //连续输出26个字母
cout<<char('a'+i); //'a'+1强制转换成char类型

for(int i=0;i<26;++i) //语句组里只有一条语句可以不写{}
printf("%c",'a'+1);

for循环结构里的表达式1和表达式3都可以是用逗号连接的如干个表达式

1
2
3
4
5
6
7
8
9
10
11
for(int i=15, j=0; i>j; i-=2,j+=3) // i=i+2,j=j+3
cout<<i<<","<<j<<endl;
//15,0 13,3 11,6

例:
int n;
cin>>n;
for(int i=1;i<=n;++1) //输入一个正整数n,从小到大输出所有因子
if(n%i==0)
cout<<i<<endl; //n=15 1 3 5 15
return 0;

for循环可以嵌套,形成多重for循环

1
2
3
4
5
6
7
for(int i=0;i<n;++i)
......
for(int j=0;j<m;++j){
...... //内重循环中的语句组执行次数一共是n*m次
}
......
}

例题: 给定正整数n和m,在1至n这n个数中,取出两个不同的数,使得其和是m的因子,问有多少种不同的取法?(穷举1-n这n个数中取两个数的所有取法,对每一种取法,判断其和是不是m的因子)

1
2
3
4
5
6
7
8
int n,m;
int total = 0; //取法总数
cin>>n>>m;
for (int i=1; i<n; ++i) { //取第一个数,共n-1种取法
for (int j=i+1;j<=n; ++j) //第二个数要比第一个数大,以免取法重复
if(m%(i+j)==0)
++total;
}

while循环和do…while循环

例题: 输入若干个(至少一个)不超过100的正整数,输出其中的最大值、最小值以及所有数的和。输入的最后一个数是0,标志着输入结束。

1
2
3
4
5
6
7
8
9
int sum=0, maxN = 0, minN = 200, n;
cin>>n;
while(n) {
if(n>maxN) maxN = n;
if(n<minN) minN = n;
sum +=n;
cin>>n;
}
cout<<maxN<<" "<<minN<<" "<<sum;

do…while循环(如果希望循环至少要执行一次,可用)

1
2
3
do{
语句组
} while(表达式);

例:输出1到10000以内所有2 的整数幂

1
2
3
4
5
6
int n = 1;
do{
cout<<n<<wndl;
n*2;
}
while(n<10000);

break语句和continue语句

break语句 (可以出现在循环体中(for while do…while),作用是跳出循环

1
2
3
4
5
6
7
int n =0;
while(true){
if(n>100)
break;
++n;
}
cout<<n; //=>101

例题:如果两个不同的正整数,他们的和是他们的积的因子,就称这两个数为兄弟数,小的为弟数,大的为兄数。(枚举)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int n,m;
cin>>n>>m;
int a =m+1,b=m+1;//a,b记录已经找到的兄弟数,a是弟数,b是兄数
for(int i=n;i<m;++i){// 取弟数,共m-n种取法
if(i>(a+b)/2+1)
break;//跳出外重循环
for(int j=i+1;j<=m;++j){//取兄数
if(i+j>a+b)
break; //跳出循环
if(i*j%(i+j)==0){/发现兄弟数
if(i+j<a+b){//发现和更小的兄弟数
a=i; b=j;//更新已经找到的最佳兄弟数
}
else if(i+j==a+b&&i<a) //发现和相同但兄弟数更小的兄弟数
a=i;b=j;//更新已经找到的最佳兄弟数
}
}
}

if(a==m+1) //没找到兄弟数
cout<<"No solution.";
else
cout<<a<<","<<b;
return 0;
}

continue语句

可以出现在循环体中,作用是立即结束本次的循环,并回到循环开头判断是否要进行下次循环

例:输出1—10的偶数

1
2
3
4
for (int i=1;i<=10;++i){
if(i%2)
continue; //导致不执行后面的语句,回到循环开头
cout<<i<<","; //=> 2,4,6,8,10

OJ编程题输入数据的处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
scanf表达式的值
scanf表达式的值为int,表示成功读入的变量的个数

int n,m;
printf("%d",scanf("%d%d",&n,&m));

output:
12 56
2

40 a
1

a 40
0

scanf值为EOF(即-1)则说明输入数据已经结束

int n,m;
while(scanf("%d%d",&n,&m) != EOF){ //EOF是直接能拿来用的符号常量
printf("%d",n+m);
}

不停输入两个整数再敲回车,则不停输入他们的和,直到输入ctrl+z然后回车,程序结束


cin>>m>>n 表达式的值,在成功读入所有变量是为true,否则为false

int n,m;
while(cin>>n>>m){
printf("d",n+m);
}



处理无结束标记的OJ题目输入

输入若干个正整数,输出其中的最大值

sample input:
2 3 4 5 6 787 54532 12
sample output:
54532

int main(){
int n,mx=0;
while(scanf("%d",&n) !=EOF){//或while(scanf("%d",&n) ==1){
if(n>mx)
mx=n;
}
printf("%d",mx);
return 0;
}

用freopen重定向输入

调试程序时,每次运行程序都要输入测试数据,麻烦可将测试数据存入文件,然后用freopen将输入由键盘重定向为文件,则运行程序时不再需要输入数据

例如:

1
2
3
4
5
6
7
8
9
10
11
int main(){
freopen("c:\\temp\test.txt","r",stdin);//此后所有输入都来自文件c:\\temp\test.txt (提交时需要注释)

int n,mx=0;
while(cin>>n){
if(n>mx)
mx=n;
}
printf("%d",mx);
return 0;
}