JavaScript的字符串、数组作业讲解

第1题

编写函数repeat(char,n) 实现重复char字符串n次。比如repeat("★",6)返回”★★★★★★”

方法1:
我们现在发现,只需要进行n次的相同操作:每次str末尾增加1颗★
str增加字符,使用连字符,或者用str.concat();

str += “★” 这条语句重复执行n次就可以了。

1
2
3
4
5
6
7
function repeat(char,n){
var str = ""
for(var i = 1 ; i <= n ; i++){
str = str.concat(char)
}
return str;
}

方法2:

二分法

首先我们来看看刚才的算法,有没有什么效率问题?效率低下。

比如我们要制造16颗★,那么我们刚才的算法,要重复执行16次,其实没有必要。

因为★ →★★ → 直接复制自己→★★★★→直接复制自己→★★★★★★★★→16颗星星。

也就是说,我们没有必要一次都增加一颗星星,因为我们已经在第二次循环的时候,得到了★★,那为什么不直接复制自己得到4颗呢??

现在的问题来了,我们的n不一定是2的某次方。比如我们输入16,可以按倍数来。比如用户输入13,怎么办?

其实有办法,因为我们发现,任何数字都能够直接表示为1、2、4、8、16、32、64……的和。

比如:

7 = 4 + 2 + 1;

9 = 8 + 1;

13 = 8 + 4 + 1;

29 = 16 + 8 + 4 + 1;

任何数字都能拆分为1、2、4、8、16、32、64……的和。

所以我们现在就能想到一种算法,就是把这个星星的数量,就在这个数字拆分的那个数值上,进行复制一倍。

比如我们现在要13颗星星,那么1颗(要) → 2颗(不累加) → 4颗(要) → 8颗(要)

伪代码:

1
2
3
4
5
6
7
8
9
10
循环开始之前,
结果串str “”
临时串char “★”
数量n

循环:
如果n是奇数,那么str要加上char;如果n是偶数,str不变。(奇变偶不变)
n = parseInt(n / 2); //n越除越小
char = char + char; //每次循环,char都要倍增。
循环直到n1截止。

试着遍历一下repeat(“★”,13)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
循环开始之前:
str “”
char “★”
n 13

1次循环:
n此时13是奇数,str就要加上char,所以str变为★
n变为6
char要复制自己一倍,char变为★★

2次循环:
n此时6是偶数,str不变。str仍为★
n变为3
char要复制自己一倍,char变为★★★★

3次循环:
n此时3是奇数,str就要加上char,所以str变为★★★★★
n变为1
char要复制自己一倍,★★★★★★★★

4次循环:
n此时1是奇数,str就要加上char,所以★★★★★★★★★★★★★
n已经是1了,不需要再除了,退出循环,打完收工。

叫做“1248因数法”、“1248拆分法” 把任何一个数字拆成1、2、4、8、16……和。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function repeat(char,n){
var str = "";
while(true){
if(n % 2 == 1){
//奇变偶不变
str += char;
}
//终点验证
if(n == 1 || n == 0){
break;
}
//改变n的值
n = parseInt(n / 2);
//每次循环,char都要倍增
char = char + char;
}
return str;
}

第2题

在控制台输出图形:

1
2
3
4
5
    *
***
*****
*******
*********

一共5行,比如行号是i,i从1开始,每行的内容: 5-i个空格 和 2i - 1个星星
重复空格5-i次,重复星星2i-1次。

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
<script type="text/javascript">
var str1;
var str2;
var str;
for(var i = 1 ; i <= 5 ; i++){
str1 = repeat(" ",5 - i);
str2 = repeat("*",2 * i - 1);
str = str1 + str2;
console.log(str);
}



function repeat(char,n){
var str = "";
while(true){
if(n % 2 == 1){
//奇变偶不变
str += char;
}
//终点验证
if(n == 1 || n == 0){
break;
}
//改变n的值
n = parseInt(n / 2);
//每次循环,char都要倍增
char = char + char;
}
return str;

}
</script>

第3题

编写函数rev(char) 实现将字符串char倒置,比如rev("spring") 返回”gnirps”

方法1:就是for循环从最后一位开始取源字符串的字符,然后拼接到新的串中。

经典面试题,经典解法。
就是for循环从最后一位开始取源字符串的字符,然后拼接到新的串中。
str.charAt(str.length - 1); 就是最后一位
str.charAt(str.length - 2) ;就是倒数第二位

1
2
3
4
5
6
7
function rev(char){
var str = "";
for(var i = char.length - 1 ; i >= 0 ; i--){
str += char.charAt(i);
}
return str;
}

方法2:字符串 →数组str.split→ 倒置arr.reveer()→ 字符串arr.join(“”)

以后一看见倒置这个词,就要立即想到数组!
数组有一个东西,reverse()可以立即将数组倒置。

1
2
3
4
5
6
7
8
function rev(char){
//字符串 → 数组
var arr = char.split(""); //按字母拆开
//数组倒置
arr.reverse();
//拼接成为字符串
return arr.join("");
}

第4题

将字符串”i come from beijing“倒置,即控制台输出”beijing from come i

语句直接写在程序中,不需要用户输入。

