基础算法练习43道(详细讲解版,随时更新)-程序员宅基地

技术标签: 算法  java  C语言  c语言  

目录:

  1:计算阶乘

  2:统计字符个数(java、c 代码编写)

  3:if else语句从小到大排序3个数

  4:第三方变量从小到大排序3个数

  5:利用三目运算符从小到大排序3个数

  6:利用嵌套三目运算符从小到大排序3个数

  7:判断是否为闰年

  8:输入某年某月某日,判断这一天是这一年的第几天?

  9:利用switch来判断某一天是这一年的第几天(体验switch的妙用)

  10:输出9*9口诀。

  11:输入二维数组,并将其转置、输出操作

  12:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和

  13:给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字

  14:判断一个五位数是否是回文

  15:求三行三列二维数组对角线之和

  16:数组逆序输出

  17:取一个整数a从右端开始的4~7位。

  18:求0—7所能组成的奇数个数。

  19:输入一段字符,统计元音字母

  20:连接字符串

  21:利用递归,一球从h米高度自由落下,每次落地后反跳回原高度的一半; 再落下,求它在 第n次落地时,共经过多少米?第n次反弹多高?

  22:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?

  23:一个整数(10000以内),它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?

  24:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单

  25:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。

  26:猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。

  27:利用递归,输出数组中十个数中的最大值

  28:利用递归,求起始下标到末尾下标元素之和

  29:利用递归,求最大公约数(辗转相除法!)

  30:利用递归,计算斐波那契数列

  31:输入一个字符串,将首字母大写,其余字母小写(拓展:java常用字符串方法总结!!)

  32:统计长字符串中小字符串出现的次数

  33:水仙花数

  34:完数

  35:鞍点

  36:计算字符串中子串出现的次数

  37:某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下: 每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。

  38:读取7个数(1—50)的整数值,每读取一个值,程序打印出该值个数的 *。

  39:判断一个素数能被几个9整除。

  40:809*??=800*??+9*?? 其中??代表的两位数, 809*??为四位数,8*??的结果为两位数,9*??的结果为3位数。求??代表的两位数,及809*??后的结果。

41:写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度。

42:利用指针数组,实现字符串排序(c语言)

43:设计一个方法,可以获取任意范围内的随机数(附带Math类常用方法总结、java Random类)


注:
(1)本算法是基础算法,既然是基础算法,既可以用java语言编写,也可以用C等其它语言编写,所以我建议想学C语言的同学,可以去看我的博客 《C语言各章节干货汇总、考研知识点归纳》,之后也可以用C语言编写,想用C练习的小伙伴,只需要将方法体中输入输出语句改为C语言输入输出语句即可,另外有些改不了的我会给出C算法的代码。

(2)在做这些算法的时候,希望大家一定要先自己想,想不通了之后再来看,这样会受益匪浅,而且有助大家编程思维的形成!!!

NEXTPART LET’S BEGIN !


  • 1:计算阶乘

第一个是计算阶乘的算法:

首先我们想一下,什么是阶乘,计算3的阶乘:3 * 2 * 1 , 计算5的阶乘5 * 4 * 3 * 2 * 1,相信这个概念大家都能理解,那么该如何实现?(先自己想一下)
1)首先大家会发现规律,不管计算记的阶乘,就是自己乘以自减的一个数或者从1开始不断自增,之后继续自减或自增,有没有发现,这就形成了一个循环。
2)循环内部如何写呢?既然每次都要乘以自减的一个数,那是不是找一个变量 A 存起来,然后循环变量不断自减或者自增,再与A相乘即可。

public static void factorial(){
	
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入计算几的阶乘:");
	int temp = 1;
	int num = sc.nextInt();
	if(num == 1)
	{
		System.out.println("阶乘为:1");
	}
	else
	{
		for(int i = 1 ; i <= num ; i++)
			temp = temp * i; 
		System.out.println("阶乘结果为:"+temp);
	}
	sc.close();
}
  • 2:统计字符个数(java、c 代码编写)

这是一个 从键盘输入一行字符串(以换行符结束),要求分别统计里面英文字符的总个数和数字的总个数,并分别输出 的算法

本算法思想主要讲一下C语言编程思想,而java则有对应的统计工具类。
1)我们都知道C语言对于字符的存储会转换成对应ASCII值以整数形式存储。所以统计字符就转换为他们是否符合对应的字符范围。
2)数字是0~9,在C中字符用单引号扩出,所以 ‘ 0 ’ 即代表字符0 ,‘ 9 ’ 即代表字符9
3)英文字母同理,统计‘ a ’ ~ ’ z ’ 和 ’ A ‘ ~ ’ Z ‘ 的(看题目要求,有的题目会要求统计大小写)
4)空格 ’ ‘ 这么表示,剩下的就是其它字符直接归纳到else里面。
5)java编写的第二个代码中,java提供测字符串长度方法string.length() 【注意和数组的区分,数组不加小括号】
6)charAt(int x)方法是返回指定位置的字符。

对于java工具类Character类,详见:Java Character类

// java编写

public static void statistical(){
	Scanner sc = new Scanner(System.in);
	int digit = 0 , space = 0 , letter = 0 , other = 0;
	System.out.println("请输入一行字符串");
	String string = sc.nextLine();
	char [] arr = string.toCharArray();
	for(int i = 0 ; i < arr.length ; i++)
	{
		if(Character.isDigit(arr[i]))
			++digit;
		else if (Character.isLetter(arr[i]))
			++letter;
		else if(Character.isSpace(arr[i]))
			++space;
		else
			++other;
	}
	System.out.println("数字有"+digit+"个!");
	System.out.println("空格有"+space+"个!");
	System.out.println("字母有"+letter+"个!");
	System.out.println("其他字符有"+other+"个!");
	sc.close();
}		

// JAVA编写

public static void statistic(){
	Scanner sc = new Scanner(System.in);
	int digit = 0 , space = 0 , smallLetter = 0 , bigLetter = 0 ,other = 0;
	System.out.println("请输入一行字符串");
	String string = sc.nextLine();
	for(int i = 0 ;  i < string.length() ; i++)
	{
		char ch = string.charAt(i);
		if( ch >= '0' && ch <= '9' ) ++digit;
		else if( ch >= 'a' && ch <= 'z') ++smallLetter;
		else if( ch >= 'A' && ch <= 'Z' ) ++bigLetter;
		else if( ch == ' ') ++space;
		else ++other;
	}
	System.out.println("数字:"+digit+"\t小写字母"+smallLetter+"\t大写字母"+bigLetter+"\t空格:"+space+"\t其它:"+other);
}

// C语言编写

int main(){
	char arr[100];
	gets(arr);
	count_char(arr); 
} 
void count_char(char arr[])
{
	int digit = 0 , space = 0 , others = 0 , letter = 0 ;
	for(int i = 0 ; arr[i] != '\0' ; i++)
	{
		if( arr[i] > '0' && arr[i] < '9' )  ++digit; 
		else if( arr[i] >= 'a' && arr[i] <= 'z' ||  arr[i] >= 'A' && arr[i] <= 'Z' )  ++letter;
		else if( arr[i] == ' ')  ++space;
		else  ++others;
	}
	printf("数字:%d\t空格:%d\t字母:%d\t其他字符:%d\n",digit,space,letter,others);
}
  • 3:if else语句从小到大排序3个数

这是一个输入三个整数x,y,z,利用if else语句将三个数由小到大输出的算法。

