概述:
环控制语句 根据对应的条件来控制对应的代码片段的执行次数(多次执行 循环执行),常用的循环 控制语句 while do while for...循环是重复执行多次代码所以对应的执行次数是可以计算的,那么对应 的执行次数和对应的条件判断中的相关条件的一个关系就是时间复杂度(时间复杂度是用于区分效率的 他是用来优化程序的)。然后对应的循环在书写过程中我们需要尽可能的避免死循环(无限循环)。
循环的三要素
-
初始值: 初始的变量值
-
迭代量:基于初始值的变化
-
判断条件: 对应的执行循环中代码的条件
常用的循环语句
-
while循环
-
do while 循环
-
for 循环
while循环
var 变量 = 初始值 while(条件表达式){ 执行的代码(循环体) 迭代 }
示例
//执行打印操作10遍
var i = 0 //初始值
//当我出现死循环的时候 在浏览器执行了打印操作 你会发现我不能进行其他的操作
//原因是JavaScript是一个单线程解析的语言
while(i<10){ //条件
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的阶乘
var i = 0
var result = 1
while(i<100){
i++
result*=i
}
console.log(result)
计算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.log('打平了')
} 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(var 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 = first * 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 = first>last?last:first
//加到对应的俩个之间的最小值停
for (var i=1;i<value;i++) {
if (first % i == 0 && last % i == 0) {
max = i
}
}
console.log(max)
break和continue
break是用于跳出 他可以跳出对应的switch块 以及对应的循环块 (跳出来了也就意味着本次对应的循 环或对应的代码执行结束了) contiue是用于跳过某个循环 下次循环继续执行
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') }
O(n) 线性阶
//这个的执行次数由对应变量n控制 所以他属于线性阶 O(n) for(var i=0;i<n;i++){ console.log('hello world') }
O(nlogn) 线性对数阶
for(var i=0;i<n;i++){ var m = 10 var n = 100 var k = 2 while(m>n){ m *= k ; console.log('hello') } }
O(n平方) 平方阶
for(var i=0;i<n;i++){ for(var j=0;j<n;j++){ console.log('hello world') } }
O(n的k次方) k次方阶
总结
从上可得 循环嵌套不会超过俩次!从对应得时间复杂度来看 我们可以得到logn和n是比较性常用得 我 们发现logn是比n要快得,所以在后续得优化中我们采用logn级别得时间复杂度来替代n。对于for循环 和while循环 对应得时间复杂度来说while要快于for循环,用while来替代for循环