文章目录
1. Java 有n个整数,使其前面各数顺序向后移 m 个位置,最后m个数变成最前面的m个数
用数组来存放这n个整数,但由于数组创建后大小是固定的,移动不了,因此一般选择新建一个数组来存放目标数组。
通过举例测验,发现了它的规律:
顺序后移之后的新数组由两部分组成,前一部分是原数组的 (n-m)~n 的元素,
后一部分是原数组的 0~(n-m) 的元素
import java.util.*;
public class Test {
public static void main(String [] args){
System.out.print("请输入整数个数n:");
Scanner scan = new Scanner(System.in);
int n=scan.nextInt();
int array[]= new int [n];
int arr[]=new int[array.length];
for(int i=0;i<n;i++) {
array[i]=(int)(Math.random()*100); //随机生成一个由n个整数组成的一维数组
System.out.print(array[i]+" ");
}
System.out.println();
System.out.print("前面各数顺序后移m: ");
int m=scan.nextInt();
int a=0;
for(int i=n-m;i<n;i++) {//先把(n-m)~n的元素复制到新数组里
arr[a]=array[i];
// arr[i]=array[(i+m)%n];//错误规律,不普遍适用
a++;
}
for(int i=0;i<n-m;i++) {//再把0~(n-m)的元素复制到新数组里
arr[a]=array[i];
a++;
}
for(int i=0;i<n;i++) {
System.out.print(arr[i]+" ");
}
}
}
运行结果:
之后又了解到一个解决本题的方法,
是利用 冒泡排序 解决的,(不理解冒泡排序的,可以先去了解下 点击链接 )
具体代码如下:
public static void main(String[] args) {
int [] x= {1,2,3,4,5,6,7,8,9};
a(x,3);
for (int i = 0; i < x.length; i++) {
System.out.print(x[i]+",");
}
}
static void a(int [] x,int m) {
//后移m位.要进行 x.length-m次冒泡
for(int i=0;i<x.length-m;i++) { //外层循环控制冒泡的趟数
for(int j=0;j<x.length-1;j++) { //内层循环控制一趟循环需要比较的次数
int t=x[j];
x[j]=x[j+1];
x[j+1]=t;
}
}
}
这个方法从代码上来看比上一个方法简单多了,但是性能方面不怎么好,双重循环,时间复杂度是 O(n^2) ,但不可否认确实是一种新的解题思想。
2. 有一个数组,从中间选一个元素, 写一算法,把所有大于这个数的元素放到这个数后面,小于的放在这个数前面
{88,6,3,9,12,10,33,7,44}
话说,一开始看到这个题,我的想法是,第一个数是88,比12大,要放在12的后面,但是把88赋值给12的下一个元素的话就会把人家原来数组那个位置的元素覆盖掉,那我该怎么把88插入到10的后面呢?
数组大小固定,要插入一个数不就溢出了么?要不重新建一个数组存放?
自此,我的思想就崩向了远方…😳( ╯□╰ )
后来百思不得其解的我,问了同学,哦,比大小,直接输出就好了。
唉~本来简单的这个题被我复杂化,,
我还是 图样图森破了。。。惭愧啊。。
public class Test {
public static void main(String[] args) {
//有一个数组,从中间选一个元素, 写一算法,把所有大于这个数的元素放到这个数后面,所以小于的放在这个数前面
int array[]={88,6,3,9,12,10,33,7,44};
System.out.println("自定义的数组为:");
for(int i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
System.out.println();
int index=array[(array.length)/2]; //取一中间数
System.out.print("取到的中间数是:"+index);
System.out.println();
System.out.println("按规律排序的数组为:");
for(int i=0;i<array.length;i++){
if(array[i]<index){
System.out.print(array[i]+" "); //比大小直接输出即可
}
}
System.out.print(index+" ");
for(int i=0;i<array.length;i++){
if(array[i]>index){
System.out.print(array[i]+" ");
}
}
}
} //注意:本题只需要将比中间数小的放在前面,大的放在后面,无需排序。
运行结果:
3. 编写一个程序,生成0-9之间的100个随机整数并且显示每一个数的个数
一段比较简单的程序~
public class Test{
public static void main(String[] args) {
int array[]=new int[100];
int m=0;//缓存数组元素个数
System.out.println("随机生成的数组是:");
for(int i=0;i<array.length;i++) {
m++;
array[i]=(int)(Math.random()*10);
System.out.print(array[i]+" ");
if(m%10==0) {
System.out.println();//10个一行输出,方便查看
}
}
int count=0;
for(int i=0;i<=9;i++) {
for(int j=0;j<array.length;j++) {
if(array[j]==i) {
count++;
}
}
System.out.println(i+"有"+count+"个");
count=0;//count清零,重新累加,也可以将count的初始化写在外循环里,就不用写这句了
}
}
}
运行结果:
4. 找出1000以内的所有完数
写的时候感觉挺简单,,写完后一运行,结果只有一句 :
1000以内的完数有:
那数呢?怎么没有数呢?
百思不得其解。。。😵😵
让别人帮我看了下,哈哈。找到了原因。
究其根本,是一个 变量的作用域 问题。我把它初始化在了循环体外,导致循环的时候,它不清零,一直累加,从而计算不出结果,,😳😳
糟心。
以下是完整代码:
//编程 找出1000以内的所有完数
//一个数如果恰好等于它的因子(除了本身之外的因数)之和,这个数就称为 "完数 "。例如6=1+2+3.
public class WanShu{
public static void main(String[] args) {
int n=2;//1不是完数,从2开始
//int s=0;//缓存因子的和 s如果在这里初始化,在执行循环的时候就不会清零了,就会导致s一直累加,找不到要求的结果
System.out.println("1000以内的完数有:");
while(n<=1000) {
int s=0;
for(int i=1;i<n;i++) {
if(n%i==0) { //除的开就是因子
s+=i; //计算这个数的因子之和
}
}
if(s==n) {
System.out.print(n+" ");
}
n++;
}
}
}
运行结果:
谨记:写代码的时候,一定要注意变量的作用域
问题!
不注意,会出人命的!!!
/(ㄒoㄒ)/~~
5. 求一个n*n矩阵对角线元素之和
比较简单的一段程序~~
import java.util.*;
//求一个n*n矩阵对角线元素之和
public class Test{
public static void main(String[] args) {
System.out.print("请输入n*n矩阵的n值:");
Scanner scan =new Scanner(System.in);
int n=scan.nextInt();
int array[][]=new int[n][n];//用二维数组来缓存一个n*n矩阵
int s=0;//缓存对角线元素之和
for(int i=0;i<n;i++) { //遍历矩阵
for(int j=0;j<n;j++) {
array[i][j]=(int)(Math.random()*10);//随机生成n*n个元素,存放到数组里
System.out.print(array[i][j]+" "); //打印数组
if(i==j||i+j==n-1) {//判断主副对角线
s+=array[i][j]; //求对角线元素之和
}
}
System.out.println();
}
System.out.println(n+"*"+n+"矩阵对角线元素之和是"+s);
}
}
运行结果:
6. 打印杨辉三角
经典问题
打印图形,最重要的是要找到规律。
具体规律详见注释。
public class YangHuiSanJiao{
public static void main(String[] args) {
int array[][]=new int [10][10];
for(int i=0;i<10;i++){
array[i][i]=1;//对角线全是1
array[i][0]=1;//第一列全是1
}
for(int i=2;i<10;i++) {//从第三行开始
for(int j=1;j<=i-1;j++) {//每行从第二列开始
array[i][j]=array[i-1][j-1]+array[i-1][j];
//第i行j列的值 = 第i-1行j-1列的值 + 第i-1行j列的值
}
}
for(int i=0;i<10;i++) {
for(int j =9; j >= i; j --){
System.out.print(" ");//打印空格,没有该循环,将是一个直角三角形,如下图运行结果
}
for(int j=0;j<=i;j++) {
System.out.print(+array[i][j]+" ");//打印杨辉三角
}
System.out.println( );
}
}
}
运行结果:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
7. 有一个数组由0和其他数字组成, 其中如果是0的话,必须是连续5个以上的0才算合法, 编写程序,把程序中 非法出现的 (就是连续个数少于5个) 的0 全挑出来,打印其数组开始位置索引,结束位置索引
例: int [] x={0,0,3,4,5,0,3,0,0,0,1,0,0,0,0,0,9};
输出:
非法序列: 从索引:0 到 1有 2个0
非法序列: 从索引:5 到 5有 1个0
非法序列: 从索引:7 到 9有 3个0
按题要求,第一次设计代码。
public class Test{
public static void main(String[] args) {
int [] x={0,0,3,4,5,0,3,0,0,0,1,0,0,0,0,0,9};
int count=0; //缓存零的个数
int last=0; //缓存连续0的最后一个0的索引
for(int i=0;i<x.length;i++) {
if(x[i]==0) {
count++;
}
else {
last=i-1; //元素不是0的时候执行else语句,此时的i为连续零的下一个非零元素的索引
if(count>0&&count<5) {
System.out.println("非法序列:从索引 "+(last-count+1)+" 到 "+last+" 有 "+count+" 个0");
} //连续零的第一个零的索引 = 最后一个零的索引 - (count-1)
count=0;//清零,重新累加
}
}
}
}
运行结果:
第一次完成这个代码的时候,觉得思想挺正确。
运行结果也莫得问题~~
符合原题输出要求~
But,在老师的提示下,测试了下边界值,,发现我 终究 还是 草率了。。😳( ╯□╰ )
我修改了原数组,在最后加了4个0,
int [] x={0,0,3,4,5,0,3,0,0,0,1,0,0,0,0,0,9,0,0,0,0};
运行结果,发现,嗯,怎么肥四??怎么结果和原来的一样内???😵
又检查了一遍思路,感觉 莫得问题啊。。。
实在不行了,我去问了朋友,啊,找到原因了~~o( ̄▽ ̄)ブ
看完原因第一想法,我把输出语句放出去应该就可以了把。。
如下图代码。
else {
last=i-1; //元素不是0的时候执行else语句,此时的i为连续零的下一个非零元素的索引
count=0;//清零,重新累加
}
if(count>0&&count<5) {
System.out.println("非法序列:从索引 "+(last-count+1)+" 到 "+last+" 有 "+count+" 个0");
} //连续零的第一个零的索引 = 最后一个零的索引 - (count-1)
结果与我想像的有点不一样。。
改了好久,试了好多次,发现原来是我算法的问题。
因为我算法的思路就是,当他遍历到不是 0 的时候,利用连续零后的第一个非零元素取得的 连续零的最后一个零的索引,
如果在后面加一个非零元素,
int [] x={0,0,3,4,5,0,3,0,0,0,1,0,0,0,0,0,9,0,0,0,0,9};
运行结果:
那我这个算法就不是很灵活,就有限制。
分享一下另一个成功的代码,它主要是利用连续零的第一个元素来取值的
public class Test{
public static void main(String[] args) {
int [] x={0,0,3,4,0,0,0,0,3,0,0,0,1,0,0,0,0};
for(int i=0;i<x.length;i++) {
if(x[i]!=0) {
continue;
}
int count=0; //连续的0的个数
int begin=i; //0开始的索引位置
//取连续为0的序列
while(x[i]==0) {
i++;
count++;
if(i==x.length) {
break;
}
}
if(count<5) {
System.out.println("非法序列:从索引 "+begin+" 到 "+(begin+count-1)+" 有 "+count+" 个0");
}
}
}
}
这样一看,感觉我之前那个应该也可以,只不过我语句的位置写错了,照上面的代码模板走一遍也可以。
通过本例代码,证明 测试边界值是非常有必要的!!!
这个问题要好好注意一下了。
8. 未完待续
java学习ing.jpg 😊o( ̄▽ ̄)ブ
有其他见解,评论区留言或者私信,一起讨论,纠正。
关注我,努力鸭~和我一起学习鸭~
另外,转载文章请记得附上原文链接哦