1)这个要熟悉if else 语句。首先要注意的是if 总是与最近的一个else进行匹配,为了防止混淆,建议加上大括号,这样不易混淆。
2)这个要搞清楚的是究竟谁大于谁,A > C , A > B 之后还要记住B与C还要进行比较。

public static void sortSL_way1(){
	Scanner sc = new Scanner(System.in);
	int num = 0 , num1 = 0 , num2 = 0;
	int maxNum = 0,maxNum1 = 0;
	System.out.println("请输入三个数:");
	num = sc.nextInt();
	num1 = sc.nextInt();
	num2 = sc.nextInt();
	if(num > num1)
	{
		if( num > num2)
		{
			if(num1 > num2)
			{
				System.out.println("从小到大排序为:"+num2+"\t"+num1+"\t"+num);
			}
			else
			{
				System.out.println("从小到大排序为:"+num1+"\t"+num2+"\t"+num);
			}
		}
		else
		{
			System.out.println("从小到大排序为:"+num1+"\t"+num+"\t"+num2);
		}
	}
	else{
		if(num < num2)
		{
			if(num1 < num2)
			{
				System.out.println("从小到大排序为:"+num+"\t"+num1+"\t"+num2);
			}
			else
			{
				System.out.println("从小到大排序为:"+num+"\t"+num2+"\t"+num1);
			}
		}
		else
		{	
			System.out.println("从小到大排序为:"+num2+"\t"+num+"\t"+num1);
		}
	}
	sc.close();
}
  • 4:第三方变量从小到大排序3个数

这是一个输入三个整数x,y,z,利用第三方变量把这三个数由小到大输出的算法

1)这个算法值得注意的一个点是利用第三方变量,比题本身更有意义的是为什么要用第三方变量:
当我们要交换两个数的时候,例如交换变量A的值和B的值,如果直接写成 A = B ; B = A ; 这个样子的话,最后变量A与B 存储的数值都是B所存储的数值 。
2)所以我们运用第三方变量temp(名字随便取)来作为一个中间值,temp = A ; A = B ; B = temp ; 这样的话,先将A的值放进 temp 中存储,之后将变量 B 的值放在变量 A 中,最后将temp中所存储的A的值赋值给B , 这样就完成了交换。

public static void sortSL_way2(){
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入三个数!");
	int num = sc.nextInt();
	int num1 = sc.nextInt();
	int num2 = sc.nextInt();
	int temp = 0;
	if( num > num1 )
	{
		temp = num1 ; 
		num1 = num;
		num = temp;
	}
	if( num > num2)
	{
		temp = num2;
		num2 = num;
		num = temp;
	}
	if( num1 > num2)
	{
		temp = num1;
		num1 = num2;
		num2 = temp;
	}
	System.out.println("从小到大排序为:"+num+","+num1+","+num2);
	
}
  • 5:利用三目运算符从小到大排序3个数

这是一个利用三目运算符从小到大排序3个数的算法。

1)三目运算符格式:A > B ? A : B ;
2)如果A>B则返回A的值,否则返回B的值。
3)这里的A 与 B 可以是一个条件表达式,且右结合。

public static void sortSL_way3(){
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入三个数!");
	int num = sc.nextInt();
	int num1 = sc.nextInt();
	int num2 = sc.nextInt();
	int temp1 = 0,temp2 = 0 , temp3 = 0;
	temp1 = num > num1 ? num : num1 ;
	temp1 = temp1 > num2 ? temp1 : num2;
	temp2 = num < num1 ? num : num1 ;
	temp2 = temp2 > num2 ? temp2 : num2;
	temp3 = num < num1 ? num : num1;
	temp3 = temp3 < num2 ? temp3 : num2;
	System.out.println("从小到大排序为:"+temp3+","+temp2+","+temp1);
	
}
  • 6:利用嵌套三目运算符从小到大排序3个数

这是一个利用嵌套三目运算符从小到大排序3个数的算法!

1)本代码中max是最大的数,next_Max是中间的数,min是最小的数。
2)首先要取出最大的数 max,而( num1 > num2 ? num1 : num2 ) 这个表达式返回的是num1和num2中大的数,再与num比较则返回三个数中最大的数了。
3)之后取出中间大的数next_Max,而 ( num1 > num2 ? num1 : num2 ) 这个表达式返回的是num1和num2中大的数,再与num相比返回小的那个数即是next_Max;
4)最后取最小的书min,而( num1 < num2 ? num1 : num2 ) 这个表达式返回的是num1和num2中最小的数,再与num相比返回小的那个数即是min。

public static void sortSL_way4(){
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入三个数!");
	int num = sc.nextInt();
	int num1 = sc.nextInt();
	int num2 = sc.nextInt();
	int max = 0 , next_Max = 0 , min = 0;
	max = num > ( num1 > num2 ? num1 : num2 ) ? num :( num1 > num2 ? num1 : num2 );
	next_Max = num < ( num1 > num2 ? num1 : num2 ) ? num : ( num1 > num2 ? num1 : num2 );
	min = num < ( num1 < num2 ? num1 : num2 ) ? num : ( num1 < num2 ? num1 : num2 );
	System.out.println("从小到大排序为:"+min+","+next_Max+","+max);
}
  • 7:判断是否为闰年

这是一个判断是否为闰年的算法

1)首先要理解什么是闰年:能被4整除,但不能被100整除的年份即为闰年,或者能被400整除的也为闰年
2)这里要提醒大家:A能被B整除,A是被除数,B是除数,别搞蒙了!!

public static boolean isLeap(int Year)
{
	if( ( Year % 100 != 0 ) && ( Year % 4 == 0 ) || ( Year % 400 == 0 ) )
	{
		System.out.println("是闰年!");
		return true;
	}
	else
	{
		System.out.println("不是闰年");
		return false;
	}
}
  • 8:输入某年某月某日,判断这一天是这一年的第几天?

这是一个输入年月日,判断这一天是这一年第几天的算法。

1)注意本算法中判断闰年直接调用了第5题的算法。
2)计算某年某月某日,需要注意的是判断平年还是闰年。原因就是2月份会差一天,所以在计算天数的时候要对月份是否大于2月份和是否是闰年进行一个判断,进而确定是否要加相差的那一天。
3)本算法是利用数组,将每一个月份的天数存在数组中,之后利用for循环进行相加。

public static void calc_day(){
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入年月日,用空格隔开!");
	int year = sc.nextInt();
	int month = sc.nextInt();
	int day = sc.nextInt();
	int sum = 0;
	int[] arr = {31,28,31,30,31,30,31,31,30,31,30,31};
	for(int i = 0 ; i < month - 1 ; i++)
	{
		sum += arr[i];
	}
	sum += day;
	if(isLeap(year) && month > 2)
		sum += 1;
	System.out.println(year+"年"+month+"月"+day+"日,是这一年的第"+sum+"天。");
	sc.close();
}
  • 9:利用switch来判断某一天是这一年的第几天(体验switch的妙用)

这是一个利用switch来判断某一天是这一年的第几天的算法。

1)注意本算法中判断闰年直接调用了第5题的算法。
2)switch的妙用:平时我们使用switch都会在每一个case语句最后加上break;这样的目的是防止继续向下执行其它case语句。而在本体中,非常巧妙的利用了这个特点,当输入月份之后,由于没有break,所以会自动向下进行,也就把之前每个月的每一天加到了一块。
3)注意,我们常见的语句中还有一个continue; 这个语句的作用是跳过本次循环,但是continue只能在循环中使用,并不能单独使用在switch中!!!!