1
2
3
4
5
6
7
8
9
10
11
<script type="text/javascript">
var str = "i come from beijing";
//字符串 → 数组
var arr = str.split(" ");
//数组倒置
arr = arr.reverse();
//数组 → 字符串
str = arr.join(" ");

alert(str);
</script>

第5题

编写函数rightchange(char,n) 实现字符串char循环右移n位。

比如rightchange("abcdefg",2)返回”fgabcde”。

方法1:就是大家想到的用数组,因为数组有popunshift();

arr.unshift(arr.pop()):把最后一位挪到第1位。

1
2
3
4
5
6
7
8
9
function rightchange(char,n){
//转为数组
var arr = char.split("");
//循环执行右移
for(var i = 1 ; i <= n ; i++){
arr.unshift(arr.pop());
}
return arr.join("");
}

方法2:原来:abcdefg (移动2) ,变为:fgabcde

fgabcde = fg + abcde = abcdefg.substr(-2) + abcdefg.substr(0 , length - 2);
移动a就是:原.substr(-a) + 原.substr(0 , length - a);

1
2
3
4
5
function rightchange(char,n){
n = n % char.length; //子串长度7,移动8位,等于移动1位
if(n == 0) return char; //移动0位,就是返回原字符串
return char.substr(-n) + char.substr(0,char.length - n);
}

第6题

编写函数maxr(char)返回字符串char中最长的连续重复字母。

比如maxr("mmmiijjjjkkkkkkssptr")返回"kkkkkk"

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
//双指针法,返回字符串char中最长的连续重复字母

function maxr(char){
//两个指针
var a = 0;
var b = 1; //b的初始位置就是a的右边1位
var maxLength = 0; //重复的最大的数量
var maxletter = ""; //重复数量最多的字母

//循环一直做一直做,直到a指针指向了最后字母
while(a != char.length - 1){
//判断,两个指针指向的字母是否一样
if(char.charAt(b) == char.charAt(a)){
//两个指针指向的字母是相同的,那么b指针右移
b++;
}else{
//两个指针指向的字母不同
//和当前最大的进行比较
if(b - a >= maxLength){
//两个指针之间的距离比最大的还大,现在的b-a就是最大的距离
maxLength = b - a;
maxletter = char.charAt(a); //a指针指向的就是这个字母
}

//让a指针右移
//b指针也要跟着复位,就是a+1的位置
a++;
b = a + 1;
}
}
return maxletter;
}

第7题

有10个学生的成绩存在数组中,请统计大于等于平均成绩的人数。

成绩直接以数组形式写在程序中,不需要用户输入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var scoreArr = [6,45,23,56,76,89,34,23,65,23];

//统计平均成绩,就要有总成绩
var sum = 0;
for(var i = 0 ; i <= scoreArr.length - 1 ; i++){
sum += scoreArr[i];
}

//平均成绩
var average = sum / scoreArr.length;

//大于等于平均成绩的人数
//又需要一个循环
var count = 0;
for(var i = 0; i <= scoreArr.length - 1 ; i++){
if(scoreArr[i] >= average){
count++;
}
}

alert("大于等于平均成绩的人数" + count);

第8题

有10个学生的成绩存在数组中,请统计最高分,最低分,并将最高分和最低分学生的下标输出到控制台。

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
//有10个学生的成绩存在数组中,请统计最高分,最低分,并将最高分和最低分学生的下标输出到控制台

var scoreArr = [6,45,23,56,76,89,34,23,65,23];

//最大值最小值
var max = 0; //如果你这个成绩比max还大,那么你就成为max
var min = 100; //如果你这个成绩比min还小,那么你就成为min

var maxindex = 0; //最大数字的下标
var minindex = 0; //最小数字的下标

//经典的找数组中最大值的方法
for(var i = 0 ; i < scoreArr.length ; i++){
//如果这个值比max还大,那么你就成为max
if(scoreArr[i] > max){
max = scoreArr[i];
maxindex = i;
}
//如果这个值比min还小,那么你就成为min
if(scoreArr[i] < min){
min = scoreArr[i];
minindex = i;
}
}

console.log("最大数" + max, "最小数" + min,"最大数下标" + maxindex,"最小数下标" + minindex);

第9题

勾股定理:直角三角形中,两个直角边的平方和,等于斜边平方和。寻找三边的长度都不大于100,并且三边边长都是整数的可能,在控制台输出。

方法1:穷举法

1
2
3
4
5
6
7
8
9
10
for(var a = 1 ;  a <= 100 ; a++){
for(var b = 1 ; b <= 100 ; b++){
for(var c = 1 ; c <= 100 ; c++){
if(a * a + b * b == c * c){
console.log(a , b ,c);
break;
}
}
}
}

方法2:设A验B

1
2
3
4
5
6
7
8
9
10
for(var a = 1 ; a <= 100 ; a++){
for(var b = 1 ; b <= 100 ; b++){
var c2 = a * a + b * b; //c的平方
//判断c2的平方根是不是整数,就是判断c是不是整数
var c = Math.sqrt(c2);
if(c == parseInt(c) && c <= 100){
console.log(a , b ,c);
}
}
}