概述:
循环控制语句 根据对应的条件来控制对应的代码片段的执行次数(多次执行 循环执行),常用的循环控制语句while 、do while、for...循环是重复执行多次代码所对应的执行次数是可以计算的,那么对应的执行次数和对应的条件判断中的相关条件的一个关系就是时间复杂度(时间复杂度是用于区分效率的 它是用来优化程序的)。然后对应的循环在书写过程中我们需要尽可能地避免死循环(无限循环)。
循环的三要素
-
初始值 初始的变量值
-
迭代量 基于初始值的变化
-
判断条件 对应的执行循环中代码的条件
常用的循环语句
-
while循环
-
do while循环
-
for循环
while循环
var 变量 = 初始值 while(条件表达式){ 执行的代码(循环体) 迭代 }
示例
//执行打印操作10遍
var i = 0//初始值
//当我出现死循环的时候 在浏览器执行了打印操作 你会发现我不能进行其他操作
//原因是JavaScript是一个单线程解析语言
while(i<0){
i++
console.log('hello world'+i);
}
练习 计算1-100的和
var i = 0 //初始值
var sum = 0 //用于存储和的变量
while(i<100){ //判断条件进入对应的循环体
i++ //迭代量变化
sum+=i; //将对应的变量的值加给对应的和
}
console.log(sum);
计算1-100的阶乘
//计算1-100的阶乘
// var i = 0;
// var product = 1;
// while(i<100){
// i++;
// product *= i;
// }
// console.log(product);
计算1-100中奇数位的阶乘
//计算1-100中奇数位的阶乘
var i = 0;
var result = 1;
while(i<100){
i++;
if(i%2!=0){
result *=i;
}
}console.log(result);
do while
var 变量 = 初始值 do{ 迭代量 循环体 }while(条件)
特点:先做后判断 最少执行一次
示例
//打印100遍hello world
var i = 0;
do{
console.log('hello world');
i++;
}while(i<100)
练习
计算1-100的偶数和
var i = 0;
var sum = 0;
do{
i++;
if(i%2==0){
sum += i;
}
}while(i<100);
console.log(sum)
计算100-1000的水仙花数之和153 1的三次方+5的三次方+3的三次方 == 本身的(153)每位的三次方的和等于本身就是水仙花数
var i =100;
var sum = 0;
do{
//获取对应的i值个位 十位 百位 进行对应的判断
var a = i % 10;
var b = parseInt(i/10) % 10
var c = parseInt(i/100)
if(Math.pow(a,3)+Math.pow(b,3)+Math.pow(c,3)==i){
console.log("i");
sum +=i;
}
i++;
}while(i<1000);
console.log(sum);
do while和while以及使用场景
do while是先执行后判断 最少执行一次(常用于人机交互)
while是先判断后执行 最少执行0次(对应的循环处理)
猜拳游戏
//0 石头 1 剪刀 2 布 Math.random 随机取0-1的数 不包括1,包含0
var computedNumber = parseInt(Math.random()*3)
do {
//用户出拳操作
var userNumber = prompt('请输入对应的内容 0 石头 1 剪刀 2 布')
if(userNumber !=0 && userNumber != 1 && userNumber !=2){
alert('输入出错 重新输入')
}
//对应的比对
else if(computedNumber == userNumber){
console.lgo('打平了')
}else if((computedNumber == 0 && userNumber == 2) || (computedNumber == 2 && userNumber ==1)||(computedNumber == 1 && userNumber == 0)){
console.log('恭喜你取胜了')
}else{
console.log('很遗憾,你输了')
}
}while(userNumber !==0 && userNumber !=1 && userNumber!=2)
for
for循环跟while之间可以互相转换也就说他们对应的运行过程是一样的
for(初始值;条件;迭代量){ 循环体 }
示例
for(var i=1;i<=100;i++){//执行101次
//你声明初始值是多少 打印的第一个值就是多少 i++属于后运行的 里面是执行100次
console.log(i)
}
console.log(i)
for(;;) //死循环
练习
打印五个*
for(var i=0;i<5;i++){
console.log('*')
}
计算1-5的阶乘
var result = 1
for(i=1;i<=5;i++){
result *=i
}console.log(result)
循环嵌套
所有的循环都可以进行嵌套 不同循环之间可以相互嵌套
for(初始值;条件;迭代量){ for(初始值;条件;迭代量){ 执行的代码(执行的次数是对应的内外两个循环的次数乘积) } } var 变量 =初始值 while(条件表达式){ 执行的代码(循环体) 迭代 var 变量 = 初始值 while(条件表达式){ 执行的代码(循环体) 迭代 } } for(初始值;条件;迭代量){ var 变量 = 初始值 while(条件表达式){ 执行的代码(循环体) 迭代 } } .....
嵌套在最里面的那个循环执行的次数是所有的循环次数的乘积
示例
//打印一个正方形 5行10列
var str = ""
for(var i=0;i<5;i++){
for(var j=0;j<10;j++){
str +="*"
}
str +='\n'
}
console.log(str);
//第二种
for (var i=0;i<5;i++){
var line =''
for(var j=0;j<10;j++){
line +='*'
}
document.write(line+'<br/>')
}
练习
打印1-100内所有的质数(除了1和本身没有其他的数可以整除)
//从2数到100
for(var i=2;i<=100;i++){
var count = 0//记录能整除的数的个数
//从2开始到本身-1结束 如果在这个范围内有可以整除的就证明他不是质数 没有的话就是质数
//记录能整除的数
for(var j=2;j<i-1;j++){
if(i%j==0){
count++
}
}
//当前的个数如果为0 就打印
if(!count){
console.log(i)
}
}
输入两个数的值 求出它们的最小公倍数 和最大公约数
//最小公倍数
var first = prompt()
var last = prompt()
//设置一个最小公倍数为它们之间的乘积
var min = fisrt * last
for(var i=first*last;i>1;i--){
if(i%first == 0 && i%last ==0){
min =i
}
}console.log(min)
//设置一个最大公约数为1
var max = 1
var value = fisrt>last?last:first
//加到对应的两个之间的最小值停
for(var i=1;i<value;i++){
if(first%i==0 && last%i ==0){
max=1
}
}console.log(max)
break和continue
break是用于跳出 它可以跳出对应的switch块 以及对应的循环块(跳出来了也就意味着本次对应的循环或对应的代码之行结束了)
continue是用于跳过某个循环 下次循环继续执行
break示例
for(var i=1;i<5;i++){
if(i%2==0){
break;//结束了当前的循环
}
console.log(i)//1
}
continue示例
for(var i=1;i<5;i++){
if(i%2==0){
continue//跳过本次循环,执行下一次循环
}
console.log(i)//1 3
}
练习
打印以下图形
* *** ***** *******
for(var i=0;i<4;i++){
var line=''//接收每一行的内容
for(var j=0;j<2*i+1;j++){
line +="*"
}
document.write(line+'<br/>')
}
* *** ***** *******
//每行的* 1 3 5 7
//每行的空格 3 2 1 0
for(var i=0;i<4;i++){
var line = ''//接收每行的内容
//打印空格的循环
for(var k=0;k<3-i;k++){
line+=" ";
}
for(var j=0;j<2*i+1;j++){
line+='*'
}
document.write(line+'<br/>')
}
50-100之间 跳过所有的里面带7和7的倍数 将其他的全部打印
for(var i=50;i<100;i++){
if(parseInt(i/10)==7||i%10==7||i%7==0){
continue;
}
console.log(i)
}
扩展内容(时间复杂度)
时间复杂度概述
在恒定的环境内,他执行的次数和对应的变量的比列构成的值为时间复杂度。时间复杂度是在一定程度上表示当前的程序的运行速度,时间复杂度越低那么运行的速度就越快。还有一个就是我们需要考虑的空间复杂度,空间复杂度是指你的程序在运行的时候开辟的内存大小,空间复杂度越低占用的内存就越小(内存不再优先考虑)
时间复杂度使用字母O来表示 它的对应分类和其执行次数的比列是相关的
O(1)常数阶
console.log('hello world')//一切没有变量来控制的 只执行一次的代码它属于常数阶 O(1)
O(logn)对数阶
//2 * 2 * 2 100-10求二的对数 log2(n-m) O(logn)
var m = 10
var n = 100
var k = 2
while(m>n){
m *=k;
console.log('hello world')
}
O(n平方)平方阶
for(var i=0;i<n;i++){
for(var j=0;j<n;j++){
console.log('hello word')
}
}
O(n的立方)立方阶
for(var i=0;i<n;i++){
for(var j=0;j<n;j++){
for(var k=0;k<n;k++){
console.log('hello world')
}
}
}
O(n的k次方)k次方阶
总结
从上可得 循环嵌套不会超过两次!从对应的时间复杂度来看 我们可以得到logn的和n是比较常用的 我们发现logn是比n要快的,所以在后续的优化中我们采用logn级别的时间复杂度来代替n。对于for循环和while循环 对应的时间复杂度来说while要快于for循环,用while来替代for循环