public static void calc_day1(){
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入年月日,用空格隔开!");
	int year = sc.nextInt();
	int month = sc.nextInt();
	int day = sc.nextInt();
	int sum = day;
	switch(month - 1)
	{
		case 12 : sum += 31;
		case 11 : sum += 30;
		case 10 : sum += 31;
		case 9 : sum += 30;
		case 8 : sum += 31;
		case 7 : sum += 31;
		case 6 : sum += 30;
		case 5 : sum += 31;
		case 4 : sum += 30;
		case 3 : sum += 31;
		case 2 : sum += 28;
		case 1 : sum += 31;
	}
	if(isLeap(year) && month > 2)
		sum += 1;
	System.out.println(year+"年"+month+"月"+day+"日,是这一年的第"+sum+"天。");
	sc.close();
}
  • 10:输出9*9口诀

这是一个输出9*9口诀的算法。

我们都在文具盒上见过9*9口诀的算法,类似一个下三角形,很容易联想到二维数组,这样的话只要第二个循环条件判断的时候小于第一个循环变量的值,这样的话就是下三角了。
之后两个循环变量相乘所得即为结果。

public static void print_multiTable(){
	
	for(int i = 1 ; i <= 9 ; i++)
	{
		for(int j = 1 ; j <= i ; j++)
		{
			System.out.print(i+"*"+j+"="+i*j+"\t");
		}
		System.out.println();
	}
}
  • 11:输入二维数组,并进行转置、输出操作

这是一个将输入的二维数组转置并输出的算法。

这里需要注意一个问题,就是转置操作的第二个for循环中,j 的取值范围要小于 i 。举个例子:当i = 0 , j = 2 的时候,arr[0][2] 与 arr[2][0] 的值进行了调换,但是如果j 的范围不小于i 的话,当 i = 2 , j = 0的时候,二者的值会再次调换,导致结果未发生转置变化。

public static void inversion(){
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入3*3的二维数组!");
	int[][] arr = new int[3][3];
	int temp = 0;
	//输入
	for(int i = 0 ; i < 3 ; i++)
	{
		for(int j = 0 ; j < 3 ; j++)
		{
			arr[i][j] = sc.nextInt();
		}
	}
	//转置操作
	for(int i = 0 ; i < arr.length ; i++)
	{
		for(int j = 0 ; j < i ; j++)
		{
			temp = arr[i][j];
			arr[i][j] = arr[j][i];
			arr[j][i] = temp ; 
		}
	
	}
	//输出
	for(int i = 0 ; i < arr.length ; i++)
	{
		for(int j = 0 ; j < arr[i].length ; j++)
		{
			System.out.print(arr[i][j]+"\t");
			if(j == 2)
				System.out.println();
		}
	}
}

//C 指针转置:

  #include<stdio.h>
  #include<stdlib.h>
  #include<string.h>
  
  int traverse(int(*p)[3]){  //指向一维数组的指针
    int flag = 0;
    for(int i = 0 ; i < 3 ; i++)
    {
      for(int j = i ; j < 3 ; j++)
      {
        flag = *(*(p + i) + j);
        *(*(p + i) + j) = *(*(p + j) + i);
        *(*(p + j) + i) = flag;
      }
    }
    
    return 0;
  }

  int main(){
    int arr[3][3];
    int *p , temp = 0;
    for(p = arr[0]; p < arr[0] + 9 ; ++p)
    {
      scanf("%d",p);
    }
    traverse(arr);
    for(p = arr[0]; p < arr[0] + 9 ; ++p)
    {
      ++temp;
      printf("%d\t",*p);
      if(temp % 3 == 0)
        printf("\n"); 
    }
    return 1;
  }

//C 二维数组转置:

  #include<stdio.h>
  #include<stdlib.h>
  #include<string.h>

  int main(){
    int arr[3][3] , temp = 0 , flag = 0;
    for(int i = 0 ; i < 3 ; i++)
    {
      for(int j = 0; j < 3 ; j++)
      {
        scanf("%d",&arr[i][j]);
      }
    }
    for(int i = 0 ; i < 3 ; i++)
    {
      for(int j = i ; j < 3 ; j++)
      {
        flag = arr[i][j];
        arr[i][j] = arr[j][i];
        arr[j][i] = flag;
      }
    }
    for(int i = 0 ; i < 3 ; i++)
    {
      for(int j = 0; j < 3 ; j++)
      {
        ++temp;
        printf("%d",arr[i][j]);
        if(temp % 3 == 0)
          printf("\n");
      }
    }
    return 1;
  }
  • 12:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和

这是一个求特定数列和的算法。

1)通常这种算法都存在着一定的规律,本题中首先挥发先一个问题第二项起,前一项的分子和分母的和是第二项的分子。
2)每一项的分子又是下一项的分母。

 public static void calc_sum(){
	 double up = 2;
	 double down = 1;
	 double fraction = up / down;
	 double temp = 0.0;
	 double sum = 0.0;
	 for(int i = 1 ; i <= 20 ; i++)
	 {
		 sum += fraction;
		 temp = up + down;
		 down = up;
		 up = temp;
		 fraction = up / down;
	 }
	 System.out.println("前20项和为:"+sum);
 }
  • 13:给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字

这是一个拆分整数的算法。

(1)我们都知道通过求余运算,我们可以把最后一位 提取出来,对于整型变量,通过除法则可以将个位去掉。
(2)再将通过求余取出的整数放入数组即可,因为我们是从个位开始取每一位数,所以数组直接输出即为倒序。

 public static void print_number(){
	 Scanner sc = new Scanner(System.in);
	 System.out.println("请输入一个不多于5位的正整数:");
	 int Num = sc.nextInt();
	 int[] arr = new int[5];
	 int count = 0 , i = 0;
	 while(Num != 0){
		arr[i] = Num % 10;
		Num /= 10;
		++count;
		++i;
	}
	 System.out.println("输入的是"+count+"位数,倒序为:");
	 for(int j = 0 ; j < count ; j++)
	 {
		 System.out.print(arr[j]+" ");
	 }
	 sc.close();
 }
  • 14:判断一个五位数是否是回文

(1)所谓的回文:就是个位和万位,十位和百位的数相同才叫回文,例如12521;
(2)参照第13题,我们可以将五位数用相同的方法放进数组里面,直接进行对个位和万位,十位和百位进行比较。

public static void back_Number(){
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入一个五位数!");
	int[] arr = new int[5];
	int Num = sc.nextInt();
	int i = 0;
	while(Num != 0){
		arr[i] = Num % 10;
		Num /= 10;
		++i;
	}
	if(arr[0] == arr[4] && arr[1] == arr[3])
	{
		System.out.println("是回文!");
	}
	else
	{
		System.out.println("不是回文!");
	}
	sc.close();
}
  • 15:求三行三列二维数组对角线之和

这是一个求三行三列二维数组对角线之和的算法。

比较简单的一道题,双重for循环进行数组初始化,由于是求二维数组对角线之和,即行数等于列数,所以设置一个循环求和即可。

public static void print_duijiaoxian(){
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入9个数:");
	int[][] arr = new int[3][3];
	int sum = 0;
	for(int i = 0 ; i < 3 ; i++)
	{
		for(int j = 0 ; j < 3 ; j++)
		{
			arr[i][j] = sc.nextInt();
		}
	}
	for(int i = 0 ; i < 3 ; i++)
			sum += arr[i][i];
	System.out.println("对角线和为:"+sum);
	sc.close();
}
  • 16:数组逆序输出

这是一个逆序输出数组的算法。

注意两点:
(1)两个数交换一定要借助第三方变量才可以
(2)for循环中,可以初始化多个循环变量。

public static void reverse(){
	int temp = 0;
	int[] arr = {1,2,3,4,5,6,7,8,9};
	for(int i = 0 , j = arr.length - 1 ; i < arr.length/2 ; i++ , j--)
	{
		temp = arr[j];
		arr[j] = arr[i];
		arr[i] = temp;
	}
	for(int k = 0 ; k < arr.length ; k++)
		System.out.println(arr[k]);
}
  • 17:取一个整数a从右端开始的4~7位。

这是一个取一个整数a从右端开始的4~7位的算法,当然位数可以灵活变化。

要注意两个java方法:
Long类的toString方法,可将数字转化为String类型。
toCharArray()方法:将字符串转换为字符数组。

public static void gain_Num(){
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入一个整数:");
	long num = sc.nextLong();
	String str = Long.toString(num);//把数字转化为String类型
	char[] ch = str.toCharArray();//把String类型的字符,转化为char类型,每一个数字赋值到字符型数组中
	int n = ch.length;
	System.out.println("从右端开始的4~7位为:"+ch[n-7]+"\t"+ch[n-6]+"\t"+ch[n-5]+"\t"+ch[n-4]);
	sc.close();
}
  • 18:求0—7所能组成的奇数个数

这是一个求0—7所能组成的奇数个数的算法。

(1)首先我们想到:当末尾是奇数的时候,不管几位数,最后肯定是奇数,多位数要注意首位不能为0,中间位都可以。
(2)当1位数的时候a1:奇数只有四种情况:1、3、5、7
(3)当2位数的时候a2:奇数情况有:47 种(个位4种,十位可取1~7。)
(4)当3位数的时候a3:奇数情况有:4
87种(个位4种,十位可取0~7 ,百位1 ~ 7)
(5) 。。。
(6)当8位数的时候a8:奇数情况有:4
8888887种情况(个位4种,十位可取0~7 ,百位0 ~ 7,…… ,千万位1 ~7)

	void count_odd()
	{
		int count_num = 4 , sum = 4 ;
		for(int i = 1 ; i <= 8 ; i++)
		{
			if(i == 1)
			{
				printf("有%d位数时,组成奇数个数为:%d\n",i,count_num);
			}
			else if(i == 2)
			{
				count_num *= 7;
				sum += count_num;
				printf("有%d位数时,组成奇数个数为:%d\n",i,count_num);
			}
			else
			{
				count_num *= 8;
				sum += count_num;
				printf("有%d位数时,组成奇数个数为:%d\n",i,count_num);
			}
		} 
		printf("总数为:%d\n",sum);
	}
  • 19:输入一段字符,统计元音字母

这是一个统计元音字符的算法

(1)本题中java短发用了17题所介绍的toCharArray()方法,将输入的字符串转化成字符存到数组arr1[]中,并利用数组arr2[]来存储元音字母。
(2)C语言中需要在main函数中创建两个数组,作为实参传入,传入的形式可以是指针,也可以是数组名,详见博客《C语言各章节干货汇总、考研知识点归纳》。

// java(其实这里的输入与输出也可以单独封装起来)

public static void vowel()
{
	char [] arr1 = new char[100];
	char [] arr2 = new char[100];
	Scanner sc = new Scanner(System.in);
	String str = sc.nextLine();
	arr1 = str.toCharArray();
	for(int i = 0 , j = 0; i < arr1.length ; i++)
	{
			if(arr1[i] == 'a' ||arr1[i] == 'e' ||arr1[i] == 'i' || arr1[i] == 'o' ||arr1[i] == 'u')
			{
				arr2[j] = arr1[i];
				++j; 
			}	
	}
	System.out.println("元音字符为:");
	for(int i = 0 ; arr2[i] != '\0'; i++)
	{
		System.out.println(arr2[i]);
	}
	
}

//C语言

void vowel(char arr1[] , char arr2[])
{
	for(int i = 0 , j = 0; i < strlen(arr1) ; i++)
	{
		if(arr1[i] == 'a' ||arr1[i] == 'e' ||arr1[i] == 'i' || arr1[i] == 'o' ||arr1[i] == 'u')
		{
			arr2[j] = arr1[i];
			++j; 
		}	
	}
}
  • 20:连接字符串

这是一个链接字符串的算法。

(1)在C语言中,有字符串连接函数------strcat(),可直接连接两个字符串,这里给出实现函数。
(2)这里要注意的是:因为字符串最后是放在arr1数组中的,所以N代表arr1数组的长度,当数组arr1[] 与 arr2[] 函数所存字符串长度加在一块大于arr1数组的长度N时候,此时数组arr1[]是放不下的。
(3)JAVA法一中用到 java字符串连接方法concat();

// C语言

void connect(char arr1[] , char arr2[],int N)
{
	int len1 , len2;
	len1 = strlen(arr1);
	len2 = strlen(arr2);
	if(N < len1 + len2) printf("error!");
	else
	{
		for(int i = len1 , j = 0; i <= len1 + len2 ; i++ , j++)
		{
			arr1[i] = arr2[j]; 
		}
	}
}

//JAVA法一

	public static void connect_str(){
		String str1 = "Hello";
		String str2 = "World";
		String str = str1.concat(str2);
		System.out.println(str);
	}

// JAVA法二

public static void connect(){
	char [] arr1 = new char[100];
	char [] arr2 = new char[100];
	int arr1_length = 100;
	Scanner sc = new Scanner(System.in);
	System.out.println("输入第一个字符串:\n");
	String str1 = sc.nextLine();
	arr1 = str1.toCharArray();
	System.out.println("输入第二个字符串:\n");
	String str2 = sc.nextLine();
	arr2 = str2.toCharArray();
	if( arr1_length < arr1.length + arr2.length) System.out.println("存储空间不足!");
	else
	{
		for(int i = arr1.length , j = 0; i <= arr1.length + arr2.length ; i++ , j++)
		{
			arr1[i] = arr2[j]; 
		}
	}
}
  • 21:利用递归,一球从h米高度自由落下,每次落地后反跳回原高度的一半; 再落下,求它在 第n次落地时,共经过多少米?第n次反弹多高?

(1)首先我们来理解一下这个过程。

第一次经过路程:h
第二次经过路程:h+h/22
第三次经过路程:h+h/2
2+(h/2/2)2
···
第n次经过路程:h+h/2
2+(h/2的n-1次方)*2

(2)其实这个过程我们可以看出,每次加的都是 弹起高度/2 再次落地,所以还要乘2。

public static void calc_altitude()
{
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入自由落下的高度:");
	float altitude = sc.nextFloat();
	System.out.println("请输入所求第几次落地:");
	int  Num = sc.nextInt();
	float sum  = 0, high = altitude;
	sum += high;
	for(int i = 2; i <= Num; i++){
		high =high / 2;
		sum += high*2;
	}
	System.out.println("从"+altitude+"米落下,经过"+Num+"次落地,共经过"+sum+"米,第"+Num+"次反弹"+high+"米。");
	sc.close();
	
}
  • 22:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?

这是一个求组成互不相同且无重复数字的三位数的算法。

(1)首先,题目要求无重复数字,也就是当百位是1,十位和各位可以是除了1以外的2,3,4中任意一个数字。所以我们可想到利用循环来表示各位数字。
(2)之后判断语句条件表示为:i != j && j != k && i != k 表示无重复。
(3)最后设置变量count计算组成三位数字的个数。

	public static void three_figures(){
		int count = 0;
		for(int i = 1 ; i <= 4 ; i++)
		{
			for(int j = 1 ; j <= 4 ; j++)
			{
				for(int k = 1 ; k <= 4 ; k++)
				{
					if(i != j && j != k && i != k)
					{
						++count;
						System.out.print(i);
						System.out.print(j);
						System.out.print(k);
						System.out.println();
					}
				}
			}
		}
		System.out.println("总共有"+count+"个三位数!");
	}
  • 23:一个整数(10000以内),它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?

(1)这里要注意的是,java中Math的父类是Object类,故不用导入任何包。如果在C语言中输入则要导入头文件:#include<math.h>
(2)首先要了解完全平方数:完全平方指用一个整数乘以自己例如11,22,3*3等,依此类推。若一个数能表示成某个整数的平方的形式,则称这个数为完全平方数。
(3)依据题意:分别将 i + 100 与 i + 268 开方,并分别赋值给num1 , num2 ,如果二者的平方分别等于i + 100 ,i + 268,即符合完全平方数的题意。

	public static void test_Perfect_square()
	{
		 for (int i = 0; i <10000;i++) 
		 {
			 	int num1 = (int)Math.sqrt(i+100);//开方,值已固定了
 				int num2=(int)Math.sqrt(i+268);
 				if ( (num1*num1==(i+100))&&(num2*num2==(i+268))) 
 				{
 					System.out.println(i+"\t");
 				}
		 }
	}
  • 24:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单

(1)本题和22题有类似的地方,可以体会一下,为什么两题都用了三重循环。
(2)本题中,在不管约束条件的情况下,a有可能和x比,有可能和y比,有可能和z比。同理,b和c也是同样的,故我们用三重循环,这样就能把每种情况覆盖上。
(3)因为比赛是1v1,而且是甲队对阵乙队,故 不可能有i , j , k 相等的情况,如果相等岂不是a可以对阵b,又可以对阵c,显然不可能。
(4)最后分别让a 对阵arr[i],a 对阵arr[j],a 对阵arr[k] ,而约束条件a != ‘x’ && c != ‘x’ && c != ‘z’ 成立即为对阵名单。

 public static void match_menu(){
	 char a = 0 ,b = 0 , c = 0;
	 char[] arr = {'x','y','z'};
	 for(int i = 0 ; i < 3 ; i++)
	 {
		 for(int j = 0; j < 3 ; j++)
		 {
			 for(int k = 0; k < 3 ; k++)
			 {
				 if(i != j && i != k && j != k)
				 {
					 a = arr[i];
					 b = arr[j];
					 c = arr[k];
					 if( a != 'x' && c != 'x'  && c != 'z' )
					 {
						 System.out.println("a对阵"+arr[i]);
						 System.out.println("b对阵"+arr[j]);
						 System.out.println("c对阵"+arr[k]);
					 }
				 }
			 }
		 }
	 }
	 
 }
  • 25:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。

(1)类似这种题,其实很重要的一个解题技巧就是找规律。
(2)仔细观察,2+22+222+2222+22222,其实就是不断的 * 10 + a的一个过程。比如 a = 2,这样的话a * 10 + a就得到第二项 22 ,以此类推。

public static void add_Number()
{
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入a和n");
	int a = sc.nextInt();
	int n = sc.nextInt();
	int temp = a , sum = 0;
	while( n > 0 )
	{
		sum += temp;
		temp *= 10;
		temp += a;
		--n;
	}
	System.out.println("a+aa+... ="+sum);
}
  • 26:猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。

(1)本题要采取逆向思维来解题,从后往前推。

由题意可知如下:(x1为前一天桃子数,x2为第二天桃子数)

x2 = before / 2 - 1 ; 可推 x1 = ( x2 + 1 ) * 2;
x3 = x2 / 2 - 1; 可推 x2 = ( x3 + 1 ) * 2;
···
以此类推,可知:x前一天 = ( x 后一天 + 1) * 2 。

public static void count_peach(){
	int day = 9, behind = 1 , before = 0;
	while(day > 0){
		before = (behind+ 1) * 2;
		behind = before;
		--day;
	}
	System.out.println("第一天摘了:"+before);
}
  • 27:利用递归,输出数组中十个数中最大值

这是一个递归输出数组中最大值的算法。

(1)一个数组中存储十个数,我们用Left标记数组起始下标,而Right来标记数组末尾下标。
(2)我们来想一下递归出口,由于Right是数组末尾的下标,当Left == Right的时候,即为最后一个数,故递归出口的条件为:Left == Right。
(3)每次递归我们让左下标加一,这样的话,当左右下标相同时,代表比较结束,则返回左下标或右下标的值给b,比较a,b的值,不断返回a,b中的最大值,返回到最上层时则得结果。

public static int recursion_findMax(int[] arr , int Left , int Right)
{
	//递归方法
	int maxNum = 0;
	if(Left == Right)
	{
		return arr[Left];
	}
	else{
	 int a = arr[Left];
	 int b = recursion_findMax(arr,Left+1,Right);
	 if(a > b )
		 return a;
	 else
		 return b;
	}
}
  • 28:利用递归,求起始下标到末尾下标元素之和

这是一个利用递归求下标和的算法。

(1)与21题类似,求起始下标到末尾下标元素之和,只需让每一项和第一项相加,即为结果。
(2)来想一下递归出口,有了21题,你是不是会想到同样的道理,每次让起始下标+1的数与第一个数相加知道末尾下标,所以Left == Right 为递归出口的条件。

public static int calc_sum(int[] arr , int Left , int Right){
	
	if( Left == Right )
	{
		return arr[Left];
	}
	else
	{
		 return arr[Left]+calc_sum(arr,Left+1,Right);
	}
}
  • 29:利用递归,求最大公约数(辗转相除法!)

这是一个利用辗转相除求最大公约数的一个算法。

(1)首先来了解一下什么是辗转相除法。

比如说:求72与56的最大公约数,利用辗转相除法
a / b = C ······ d (a 除 b = c 余 d)
72 / 56 = 1 ······ 16 ( 1余 16 )
56 / 16 = 3 ······ 8 ( 3 余8 )
16 / 8 = 2 ······ 0
此时余数为0 , 所以8为最大公约数!
令被除数等于a,除数等于b ,余数等于c
那么此时发现辗转相除法每次均为b / c ,当 余数为0 , 则b为最大公约数。

public static int gcd(int a , int b){
	int remainder = a % b;
	if (remainder == 0)
	{
		return b;
	}
	else
	{
		return gcd(b,remainder);
	}
	
}
  • 30:利用递归,计算斐波那契数列

(1)斐波那契数列:斐波那契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*)
(2)简单来说就是第一项是1,第二项是1,从第三项开始每一项是前两项之和。
(3)故递归出口即为当 i为第0项和第1项的时候,分别返回 0 ,1 即可。

public static int fibonaci(int i){
	if( i == 0)
	{
		return 0;
	}
	if(i == 1)
	{
		return 1;
	}
	return (fibonaci(i - 1) + fibonaci(i));
}
  • 31:输入一个字符串,将首字母大写,其余字母小写

(1)献给大家介绍一下java字符串方法。(本题很简单,只是为了让大家知道这些方法)

1)string.subString( int startIndex , int endIndex ); //subString是截取字符串方法,从开始下标到结束下标,截取的字符串包含开始下标字符,不包括结束下标字符。
2)string.subString( int startIndex ); //从开始字符截取一直到字符串末尾。
3)string.toUpperCase(); //转换成大写字母 。
4)string.toLowerCase(); // 转换成小写字母。
5)str1.concat( str2 ); //连接字符串 str1 和 str 2。

(2)拓展:字符串的其他功能

string.replace( char old , char new ) ; // 替换字符
string.replace( String old , String new ) ; // 替换字符
string.trim(); //去除字符串两端空格。
string.compareTo( String str ); // 区分大小写进行比较
string.compareToIgnoreCase( String str ); //不区分大小写进行比较。

(3)拓展:String类的获取功能

int length();获取字符串长度。
char charAt ( int index ) :获取指定索引位置的字符
int indexOf( int ch ) :返回指定字符在此字符串中第一次出现处的索引。
int indexOf( int ch , int fromIndex ) :返回指定字符在此字符串中从指定位置后第一次出现处的索引。
int indexOf( String str , int fromIndex ) :返回指定字符串在此字符串中从指定位置后第一次出现处的索引。
String subString( int start ) : 从指定位置开始截取字符串,直到末尾。
String subString( int start , int end ) : 从指定位置开始到截止位置结束截取字符串。

// JAVA

public static void change_letter(){
	String str = "helloWorld";
	String str1 = str.substring(0, 1);
	String str2 = str.substring(1);
	String str3 = str1.toUpperCase();
	String str4 = str2.toLowerCase();
	String result = str3.concat(str4);
	System.out.println(result);
}

// JAVA 链式编程

public static void change_letter(){
	String result = str.substring(0, 1).toUpperCase().concat(str.substring(1).toLowerCase());
	System.out.println(result);
}
  • 32:统计长字符串中小字符串出现的次数

(1)定义一个统计变量,初始化为0;
(2)先获取一次指定字符串,利用31题所说的方法indexOf( String ) ,会返回第一次出现指定字符串的首部索引。

如果索引值是 -1 ,就说明不存在,返回统计变量。
如果索引值不是-1,就说明存在,统计变量++

(3)把刚才的索引+指定字符串的长度作为起始位置截取原始长字符串(利用31题所说的方法:string.subString( int start ) ; ),并把该字符串重新赋值给长字符串。
(4)回到(2)即可。

// JAVA

public static void main(String [] args)
{
		//长字符串
		String maxString = "woaijavawozhenaijavawozhendeaijavawoshizhendeaijavameijavawodoubuxing";
		//指定字符串
		String minString = "java";
		//传入getCount方法
		int count = Basic_arithmetic.getCount(maxString, minString); //Basic_arithmetic是我的工具类类名
		System.out.println("指定字符串“"+minString+"”出现了"+count+"次!");
}

public static int getCount(String maxString , String minString)
{
	int count = 0;
	int index = maxString.indexOf(minString);
	while( index != -1 )
	{
		++count;
		maxString = maxString.substring(index+minString.length());
		index = maxString.indexOf(minString);
	}
	return count;
}
  • 33:水仙花数

水仙花数:所谓“水仙花数”是指一个3位数,其各位数字立方和等于该数本身。

(1)首先,我们通过取余运算可将数字中的每一位取下来,进而进行立方操作
(2)由于每次进行的操作相同,我们用一个循环来进行。
(3)要注意:要设置一个变量将num的初始值存储下来,不然最后无法与立方和进行比较。

//C语言

void water_flower(int num){
	int temp = num , temp1 = 0 , sum = 0;
	for(int i = 0 ; i < 3 ; i++)
	{
		temp1 = num % 10;
		temp1 = temp1 * temp1 * temp1;
		sum += temp1;
		num /= 10;
	}
	if( temp == sum )
	{
		 printf("%d\n",temp);
	}
	
}
int main(){
	printf("水仙花数为:\n");
	for(int i = 100 ; i <= 10000 ; i++)
	{
		water_flower(i);
	}
} 
  • 34:完数

完数:一个数等于因子之和,这个数就称为 “ 完数 ” 。例如6 的因子:1,2,3 ,3个因子相加即为6。

(1)这里运用了一个重要的方法:取根号。大家可以记住,只要是求因子,都可以取根号,这样会节约时间,博客《判断一个数是否是素数,或者判断一定范围内的素数有哪些》也使用了相同的方法,大家做完这道题可以做一下这个判断素数这道题。
(2)这里为什么会取根号?举个例子:例如15这个数:根号15约等于3.87,因为15有个一因子是3,且3小于3.87,所以一定存在一个大于3.87且小于15的数乘以3等于15,即5。就是这样一个一一对应的关系,如果小于开根号的因数不存在,则大于开根号的因数一定不存在。

void  perfect_Num(int num){
	int Num = 0 , sum = 1 , temp = 0; 
	Num = sqrt(num);
	for(int i = 2 ; i <= Num ; i++)
	{
		if( num % i == 0)
		{
			sum += i ; 
			temp = num / i ;
			sum += temp;
		}
	}
	if( num == sum )
	{	
		printf("%d\n",num);
	}
}
 
int main(){
	printf("完数数为:\n");
	for(int i = 1 ; i <= 1000 ; i++)
	{
		perfect_Num(i);
	}
} 
  • 35:鞍点

鞍点:数组中行最大,列最小的元素

(1)首先我们要找出行最大值 row_Max,进而找到行最大值所在列的索引colu_Index
(2)固定colu_Index , 设置一个循环变量k,来遍历所在列每一个元素(除了本身),有一个比行最大值小,则违反列最小,反之,满足则为鞍点。

void saddle_point(int arr[row][colu]){
	int row_Max = 0 , row_Index = 0 , colu_Index = 0; //行最大索引,列最小索引,行最大的值
	bool flag = true;     //  标志是否为鞍点
	for(int i = 0 ; i < row ; i++)
	{
		for(int j = 0 ; j < colu ; j++)
		{
			if( row_Max < arr[i][j] )  //行最大进入循环
			{
				row_Max = arr[i][j];	 // 记录行最大值
				colu_Index = j;          //先将行最大看成列最小值,取其索引
				row_Index = i;           //行最大索引
			}
		} 
		
		for(int k = 0 ; k < row ; k++)  //取行最大值所在列,设置k遍历所在列每个元素
		{
			// 如果所在列有任何一个数小于行最大值,则不是列最小值,不是鞍点
			// 将flag 赋值为false;
			if( arr[k][colu_Index]  < arr[row_Index][colu_Index] && k != row_Index) 
			{
				flag = false;
			}

		}
		
		if(flag)
		{
			printf("鞍点坐标为为:(%d,%d),鞍点值为:%d\n",row_Index,colu_Index,row_Max);
		}
	} 
	
	
	
} 
 
int main(){
	int arr[row][colu];
	for(int i = 0 ; i < row ; i++)
	{
		for(int j = 0 ; j < colu ; j++)
		{
			scanf("%d",&arr[i][j]);
		}
	}
	
	for(int i = 0 ; i < row ; i++)
	{
		for(int j = 0 ; j < colu ; j++)
		{
			printf("%4d",arr[i][j]);
			if(j == colu - 1)
				printf("\n");
		}
	}
	saddle_point(arr);
	
} 
  • 36:计算字符串中子串出现的次数

(1)C语言在使用strlen()函数时,要导入库函数:#include<string.h>
(2)双循环,外循环控制遍历字符串,内循环控制遍历子串。
(3)要注意,当内循环已经遍历到len_Zi的时候,外循环变量 i 是不能继续自增的,如果自增,内循环结束,外循环会再一次自增,这样造成了字符串的字符丢失。
(4)如果字符串和子串每个元素相同,且内循环遍历到len_Zi - 1的时候,即成功遍历到一个子串,则 ++count_Zi ;

	void count_SonStr(){
		char arr[50] = {0} , arr1[10] = {0};
		int len_Fu = 0 , len_Zi = 0 , count_len = 0 , count_Zi = 0;
		printf("请输入字符串:\n");
		gets(arr);
		printf("请输入子串:\n");
		gets(arr1);
		len_Fu = strlen(arr);
		len_Zi = strlen(arr1);
		for(int i = 0 ; i < len_Fu ; i++)
		{
			count_len = 0;  //注意,每一次统计子字符串后,都要将计算子字符串长度变量清 0 。
			for( int j = 0 ; j < len_Zi ; j++ ) 
			{
				if( arr[i] == arr1[j] )  
				{
					if(j == len_Zi - 1)
					{
						count_len++;
						if( count_len == len_Zi ) 
						{
							++count_Zi; 
						}
					} 
					else
					{
						count_len++; 
						i++;
					}
				}
				else  // 如果 arr[ i ] == arr1[ j ]  ,直接结束内循环
				{
					break;	
				} 
			   
			}
		} 
		printf("子串出现次数:%d次!\n",count_Zi);
		
	}
  • 37:某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下: 每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。

(1)本题不难,取各位数字在前边的题型中已经多次遇到了。
(2)需要注意的是,本次我循环变量是自减的。原因:我们通过求余运算都是从个位开始取,如果是自增的话,数组中第一个值应该是就是个位。如果自减,数组中第一个值就是千位。所以以后遇到涉及逆序的题目可联想此方法。

	void send_data( int num ){
		int arr[4] = {0} ;
		int temp = 0 ;
		for(int i = 3 ; i >= 0; i--)
		{
			arr[i] = num % 10;
			arr[i] += 5;
			arr[i] %= 10;
			num /= 10;
		}
		temp = arr[0];
		arr[0] = arr[3];
		arr[3] = temp;
		temp = arr[1];
		arr[1] = arr[2];
		arr[2] = temp;
		
		for(int j = 0 ; j < 4 ; j++)
		{
			printf("%d\n",arr[j]);
		} 
		
	}
  • 38:读取7个数(1—50)的整数值,每读取一个值,程序打印出该值个数的 *。

本题需要注意的一个点是:对于输入值的判断,如果输入不符合范围,则先自减 i ,从新输入,这个思想在以后很多C语言的输入判断中使用。

	void print_star(){
		int num = 0;
		for(int i = 0 ; i < 7 ; i++)
		{
			printf("请输入一个整数(1-50):\n");
			scanf("%d",&num);	
			if( num > 50 || num <= 0 )
			{
				printf("输入错误,请重新输入!");
				--i;
				continue; 
			}
			for(int j = 0 ; j < num ; j++)
			{
				if(j == num - 1 )
				{
					printf("*");
					printf("\n");
				} 
				else
				{
					printf("*");
				}
			}	
		}	
	}
  • 39:判断一个素数能被几个9整除。

(1)判断素数的在博客《 判断一个数是否是素数,或者判断一定范围内的素数有哪些》有详细介绍,在此不多解释。
(2) 本题的一个亮点:通过指针增加了返回值,这也是C语言的一大特点,通常虚实结合都是值传递,但是指针传递的是地址,形参指向了与实参相同的一片地址空间,故增加了返回值。详见博客《C语言各章节干货汇总、考研知识点归纳》。

int mod_prime(int num , int* count){
	int temp = 9;
	while(count)
	{
		if(temp % num == 0) 
		{
			break;
		}
		else
		{
			++count;
			temp = temp * 10 + 9;
		}
	}
	return temp;
}
int main(){
	int num = 0 , count = 1;
	printf("请输入一个素数:\n");
	scanf("%d",&num);
	//此处判断是否为素数省略
	long result = mod_prime(num,&count); 
	printf("素数%d能整除%d个9组成的整数%d",num,count,result);
}
  • 40:809*??=800*??+9*?? 其中??代表的两位数, 809*??为四位数,8*??的结果为两位数,9*??的结果为3位数。求??代表的两位数,及809*??后的结果。
      void cala_num()
      {
      	int num = 809 ;
      	for(int i = 10 ; i < 100 ; i++ )
      	{
      		int temp = num * i;
      		if( temp >= 1000 && temp < 10000 && 8 * i < 100 && 9 * i >= 100  )
      		{
      			printf("%ld = 800 * %ld + 9 * %ld\n",temp , i , i);
      		}
      	}
      }
    
  • 41:写一个函数,利用指针求一个字符串的长度,在main函数中输入字符串,并输出其长度。

数组名做实参的时候,传到形参的是数组的首地址。

	int length(char *s)  
	{  
	    int i=0;
	    while(*s!='\0')
	    {  
	        i++;   
	        s++;  
	    }  
	    return i;  
	} 

	int main()
	{
	    int len;
	    char str[20];
	    printf("请输入字符串:\n");
	    scanf("%s",str);
	    len=length(str);
	    printf("字符串有 %d 个字符。",len);
	}
  • 42:利用指针数组,实现字符串排序

(1)输入字符串的时候,需要注意的是,要个元素开辟一个动态空间,不然运行会出现问题。
指针数组的每一个元素都是一个指针,指向字符串的第一个字符。

	//  排序(选择法,详细讲解请看博客《选择排序法、冒泡排序法、二分查找法(折半查找法)》)
	char* sort(char* name[] , int n ){
		char *temp;
		int k ;
		for(int i = 0 ; i < n - 1 ; i++)
		{
			k = i;
			for(int j = i + 1 ; j < n; j++ )
			{
				if(strcmp(name[k] , name[j]) > 0 ) k = j;
			}
			if( k != i)
			{
				temp = name[i];
				name[i] = name[k];
				name[k] = temp;
			}
		}
	} 

// 打印排序好的字符串字符串
	void print(char *name[] , int n)
	{
		for(int i = 0 ; i < n ; i++)
		{
			printf("%s\n",name[i]);
		}
	 } 

	int main()
	{
		int n = 3;
		char* name[n] ;
		for(int i = 0 ; i < n ; i++)
		{
			printf("请输入第%d个字符串:\n",i);
			name[i] = (char*)malloc(sizeof(char*));
			gets(name[i]);
		}
		sort(name,n);
		print(name,n); 

		return 0;
	}
  • 43:设计一个方法,可以获取任意范围内的随机数(附带Math类常用方法总结、java Random类)

Math类常用方法总结:

成员变量:
              public static final double PI ( 3.1415926 )
              public static final double E ( 2.7 )
成员方法:
              public static int abs ( int a ) : 绝对值
              public static double ceil (double a) :向上取整 (ceil天花板的意思,所以向上取整)
              public static double floor(double a):向下取整(floor地板的意思,所以向下取整)
              public static int max (int a , int b) :最大值
              public static int min( int a , int b ) : 最小值
              public static double pow ( double a , double b ) :a的b次幂
              public static double random() : 随机数
              public static int round round( float a ):四舍五入 (通过源代码可查看,四舍五入的实现其实是 + 1/2 之后取整 )
              public static double sqrt( double a ) :正平方根

获取任意范围的随机数:

首先我们回想获取1~100的随机数如何获取?

因为random()函数返回一个double类型的值,且都是0.ABC的形式 (可上机调试验证),这样的话如果我们将random()函数产生的随机数 * 100 , 就变成AB.CD的小数形式,再强制转换成int型之后,AB.CD就变成了AB形式,由于AB形式最大值是99,所以我们最后要 + 1 ,这样随机数就可以取值从1~100.
即:int number = ( int )( Math.random() * 100 ) + 1 ;

按照这个逻辑,修改上式得到:int number = ( int )( Math.random() * end ) + start ; 这样是不是就达到目的了呢?
答案是否定的。 假如取200~300之间的随机数,start就已经是200了,前边只能是100以内, 但是Math.random() * 300 的结果已经超过100,这样结果肯定是不对的。
所以:我们应该这样:int number = (int)(Math.random() * (end - start + 1) ) + start; 注意这里同上,300-200 = 100 , 但是取不到100 , 所以要+1 。

public static void main(String[] args)
{
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入开始数:");
	int start = sc.nextInt();
	System.out.println("请输入结束数:");
	int  end = sc.nextInt();
	for(int i = 0 ;i < 20 ; i++)
	{
		int num = Basic_arithmetic.getRandom(start, end);
		System.out.println("num:"+num);
	}	
}

public static int getRandom(int start , int end)
{
	int number = (int)(Math.random() * (end - start + 1) )+ start;
	return number;
}

介绍一下random类(接口):
构造方法:

public Random( ); //没有给种子,用的是默认的种子,是当前的毫秒值
public Random( long seed ); // 给定种子后,每次获取的随机数是相同的。

成员方法:

public int nextInt() : 返回的是 int 范围内的随机数。
public int nextInt( int n ) : 返回的是[ 0 , n )范围内的随机数

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_36657788/article/details/104409270

智能推荐

基于SpringBoot+Vue的小徐影城管理系统的设计与实现(源码+lw+部署文档+讲解等)-程序员宅基地

文章浏览阅读728次,点赞23次,收藏16次。博主介绍:全网粉丝15W+,CSDN特邀作者、211毕业、高级全栈开发程序员、大厂多年工作经验、码云/掘金/华为云/阿里云/InfoQ/StackOverflow/github等平台优质作者、专注于Java、小程序技术领域和毕业项目实战,以及程序定制化开发、全栈讲解、就业辅导精彩专栏 推荐订阅2023-2024年最值得选的微信小程序毕业设计选题大全:100个热门选题推荐2023-2024年最值得选的Java毕业设计选题大全:500个热门选题推荐Java精品实战案例《500套》

RDD编程实验_rdd编程中计算班级人数-程序员宅基地

文章浏览阅读5.7k次,点赞5次,收藏69次。RDD编程初级实践基于《Spark编程基础(Scala版)》目录RDD编程初级实践前言一、实验目的二、实验内容和要求三、实验步骤1.spark-shell交互式编程(1)该系总共有多少学生;(2)该系共开设了多少门课程;(3)Tom同学的总成绩平均分是多少;(4)求每名同学的选修的课程门数;(5)该系DataBase课程共有多少人选修;(6)各门课程的平均分是多少;(7)使用累加器计算共有多少人选了DataBase这门课。总结前言前面已经基于docker搭建好spark集群,集群为一台mast_rdd编程中计算班级人数

Log4j2AsyncAppender形式做异步日志_日志<async>-程序员宅基地

文章浏览阅读198次。Log4j2AsyncAppender形式做异步日志_日志

html特效文本框,各种html文本框input特效-程序员宅基地

文章浏览阅读291次。输入框景背景透明:鼠标划过输入框,输入框背景色变色:TYPE="text" SIZE="29"onmouseover="this.style.borderColor='black';this.style.backgroundColor='plum'"style="width: 106; height: 21"onmouseout="this.style.borderColor='black';th..._ios html input 特效

docker上启动部署好的ES方法_如何确认docker启动的es是否成功-程序员宅基地

文章浏览阅读2k次。1.查看镜像文件有哪些docker images2.启动3.查看是否成功在浏览器输入:http://192.168.150.101:9200 可以判断es是否部署成功http://192.168.150.101:5601 可以判断kibana是否部署成功**注意:**需要修改成自己虚拟机的ip地址查看ip地址的方法:ip addr或者ifconfig..._如何确认docker启动的es是否成功

ADVANCE.AI寿栋:面对高度竞争的国际市场 中国出海企业的机会在哪?_advance.ai出海遇到的问题-程序员宅基地

文章浏览阅读190次。据悉,『细分·增长2022新兴市场品牌出海线上峰会』是一次专为企业出海新兴市场打造的行业级跨境盛会,峰会集结了包括猫王音响、森马、Y.O.U、重力星球、挪客、Yeelight等在内的多家各领域全球化品牌,旨在为跨境行业揭示不确定性下的新兴市场机遇,探寻基于海外用户需求洞察形成的细分品类增长策略。..._advance.ai出海遇到的问题

随便推点

java计算机毕业设计springboot+vue超时代停车场管理平台系统_githubspringboot vue停车管理系统-程序员宅基地

文章浏览阅读126次。随着计算机信息技术的发展,越来越多的用户使用管理系统,各种信息化应用出现在停车管理中,特别是超时代停车场拥有大量的用户群,使用管理平台可以为人们的生活提供便利。本文先提出了开发基于Spring Boot的超时代停车场管理平台的背景意义,然后通过功能性和非功能性分析阐述本系统的需求,然后从功能设计和数据库设计两方面进行系统的设计建模。服务器管理端需要通过权限认证后进行登录,功能包括停车场管理、车辆信息的管理、公告信息的管理、停车记录、用户管理、停车位查看、财务收入统计。后端框架:springboot。_githubspringboot vue停车管理系统

人工智能导论实验——KNN_knn算法实验-程序员宅基地

文章浏览阅读648次。k近邻法(k-nearest neighbor,k-NN)是一种基本的分类和回归方法,是监督学习方法里的一种常用方法。分类时,对新的实例,根据其k个最近邻的训练实例类别,通过多数表决等方式进行预测。k近邻法三要素:距离度量、k值的选择和分类决策规则。k值的选择反映了对近似误差与估计误差之间的权衡,通常由交叉验证选择最优的k。分类决策规则往往是多数表决,即由输入实例的k个邻近输入实例中的多数类决定输入实例的类。模型训练时间快,上面说到KNN算法是惰性的,这里也就不再过多讲述。1) 了解KNN的基本概念;_knn算法实验

python常用转义字符串总结:各种字符转义的不同、如何取消转义字符效果?-程序员宅基地

文章浏览阅读573次,点赞13次,收藏20次。我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。print(‘v 的转义效果是:\v Python 集中营’)

Linux下手动安装screen_screen预编译二进制文件下载-程序员宅基地

文章浏览阅读1w次,点赞2次,收藏9次。简单说来就是自己用screen源码编译安装第一步:下载screen源码并解压下载地址:http://ftp.gnu.org/gnu/screen/第二步:运行配置程序,生成Makefile文件运行源码目录下的./configure,运行成功会得到如下提示:Now please check the pathnames in the Makefile and in the ..._screen预编译二进制文件下载

OpenCV图像处理知识_opencv中为了更好的对图像进行区分、识别,通常使用()来衡量图像之间的差异。-程序员宅基地

文章浏览阅读863次。OpenCV图像处理知识OpenCV图像处理参考博客_opencv中为了更好的对图像进行区分、识别,通常使用()来衡量图像之间的差异。

微信公众平台测试账号:redirect_uri参数错误_redirect_uri 参数错误-程序员宅基地

文章浏览阅读2.6k次,点赞21次,收藏10次。本文记录了微信公众平台测试账号:redirect_uri参数错误的解决办法。_redirect_uri 参数错误